Module: wine Branch: master Commit: 368e3a93b8da3641c53f260bb4c96d03d00d1080 URL: https://source.winehq.org/git/wine.git/?a=commit;h=368e3a93b8da3641c53f260bb...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jul 9 09:59:08 2020 +0200
ntdll: Allocate the return buffer in the caller for wine_nt_to_unix_file_name().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/path.c | 18 +++++++++++++++--- dlls/ntdll/directory.c | 4 ++-- dlls/ntdll/ntdll.spec | 2 +- dlls/ntdll/unix/file.c | 11 +++++++++-- dlls/ntdll/unixlib.h | 2 +- include/winternl.h | 2 +- 6 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c index 33c39865b9..f958610dbd 100644 --- a/dlls/kernel32/path.c +++ b/dlls/kernel32/path.c @@ -276,18 +276,30 @@ DWORD /*BOOLEAN*/ WINAPI KERNEL32_Wow64EnableWow64FsRedirection( BOOLEAN enable char * CDECL wine_get_unix_file_name( LPCWSTR dosW ) { UNICODE_STRING nt_name; - ANSI_STRING unix_name; NTSTATUS status; + SIZE_T size = 256; + char *buffer;
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL; - status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF ); + for (;;) + { + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) + { + RtlFreeUnicodeString( &nt_name ); + return NULL; + } + status = wine_nt_to_unix_file_name( &nt_name, buffer, &size, FILE_OPEN_IF ); + if (status != STATUS_BUFFER_TOO_SMALL) break; + HeapFree( GetProcessHeap(), 0, buffer ); + } RtlFreeUnicodeString( &nt_name ); if (status && status != STATUS_NO_SUCH_FILE) { + HeapFree( GetProcessHeap(), 0, buffer ); SetLastError( RtlNtStatusToDosError( status ) ); return NULL; } - return unix_name.Buffer; + return buffer; }
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 6c78203981..ad129acfb5 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -110,10 +110,10 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH NtQueryDirectoryFile( HANDLE handle, HANDLE ev * element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is * returned, but the unix name is still filled in properly. */ -NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, +NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nameA, SIZE_T *size, UINT disposition ) { - return unix_funcs->nt_to_unix_file_name( nameW, unix_name_ret, disposition ); + return unix_funcs->nt_to_unix_file_name( nameW, nameA, size, disposition ); }
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 3f28e3d5ea..d80a80cf39 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1604,5 +1604,5 @@ @ cdecl __wine_get_unix_codepage()
# Filesystem -@ cdecl wine_nt_to_unix_file_name(ptr ptr long) +@ cdecl wine_nt_to_unix_file_name(ptr ptr ptr long) @ cdecl wine_unix_to_nt_file_name(ptr ptr) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 0862b94921..9b6158f2cc 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -3427,12 +3427,19 @@ NTSTATUS nt_to_unix_file_name( const UNICODE_STRING *nameW, char **unix_name_ret * element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is * returned, but the unix name is still filled in properly. */ -NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, +NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nameA, SIZE_T *size, UINT disposition ) { char *buffer = NULL; NTSTATUS status = nt_to_unix_file_name( nameW, &buffer, disposition ); - if (buffer) RtlInitAnsiString( unix_name_ret, buffer ); + + if (buffer) + { + if (*size > strlen(buffer)) strcpy( nameA, buffer ); + else status = STATUS_BUFFER_TOO_SMALL; + *size = strlen(buffer) + 1; + RtlFreeHeap( GetProcessHeap(), 0, buffer ); + } return status; }
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index 0c0d2e3250..ca708e45c2 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -332,7 +332,7 @@ struct unix_funcs void (CDECL *server_init_process_done)( void *relay );
/* file functions */ - NTSTATUS (CDECL *nt_to_unix_file_name)( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, + NTSTATUS (CDECL *nt_to_unix_file_name)( const UNICODE_STRING *nameW, char *nameA, SIZE_T *size, UINT disposition ); NTSTATUS (CDECL *unix_to_nt_file_name)( const ANSI_STRING *name, UNICODE_STRING *nt ); void (CDECL *set_show_dot_files)( BOOL enable ); diff --git a/include/winternl.h b/include/winternl.h index 4ee32d3c9e..ea2a23f3b6 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3371,7 +3371,7 @@ NTSYSAPI void WINAPI TpWaitForWork(TP_WORK *,BOOL);
/* Wine internal functions */
-NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, +NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nameA, SIZE_T *size, UINT disposition ); NTSYSAPI NTSTATUS CDECL wine_unix_to_nt_file_name( const ANSI_STRING *name, UNICODE_STRING *nt );