Alexandre Julliard : ntdll: Allocate the return buffer in the caller for wine_nt_to_unix_file_name().

Alexandre Julliard julliard at winehq.org
Thu Jul 9 17:10:38 CDT 2020


Module: wine
Branch: master
Commit: 368e3a93b8da3641c53f260bb4c96d03d00d1080
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=368e3a93b8da3641c53f260bb4c96d03d00d1080

Author: Alexandre Julliard <julliard at 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 at 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 );
 




More information about the wine-cvs mailing list