Alexandre Julliard : ntdll: Add support for the different info classes in NtQueryDirectoryFile.

Alexandre Julliard julliard at winehq.org
Thu Nov 19 10:15:17 CST 2009


Module: wine
Branch: master
Commit: 74ae7d358f786740e44ff184d432a42b57291a83
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=74ae7d358f786740e44ff184d432a42b57291a83

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Nov 18 18:07:30 2009 +0100

ntdll: Add support for the different info classes in NtQueryDirectoryFile.

---

 dlls/ntdll/directory.c |   59 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 602b08c..a09aab1 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -151,7 +151,11 @@ static int ignored_files_count;
 union file_directory_info
 {
     ULONG                              next;
+    FILE_DIRECTORY_INFORMATION         dir;
     FILE_BOTH_DIRECTORY_INFORMATION    both;
+    FILE_FULL_DIRECTORY_INFORMATION    full;
+    FILE_ID_BOTH_DIRECTORY_INFORMATION id_both;
+    FILE_ID_FULL_DIRECTORY_INFORMATION id_full;
 };
 
 static int show_dot_files = -1;
@@ -223,8 +227,16 @@ static inline unsigned int dir_info_size( FILE_INFORMATION_CLASS class, unsigned
 {
     switch (class)
     {
+    case FileDirectoryInformation:
+        return (FIELD_OFFSET( FILE_DIRECTORY_INFORMATION, FileName[len] ) + 3) & ~3;
     case FileBothDirectoryInformation:
-        return (FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, FileName[len] ) + 3) & ~3;
+        return (FIELD_OFFSET( FILE_BOTH_DIRECTORY_INFORMATION, FileName[len] ) + 3) & ~3;
+    case FileFullDirectoryInformation:
+        return (FIELD_OFFSET( FILE_FULL_DIRECTORY_INFORMATION, FileName[len] ) + 3) & ~3;
+    case FileIdBothDirectoryInformation:
+        return (FIELD_OFFSET( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[len] ) + 3) & ~3;
+    case FileIdFullDirectoryInformation:
+        return (FIELD_OFFSET( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[len] ) + 3) & ~3;
     default:
         assert(0);
     }
@@ -953,6 +965,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
     struct stat st;
     WCHAR long_nameW[MAX_DIR_ENTRY_LEN];
     WCHAR short_nameW[12];
+    WCHAR *filename;
     UNICODE_STRING str;
     ULONG attributes = 0;
 
@@ -1012,25 +1025,51 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
         io->u.Status = STATUS_BUFFER_OVERFLOW;
     }
     info = (union file_directory_info *)((char *)info_ptr + io->Information);
+    /* all the structures start with a FileDirectoryInformation layout */
+    fill_stat_info( &st, info, class );
+    info->dir.NextEntryOffset = total_len;
+    info->dir.FileIndex = 0;  /* NTFS always has 0 here, so let's not bother with it */
+    info->dir.FileAttributes |= attributes;
 
     switch (class)
     {
+    case FileDirectoryInformation:
+        info->dir.FileNameLength = long_len * sizeof(WCHAR);
+        filename = info->dir.FileName;
+        break;
+
+    case FileFullDirectoryInformation:
+        info->full.EaSize = 0; /* FIXME */
+        info->full.FileNameLength = long_len * sizeof(WCHAR);
+        filename = info->full.FileName;
+        break;
+
+    case FileIdFullDirectoryInformation:
+        info->id_full.EaSize = 0; /* FIXME */
+        info->id_full.FileNameLength = long_len * sizeof(WCHAR);
+        filename = info->id_full.FileName;
+        break;
+
     case FileBothDirectoryInformation:
-        fill_stat_info( &st, &info->both, class );
-        info->both.NextEntryOffset = total_len;
-        info->both.FileIndex = 0;  /* NTFS always has 0 here, so let's not bother with it */
-        info->both.FileAttributes |= attributes;
         info->both.EaSize = 0; /* FIXME */
         info->both.ShortNameLength = short_len * sizeof(WCHAR);
         for (i = 0; i < short_len; i++) info->both.ShortName[i] = toupperW(short_nameW[i]);
         info->both.FileNameLength = long_len * sizeof(WCHAR);
-        memcpy( info->both.FileName, long_nameW,
-                min( info->both.FileNameLength,
-                     total_len - FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, FileName )));
+        filename = info->both.FileName;
+        break;
+
+    case FileIdBothDirectoryInformation:
+        info->id_both.EaSize = 0; /* FIXME */
+        info->id_both.ShortNameLength = short_len * sizeof(WCHAR);
+        for (i = 0; i < short_len; i++) info->id_both.ShortName[i] = toupperW(short_nameW[i]);
+        info->id_both.FileNameLength = long_len * sizeof(WCHAR);
+        filename = info->id_both.FileName;
         break;
+
     default:
         assert(0);
     }
+    memcpy( filename, long_nameW, total_len - ((char *)filename - (char *)info) );
     io->Information += total_len;
     return info;
 }
@@ -1650,7 +1689,11 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
     }
     switch (info_class)
     {
+    case FileDirectoryInformation:
     case FileBothDirectoryInformation:
+    case FileFullDirectoryInformation:
+    case FileIdBothDirectoryInformation:
+    case FileIdFullDirectoryInformation:
         if (length < dir_info_size( info_class, 1 )) return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
         break;
     default:




More information about the wine-cvs mailing list