Alexandre Julliard : ntdll: Make the various directory info size functions depend on the info class.
Alexandre Julliard
julliard at winehq.org
Thu Nov 19 10:15:17 CST 2009
Module: wine
Branch: master
Commit: 551ddfe4028f5b63ddda703956a1132a59def666
URL: http://source.winehq.org/git/wine.git/?a=commit;h=551ddfe4028f5b63ddda703956a1132a59def666
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Nov 18 17:54:06 2009 +0100
ntdll: Make the various directory info size functions depend on the info class.
---
dlls/ntdll/directory.c | 47 ++++++++++++++++++++++++++++++-----------------
1 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index ef5b17e..602b08c 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -154,8 +154,6 @@ union file_directory_info
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;
/* at some point we may want to allow Winelib apps to set this */
@@ -221,6 +219,23 @@ static inline BOOL is_ignored_file( const struct stat *st )
return FALSE;
}
+static inline unsigned int dir_info_size( FILE_INFORMATION_CLASS class, unsigned int len )
+{
+ switch (class)
+ {
+ case FileBothDirectoryInformation:
+ return (FIELD_OFFSET( FILE_BOTH_DIR_INFORMATION, FileName[len] ) + 3) & ~3;
+ default:
+ assert(0);
+ }
+}
+
+static inline unsigned int max_dir_info_size( FILE_INFORMATION_CLASS class )
+{
+ return dir_info_size( class, MAX_DIR_ENTRY_LEN );
+}
+
+
/***********************************************************************
* get_default_com_device
*
@@ -990,7 +1005,7 @@ static union file_directory_info *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 = (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[long_len]) + 3) & ~3;
+ total_len = dir_info_size( class, long_len );
if (io->Information + total_len > max_length)
{
total_len = max_length - io->Information;
@@ -1082,7 +1097,7 @@ static int read_directory_vfat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
if (restart_scan) lseek( fd, 0, SEEK_SET );
- if (length < max_dir_info_size) /* we may have to return a partial entry here */
+ if (length < max_dir_info_size(class)) /* we may have to return a partial entry here */
{
off_t old_pos = lseek( fd, 0, SEEK_CUR );
@@ -1132,7 +1147,7 @@ static int read_directory_vfat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
last_info = info;
if (single_entry) break;
/* check if we still have enough space for the largest possible entry */
- if (io->Information + max_dir_info_size > length) break;
+ if (io->Information + max_dir_info_size(class) > length) break;
}
if (ioctl( fd, VFAT_IOCTL_READDIR_BOTH, (long)de ) == -1) break;
}
@@ -1169,7 +1184,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
}
if (restart_scan) lseek( fd, 0, SEEK_SET );
- else if (length < max_dir_info_size) /* we may have to return a partial entry here */
+ else if (length < max_dir_info_size(class)) /* we may have to return a partial entry here */
{
old_pos = lseek( fd, 0, SEEK_CUR );
if (old_pos == -1 && errno == ENOENT)
@@ -1209,8 +1224,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
/* make sure we have enough room for both entries */
if (fake_dot_dot)
{
- static const ULONG min_info_size = (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[1]) +
- FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[2]) + 3) & ~3;
+ const ULONG min_info_size = dir_info_size( class, 1 ) + dir_info_size( class, 2 );
if (length < min_info_size || single_entry)
{
FIXME( "not enough room %u/%u for fake . and .. entries\n", length, single_entry );
@@ -1226,7 +1240,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
last_info = info;
/* check if we still have enough space for the largest possible entry */
- if (last_info && io->Information + max_dir_info_size > length)
+ if (last_info && io->Information + max_dir_info_size(class) > length)
{
lseek( fd, 0, SEEK_SET ); /* reset pos to first entry */
res = 0;
@@ -1248,7 +1262,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
break;
}
/* check if we still have enough space for the largest possible entry */
- if (single_entry || io->Information + max_dir_info_size > length)
+ if (single_entry || io->Information + max_dir_info_size(class) > length)
{
if (res > 0) lseek( fd, de->d_off, SEEK_SET ); /* set pos to next entry */
break;
@@ -1372,8 +1386,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
/* make sure we have enough room for both entries */
if (fake_dot_dot)
{
- static const ULONG min_info_size = (FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[1]) +
- FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName[2]) + 3) & ~3;
+ const ULONG min_info_size = dir_info_size( class, 1 ) + dir_info_size( class, 2 );
if (length < min_info_size || single_entry)
{
FIXME( "not enough room %u/%u for fake . and .. entries\n", length, single_entry );
@@ -1392,7 +1405,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
restart_info_pos = io->Information;
/* check if we still have enough space for the largest possible entry */
- if (last_info && io->Information + max_dir_info_size > length)
+ if (last_info && io->Information + max_dir_info_size(class) > length)
{
lseek( fd, 0, SEEK_SET ); /* reset pos to first entry */
res = 0;
@@ -1426,7 +1439,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
goto restart;
}
/* if we have to return but the buffer contains more data, restart with a smaller size */
- if (res > 0 && (single_entry || io->Information + max_dir_info_size > length))
+ if (res > 0 && (single_entry || io->Information + max_dir_info_size(class) > length))
{
lseek( fd, (unsigned long)restart_pos, SEEK_SET );
size = (char *)de - data;
@@ -1444,7 +1457,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
if (size < initial_size) break; /* already restarted once, give up now */
size = min( size, length - io->Information );
/* if size is too small don't bother to continue */
- if (size < max_dir_info_size && last_info) break;
+ if (size < max_dir_info_size(class) && last_info) break;
restart_last_info = last_info;
restart_info_pos = io->Information;
restart:
@@ -1530,7 +1543,7 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
}
if (single_entry) break;
/* check if we still have enough space for the largest possible entry */
- if (io->Information + max_dir_info_size > length) break;
+ if (io->Information + max_dir_info_size(class) > length) break;
}
}
@@ -1638,7 +1651,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
switch (info_class)
{
case FileBothDirectoryInformation:
- if (length < sizeof(FILE_BOTH_DIR_INFORMATION)) return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
+ if (length < dir_info_size( info_class, 1 )) return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
break;
default:
FIXME( "Unsupported file info class %d\n", info_class );
More information about the wine-cvs
mailing list