Commit 6261e267 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Support remaining information classes in NtQueryDirectoryFile.

parent 0a8ce1d0
...@@ -159,6 +159,8 @@ union file_directory_info ...@@ -159,6 +159,8 @@ union file_directory_info
FILE_FULL_DIRECTORY_INFORMATION full; FILE_FULL_DIRECTORY_INFORMATION full;
FILE_ID_BOTH_DIRECTORY_INFORMATION id_both; FILE_ID_BOTH_DIRECTORY_INFORMATION id_both;
FILE_ID_FULL_DIRECTORY_INFORMATION id_full; FILE_ID_FULL_DIRECTORY_INFORMATION id_full;
FILE_ID_GLOBAL_TX_DIR_INFORMATION id_tx;
FILE_NAMES_INFORMATION names;
}; };
struct dir_data_buffer struct dir_data_buffer
...@@ -277,6 +279,10 @@ static inline unsigned int dir_info_size( FILE_INFORMATION_CLASS class, unsigned ...@@ -277,6 +279,10 @@ static inline unsigned int dir_info_size( FILE_INFORMATION_CLASS class, unsigned
return offsetof( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[len] ); return offsetof( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[len] );
case FileIdFullDirectoryInformation: case FileIdFullDirectoryInformation:
return offsetof( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[len] ); return offsetof( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[len] );
case FileIdGlobalTxDirectoryInformation:
return offsetof( FILE_ID_GLOBAL_TX_DIR_INFORMATION, FileName[len] );
case FileNamesInformation:
return offsetof( FILE_NAMES_INFORMATION, FileName[len] );
default: default:
assert(0); assert(0);
return 0; return 0;
...@@ -1548,12 +1554,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I ...@@ -1548,12 +1554,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I
TRACE( "ignoring file %s\n", names->unix_name ); TRACE( "ignoring file %s\n", names->unix_name );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
if (!show_dot_files && names->long_name[0] == '.' && names->long_name[1] &&
(names->long_name[1] != '.' || names->long_name[2]))
attributes |= FILE_ATTRIBUTE_HIDDEN;
if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */
start = dir_info_align( io->Information ); start = dir_info_align( io->Information );
dir_size = dir_info_size( class, 0 ); dir_size = dir_info_size( class, 0 );
if (start + dir_size > max_length) return STATUS_MORE_ENTRIES; if (start + dir_size > max_length) return STATUS_MORE_ENTRIES;
...@@ -1564,12 +1564,21 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I ...@@ -1564,12 +1564,21 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I
if (*last_info && name_len > max_length) return STATUS_MORE_ENTRIES; if (*last_info && name_len > max_length) return STATUS_MORE_ENTRIES;
info = (union file_directory_info *)((char *)info_ptr + start); info = (union file_directory_info *)((char *)info_ptr + start);
/* all the structures start with a FileDirectoryInformation layout */
fill_file_info( &st, attributes, info, class );
info->dir.NextEntryOffset = 0; info->dir.NextEntryOffset = 0;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */ info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
/* all the structures except FileNamesInformation start with a FileDirectoryInformation layout */
if (class != FileNamesInformation)
{
if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */
if (!show_dot_files && names->long_name[0] == '.' && names->long_name[1] &&
(names->long_name[1] != '.' || names->long_name[2]))
attributes |= FILE_ATTRIBUTE_HIDDEN;
fill_file_info( &st, attributes, info, class );
}
switch (class) switch (class)
{ {
case FileDirectoryInformation: case FileDirectoryInformation:
...@@ -1600,6 +1609,15 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I ...@@ -1600,6 +1609,15 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I
info->id_both.FileNameLength = name_len; info->id_both.FileNameLength = name_len;
break; break;
case FileIdGlobalTxDirectoryInformation:
info->id_tx.TxInfoFlags = 0;
info->id_tx.FileNameLength = name_len;
break;
case FileNamesInformation:
info->names.FileNameLength = name_len;
break;
default: default:
assert(0); assert(0);
return 0; return 0;
...@@ -1990,13 +2008,23 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event, ...@@ -1990,13 +2008,23 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
case FileFullDirectoryInformation: case FileFullDirectoryInformation:
case FileIdBothDirectoryInformation: case FileIdBothDirectoryInformation:
case FileIdFullDirectoryInformation: case FileIdFullDirectoryInformation:
case FileIdGlobalTxDirectoryInformation:
case FileNamesInformation:
if (length < dir_info_align( dir_info_size( info_class, 1 ))) return STATUS_INFO_LENGTH_MISMATCH; if (length < dir_info_align( dir_info_size( info_class, 1 ))) return STATUS_INFO_LENGTH_MISMATCH;
if (!buffer) return STATUS_ACCESS_VIOLATION;
break; break;
case FileObjectIdInformation:
if (length != sizeof(FILE_OBJECTID_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
return STATUS_INVALID_INFO_CLASS;
case FileQuotaInformation:
if (length != sizeof(FILE_QUOTA_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
return STATUS_INVALID_INFO_CLASS;
case FileReparsePointInformation:
if (length != sizeof(FILE_REPARSE_POINT_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
return STATUS_INVALID_INFO_CLASS;
default: default:
FIXME( "Unsupported file info class %d\n", info_class ); return STATUS_INVALID_INFO_CLASS;
return STATUS_NOT_IMPLEMENTED;
} }
if (!buffer) return STATUS_ACCESS_VIOLATION;
if ((status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS) if ((status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
return status; return status;
......
...@@ -2198,6 +2198,13 @@ NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr, ...@@ -2198,6 +2198,13 @@ NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
fill_file_info( st, attr, info, FileDirectoryInformation ); fill_file_info( st, attr, info, FileDirectoryInformation );
} }
break; break;
case FileIdGlobalTxDirectoryInformation:
{
FILE_ID_GLOBAL_TX_DIR_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
fill_file_info( st, attr, info, FileDirectoryInformation );
}
break;
default: default:
return STATUS_INVALID_INFO_CLASS; return STATUS_INVALID_INFO_CLASS;
......
...@@ -527,6 +527,23 @@ typedef struct _FILE_ID_BOTH_DIRECTORY_INFORMATION { ...@@ -527,6 +527,23 @@ typedef struct _FILE_ID_BOTH_DIRECTORY_INFORMATION {
WCHAR FileName[ANYSIZE_ARRAY]; WCHAR FileName[ANYSIZE_ARRAY];
} FILE_ID_BOTH_DIRECTORY_INFORMATION, *PFILE_ID_BOTH_DIRECTORY_INFORMATION; } FILE_ID_BOTH_DIRECTORY_INFORMATION, *PFILE_ID_BOTH_DIRECTORY_INFORMATION;
typedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
LARGE_INTEGER FileId;
GUID LockingTransactionId;
ULONG TxInfoFlags;
WCHAR FileName[ANYSIZE_ARRAY];
} FILE_ID_GLOBAL_TX_DIR_INFORMATION, *PFILE_ID_GLOBAL_TX_DIR_INFORMATION;
typedef struct _FILE_BASIC_INFORMATION { typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime; LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastAccessTime;
...@@ -668,6 +685,34 @@ typedef struct _FILE_PIPE_LOCAL_INFORMATION { ...@@ -668,6 +685,34 @@ typedef struct _FILE_PIPE_LOCAL_INFORMATION {
ULONG NamedPipeEnd; ULONG NamedPipeEnd;
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
typedef struct _FILE_OBJECTID_INFORMATION {
LONGLONG FileReference;
UCHAR ObjectId[16];
union {
struct {
UCHAR BirthVolumeId[16];
UCHAR BirthObjectId[16];
UCHAR DomainId[16];
} DUMMYSTRUCTNAME;
UCHAR ExtendedInfo[48];
} DUMMYUNIONNAME;
} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION;
typedef struct _FILE_QUOTA_INFORMATION {
ULONG NextEntryOffset;
ULONG SidLength;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER QuotaUsed;
LARGE_INTEGER QuotaThreshold;
LARGE_INTEGER QuotaLimit;
SID Sid;
} FILE_QUOTA_INFORMATION, *PFILE_QUOTA_INFORMATION;
typedef struct _FILE_REPARSE_POINT_INFORMATION {
LONGLONG FileReference;
ULONG Tag;
} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION;
typedef struct _FILE_ALL_INFORMATION { typedef struct _FILE_ALL_INFORMATION {
FILE_BASIC_INFORMATION BasicInformation; FILE_BASIC_INFORMATION BasicInformation;
FILE_STANDARD_INFORMATION StandardInformation; FILE_STANDARD_INFORMATION StandardInformation;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment