Commit 6acbaee3 authored by Erich E. Hoover's avatar Erich E. Hoover Committed by Vitaly Lipatov

kernel32: Advertise junction point support.

parent 8d5a2a99
......@@ -197,6 +197,36 @@ static void get_filesystem_serial( struct volume *volume )
volume->serial = strtoul( buffer, NULL, 16 );
}
/* get the flags for the volume by looking at the type of underlying filesystem */
static DWORD get_filesystem_flags( struct volume *volume )
{
char fstypename[256];
ULONG size = sizeof(fstypename);
struct get_volume_filesystem_params params = { volume->device->unix_mount, fstypename, &size };
if (!volume->device->unix_mount) return 0;
if (MOUNTMGR_CALL( get_volume_filesystem, &params )) return 0;
if (!strcmp("apfs", fstypename) ||
!strcmp("nfs", fstypename) ||
!strcmp("cifs", fstypename) ||
!strcmp("ncpfs", fstypename) ||
!strcmp("tmpfs", fstypename) ||
!strcmp("cramfs", fstypename) ||
!strcmp("devfs", fstypename) ||
!strcmp("procfs", fstypename) ||
!strcmp("ext2", fstypename) ||
!strcmp("ext3", fstypename) ||
!strcmp("ext4", fstypename) ||
!strcmp("hfs", fstypename) ||
!strcmp("hpfs", fstypename) ||
!strcmp("ntfs", fstypename))
{
return FILE_SUPPORTS_REPARSE_POINTS;
}
return 0;
}
/******************************************************************
* VOLUME_FindCdRomDataBestVoldesc
......@@ -1692,7 +1722,8 @@ static NTSTATUS WINAPI harddisk_query_volume( DEVICE_OBJECT *device, IRP *irp )
break;
default:
fsname = L"NTFS";
info->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_PERSISTENT_ACLS;
info->FileSystemAttributes = FILE_CASE_PRESERVED_NAMES | FILE_PERSISTENT_ACLS
| get_filesystem_flags( volume );
info->MaximumComponentNameLength = 255;
break;
}
......
......@@ -31,6 +31,21 @@
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_SYS_STATFS_H
# include <sys/statfs.h>
#endif
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
#ifdef HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#include "unixlib.h"
......@@ -311,6 +326,87 @@ static NTSTATUS read_volume_file( void *args )
return STATUS_SUCCESS;
}
static NTSTATUS get_volume_filesystem( void *args )
{
#if defined(__NR_renameat2) || defined(RENAME_SWAP)
const struct get_volume_filesystem_params *params = args;
#if defined(HAVE_FSTATFS)
struct statfs stfs;
#elif defined(HAVE_FSTATVFS)
struct statvfs stfs;
#endif
const char *fstypename = "unknown";
int fd = -1;
if (params->volume[0] != '/')
{
char *path = get_dosdevices_path( params->volume );
if (path) fd = open( path, O_RDONLY );
free( path );
}
else fd = open( params->volume, O_RDONLY );
if (fd == -1) return STATUS_NO_SUCH_FILE;
#if defined(HAVE_FSTATFS)
if (fstatfs(fd, &stfs))
return STATUS_NO_SUCH_FILE;
#elif defined(HAVE_FSTATVFS)
if (fstatvfs(fd, &stfs))
return STATUS_NO_SUCH_FILE;
#endif
close( fd );
#if defined(HAVE_FSTATFS) && defined(linux)
switch (stfs.f_type)
{
case 0x6969: /* nfs */
fstypename = "nfs";
break;
case 0xff534d42: /* cifs */
fstypename = "cifs";
break;
case 0x564c: /* ncpfs */
fstypename = "ncpfs";
break;
case 0x01021994: /* tmpfs */
fstypename = "tmpfs";
break;
case 0x28cd3d45: /* cramfs */
fstypename = "cramfs";
break;
case 0x1373: /* devfs */
fstypename = "devfs";
break;
case 0x9fa0: /* procfs */
fstypename = "procfs";
break;
case 0xef51: /* old ext2 */
fstypename = "ext2";
break;
case 0xef53: /* ext2/3/4 */
fstypename = "ext2";
break;
case 0x4244: /* hfs */
fstypename = "hfs";
break;
case 0xf995e849: /* hpfs */
fstypename = "hpfs";
break;
case 0x5346544e: /* ntfs */
fstypename = "ntfs";
break;
default:
break;
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) || defined(__NetBSD__)
fstypename = stfs.f_fstypename;
#endif
lstrcpynA( params->fstypename, fstypename, *params->size );
return STATUS_SUCCESS;
#else
return STATUS_NOT_IMPLEMENTED;
#endif
}
static NTSTATUS match_unixdev( void *args )
{
const struct match_unixdev_params *params = args;
......@@ -454,4 +550,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
write_credential,
delete_credential,
enumerate_credentials,
get_volume_filesystem,
};
......@@ -91,6 +91,13 @@ struct read_volume_file_params
ULONG *size;
};
struct get_volume_filesystem_params
{
const char *volume;
void *fstypename;
ULONG *size;
};
struct match_unixdev_params
{
const char *device;
......@@ -156,6 +163,7 @@ enum mountmgr_funcs
unix_write_credential,
unix_delete_credential,
unix_enumerate_credentials,
unix_get_volume_filesystem,
};
extern unixlib_handle_t mountmgr_handle;
......
......@@ -5361,8 +5361,8 @@ static INT build_reparse_buffer(const WCHAR *filename, REPARSE_DATA_BUFFER **pbu
static void test_reparse_points(void)
{
WCHAR path[MAX_PATH], reparse_path[MAX_PATH], target_path[MAX_PATH], volnameW[MAX_PATH];
static const WCHAR reparseW[] = {'\\','r','e','p','a','r','s','e',0};
WCHAR path[MAX_PATH], reparse_path[MAX_PATH], target_path[MAX_PATH];
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
INT buffer_len, string_len, path_len, total_len;
FILE_BASIC_INFORMATION old_attrib, new_attrib;
......@@ -5391,7 +5391,12 @@ static void test_reparse_points(void)
pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL);
volW[0] = nameW.Buffer[4];
pRtlFreeUnicodeString( &nameW );
GetVolumeInformationW(volW, 0, 0, 0, &dwLen, &dwFlags, 0, 0);
if (!GetVolumeNameForVolumeMountPointW(volW, volnameW, MAX_PATH))
{
win_skip("Failed to obtain volume name for current volume.\n");
return;
}
GetVolumeInformationW(volnameW, 0, 0, 0, &dwLen, &dwFlags, 0, 0);
if (!(dwFlags & FILE_SUPPORTS_REPARSE_POINTS))
{
skip("File system does not support reparse points.\n");
......
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