Alexandre Julliard : ntdll: Define a generic file information structure to allow supporting multiple info classes in NtQueryDirectoryFile .
Alexandre Julliard
julliard at winehq.org
Thu Nov 19 10:15:17 CST 2009
Module: wine
Branch: master
Commit: cfafcc5a6ef8ccf73e07a92ea0fe7fb041f652d3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cfafcc5a6ef8ccf73e07a92ea0fe7fb041f652d3
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Nov 18 17:42:51 2009 +0100
ntdll: Define a generic file information structure to allow supporting multiple info classes in NtQueryDirectoryFile.
---
dlls/ntdll/directory.c | 55 +++++++++++++++++++++++++++---------------------
1 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index f7736e2..85170aa 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -148,6 +148,12 @@ struct file_identity
static struct file_identity ignored_files[MAX_IGNORED_FILES];
static int ignored_files_count;
+union file_directory_info
+{
+ ULONG next;
+ FILE_BOTH_DIRECTORY_INFORMATION both;
+};
+
static const unsigned int max_dir_info_size = FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, FileName[MAX_DIR_ENTRY_LEN] );
static int show_dot_files = -1;
@@ -923,11 +929,11 @@ static BOOLEAN match_filename( const UNICODE_STRING *name_str, const UNICODE_STR
*
* helper for NtQueryDirectoryFile
*/
-static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, IO_STATUS_BLOCK *io, ULONG max_length,
+static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK *io, ULONG max_length,
const char *long_name, const char *short_name,
const UNICODE_STRING *mask )
{
- FILE_BOTH_DIR_INFORMATION *info;
+ union file_directory_info *info;
int i, long_len, short_len, total_len;
struct stat st;
WCHAR long_nameW[MAX_DIR_ENTRY_LEN];
@@ -984,24 +990,25 @@ static FILE_BOTH_DIR_INFORMATION *append_entry( void *info_ptr, IO_STATUS_BLOCK
if (!show_dot_files && long_name[0] == '.' && long_name[1] && (long_name[1] != '.' || long_name[2]))
attributes |= FILE_ATTRIBUTE_HIDDEN;
- total_len = (sizeof(*info) - sizeof(info->FileName) + long_len*sizeof(WCHAR) + 3) & ~3;
+ total_len = (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[long_len]) + 3) & ~3;
if (io->Information + total_len > max_length)
{
total_len = max_length - io->Information;
io->u.Status = STATUS_BUFFER_OVERFLOW;
}
- info = (FILE_BOTH_DIR_INFORMATION *)((char *)info_ptr + io->Information);
- fill_stat_info( &st, info, FileBothDirectoryInformation );
- info->NextEntryOffset = total_len;
- info->FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
- info->FileAttributes |= attributes;
- info->EaSize = 0; /* FIXME */
- info->ShortNameLength = short_len * sizeof(WCHAR);
- for (i = 0; i < short_len; i++) info->ShortName[i] = toupperW(short_nameW[i]);
- info->FileNameLength = long_len * sizeof(WCHAR);
- memcpy( info->FileName, long_nameW,
- min( info->FileNameLength, total_len-sizeof(*info)+sizeof(info->FileName) ));
+ info = (union file_directory_info *)((char *)info_ptr + io->Information);
+ fill_stat_info( &st, &info->both, FileBothDirectoryInformation );
+ 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 )));
io->Information += total_len;
return info;
@@ -1063,7 +1070,7 @@ static int read_directory_vfat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
{
size_t len;
KERNEL_DIRENT *de;
- FILE_BOTH_DIR_INFORMATION *info, *last_info = NULL;
+ union file_directory_info *info, *last_info = NULL;
io->u.Status = STATUS_SUCCESS;
@@ -1125,7 +1132,7 @@ static int read_directory_vfat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
}
}
- if (last_info) last_info->NextEntryOffset = 0;
+ if (last_info) last_info->next = 0;
else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
return 0;
}
@@ -1147,7 +1154,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
int res, fake_dot_dot = 1;
char *data, local_buffer[8192];
KERNEL_DIRENT64 *de;
- FILE_BOTH_DIR_INFORMATION *info, *last_info = NULL;
+ union file_directory_info *info, *last_info = NULL;
if (size <= sizeof(local_buffer) || !(data = RtlAllocateHeap( GetProcessHeap(), 0, size )))
{
@@ -1251,7 +1258,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
}
}
- if (last_info) last_info->NextEntryOffset = 0;
+ if (last_info) last_info->next = 0;
else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
res = 0;
done:
@@ -1320,7 +1327,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
int res, fake_dot_dot = 1;
char *data, local_buffer[8192];
struct dirent *de;
- FILE_BOTH_DIR_INFORMATION *info, *last_info = NULL, *restart_last_info = NULL;
+ union file_directory_info *info, *last_info = NULL, *restart_last_info = NULL;
size = initial_size;
data = local_buffer;
@@ -1439,7 +1446,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
de = (struct dirent *)data;
}
- if (last_info) last_info->NextEntryOffset = 0;
+ if (last_info) last_info->next = 0;
else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
res = 0;
done:
@@ -1467,7 +1474,7 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
DIR *dir;
off_t i, old_pos = 0;
struct dirent *de;
- FILE_BOTH_DIR_INFORMATION *info, *last_info = NULL;
+ union file_directory_info *info, *last_info = NULL;
if (!(dir = opendir( "." )))
{
@@ -1524,7 +1531,7 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
lseek( fd, old_pos, SEEK_SET ); /* store dir offset as filepos for fd */
closedir( dir );
- if (last_info) last_info->NextEntryOffset = 0;
+ if (last_info) last_info->next = 0;
else io->u.Status = restart_scan ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
}
@@ -1569,10 +1576,10 @@ static int read_directory_stat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
ret = stat( unix_name, &st );
if (!ret)
{
- FILE_BOTH_DIR_INFORMATION *info = append_entry( buffer, io, length, unix_name, NULL, NULL );
+ union file_directory_info *info = append_entry( buffer, io, length, unix_name, NULL, NULL );
if (info)
{
- info->NextEntryOffset = 0;
+ info->next = 0;
if (io->u.Status != STATUS_BUFFER_OVERFLOW) lseek( fd, 1, SEEK_CUR );
}
else io->u.Status = STATUS_NO_MORE_FILES;
More information about the wine-cvs
mailing list