[PATCH 2/4] ntdll: Implement the FileNameInformation class for NtQueryInformationFile().

Henri Verbeet hverbeet at codeweavers.com
Thu Nov 12 08:10:13 CST 2009


---
 dlls/ntdll/file.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 228646f..5587baf 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1486,6 +1486,53 @@ NTSTATUS WINAPI NtSetVolumeInformationFile(
 	return 0;
 }
 
+static NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name )
+{
+    data_size_t name_size;
+    NTSTATUS ret;
+    char *name;
+
+    name_size = MAX_PATH;
+    name = RtlAllocateHeap( GetProcessHeap(), 0, name_size );
+    if (!name)
+    {
+        ERR("Failed to allocate unix name memory.\n");
+        return STATUS_NO_MEMORY;
+    }
+
+    SERVER_START_REQ( get_handle_unix_name )
+    {
+        req->handle = wine_server_obj_handle( handle );
+        wine_server_set_reply( req, name, name_size );
+        ret = wine_server_call( req );
+        name_size = reply->name_len;
+    }
+    SERVER_END_REQ;
+
+    if (ret == STATUS_BUFFER_OVERFLOW)
+    {
+        name = RtlReAllocateHeap( GetProcessHeap(), 0, name, name_size );
+        if (!name)
+        {
+            ERR("Failed to resize unix name memory.\n");
+            return STATUS_NO_MEMORY;
+        }
+
+        SERVER_START_REQ( get_handle_unix_name )
+        {
+            req->handle = wine_server_obj_handle( handle );
+            wine_server_set_reply( req, name, name_size );
+            ret = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+
+    if (!ret) RtlInitAnsiString( unix_name, name );
+    else RtlFreeHeap( GetProcessHeap(), 0, name );
+
+    return ret;
+}
+
 /******************************************************************************
  *  NtQueryInformationFile		[NTDLL.@]
  *  ZwQueryInformationFile		[NTDLL.@]
@@ -1774,6 +1821,42 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
             SERVER_END_REQ;
         }
         break;
+    case FileNameInformation:
+        {
+            FILE_NAME_INFORMATION *info = ptr;
+            ANSI_STRING unix_name;
+
+            if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
+            {
+                LONG name_len = len - FIELD_OFFSET(FILE_NAME_INFORMATION, FileName);
+                UNICODE_STRING nt_name;
+
+                io->u.Status = wine_unix_to_nt_file_name( &unix_name, &nt_name );
+                RtlFreeAnsiString( &unix_name );
+
+                if (!io->u.Status)
+                {
+                    const WCHAR *ptr = nt_name.Buffer;
+                    const WCHAR *end = ptr + (nt_name.Length / sizeof(WCHAR));
+
+                    /* Skip the volume mount point. */
+                    while (ptr != end && *ptr == '\\') ++ptr;
+                    while (ptr != end && *ptr != '\\') ++ptr;
+                    while (ptr != end && *ptr == '\\') ++ptr;
+                    while (ptr != end && *ptr != '\\') ++ptr;
+
+                    info->FileNameLength = (end - ptr) * sizeof(WCHAR);
+                    if (name_len < info->FileNameLength) io->u.Status = STATUS_BUFFER_OVERFLOW;
+                    else name_len = info->FileNameLength;
+
+                    memcpy( info->FileName, ptr, name_len );
+                    RtlFreeUnicodeString( &nt_name );
+
+                    io->Information = FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + name_len;
+                }
+            }
+        }
+        break;
     default:
         FIXME("Unsupported class (%d)\n", class);
         io->u.Status = STATUS_NOT_IMPLEMENTED;
-- 
1.6.4.4




More information about the wine-patches mailing list