Commit 340757c6 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

ntdll: Report Unix mount points as Win32 mount points in NtQueryInformationFile().

parent 6b498d98
...@@ -136,8 +136,15 @@ static inline ULONG get_file_attributes( const struct stat *st ) ...@@ -136,8 +136,15 @@ static inline ULONG get_file_attributes( const struct stat *st )
return attr; return attr;
} }
static BOOL fd_is_mount_point( int fd, const struct stat *st )
{
struct stat parent;
return S_ISDIR( st->st_mode ) && !fstatat( fd, "..", &parent, 0 )
&& (parent.st_dev != st->st_dev || parent.st_ino == st->st_ino);
}
/* get the stat info and file attributes for a file (by file descriptor) */ /* get the stat info and file attributes for a file (by file descriptor) */
int fd_get_file_info( int fd, struct stat *st, ULONG *attr ) int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULONG *attr )
{ {
int ret; int ret;
...@@ -145,6 +152,9 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr ) ...@@ -145,6 +152,9 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
ret = fstat( fd, st ); ret = fstat( fd, st );
if (ret == -1) return ret; if (ret == -1) return ret;
*attr |= get_file_attributes( st ); *attr |= get_file_attributes( st );
/* consider mount points to be reparse points (IO_REPARSE_TAG_MOUNT_POINT) */
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st ))
*attr |= FILE_ATTRIBUTE_REPARSE_POINT;
return ret; return ret;
} }
...@@ -2319,6 +2329,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2319,6 +2329,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
struct stat st; struct stat st;
int fd, needs_close = FALSE; int fd, needs_close = FALSE;
ULONG attr; ULONG attr;
unsigned int options;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class); TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
...@@ -2331,7 +2342,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2331,7 +2342,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (len < info_sizes[class]) if (len < info_sizes[class])
return io->u.Status = STATUS_INFO_LENGTH_MISMATCH; return io->u.Status = STATUS_INFO_LENGTH_MISMATCH;
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL ))) if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, &options )))
{ {
if (io->u.Status != STATUS_BAD_DEVICE_TYPE) return io->u.Status; if (io->u.Status != STATUS_BAD_DEVICE_TYPE) return io->u.Status;
return server_get_file_info( hFile, io, ptr, len, class ); return server_get_file_info( hFile, io, ptr, len, class );
...@@ -2340,7 +2351,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2340,7 +2351,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
switch (class) switch (class)
{ {
case FileBasicInformation: case FileBasicInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) if (fd_get_file_info( fd, options, &st, &attr ) == -1)
io->u.Status = FILE_GetNtStatus(); io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS; io->u.Status = STATUS_INVALID_INFO_CLASS;
...@@ -2351,7 +2362,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2351,7 +2362,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
{ {
FILE_STANDARD_INFORMATION *info = ptr; FILE_STANDARD_INFORMATION *info = ptr;
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else else
{ {
fill_file_info( &st, attr, info, class ); fill_file_info( &st, attr, info, class );
...@@ -2368,7 +2379,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2368,7 +2379,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
} }
break; break;
case FileInternalInformation: case FileInternalInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else fill_file_info( &st, attr, ptr, class ); else fill_file_info( &st, attr, ptr, class );
break; break;
case FileEaInformation: case FileEaInformation:
...@@ -2378,7 +2389,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2378,7 +2389,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
} }
break; break;
case FileEndOfFileInformation: case FileEndOfFileInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else fill_file_info( &st, attr, ptr, class ); else fill_file_info( &st, attr, ptr, class );
break; break;
case FileAllInformation: case FileAllInformation:
...@@ -2386,7 +2397,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2386,7 +2397,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
FILE_ALL_INFORMATION *info = ptr; FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name; ANSI_STRING unix_name;
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS; io->u.Status = STATUS_INVALID_INFO_CLASS;
else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name ))) else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
...@@ -2494,7 +2505,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2494,7 +2505,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
} }
break; break;
case FileIdInformation: case FileIdInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else else
{ {
FILE_ID_INFORMATION *info = ptr; FILE_ID_INFORMATION *info = ptr;
...@@ -2504,12 +2515,14 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io, ...@@ -2504,12 +2515,14 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
} }
break; break;
case FileAttributeTagInformation: case FileAttributeTagInformation:
if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus(); if (fd_get_file_info( fd, options, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else else
{ {
FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr; FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr;
info->FileAttributes = attr; info->FileAttributes = attr;
info->ReparseTag = 0; /* FIXME */ info->ReparseTag = 0; /* FIXME */
if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st ))
info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
} }
break; break;
default: default:
......
...@@ -1795,7 +1795,7 @@ typedef struct _RTL_HANDLE_TABLE ...@@ -1795,7 +1795,7 @@ typedef struct _RTL_HANDLE_TABLE
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 #define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define FILE_NO_COMPRESSION 0x00008000 #define FILE_NO_COMPRESSION 0x00008000
#define FILE_RESERVE_OPFILTER 0x00100000 #define FILE_RESERVE_OPFILTER 0x00100000
#define FILE_TRANSACTED_MODE 0x00200000 #define FILE_OPEN_REPARSE_POINT 0x00200000
#define FILE_OPEN_OFFLINE_FILE 0x00400000 #define FILE_OPEN_OFFLINE_FILE 0x00400000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
......
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