From a796dda4d4b7676ef758245f712ed4891902043c Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:03:47 -0700
Subject: kernel32: Advertise junction point support.

TODO: this patch requires an update that is dependent upon obtaining
volume information through mountmgr.

Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
---
 dlls/kernelbase/volume.c | 72 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/dlls/kernelbase/volume.c b/dlls/kernelbase/volume.c
index 53cc0d49b65..f58909d321d 100644
--- a/dlls/kernelbase/volume.c
+++ b/dlls/kernelbase/volume.c
@@ -646,6 +646,75 @@ static DWORD get_audiocd_serial( const CDROM_TOC *toc )
 }
 
 
+static DWORD WINAPI get_fs_flags( UNICODE_STRING *nt_name )
+{
+#if defined(__NR_renameat2) || defined(RENAME_SWAP)
+    ANSI_STRING unix_name;
+#if defined(HAVE_FSTATFS)
+    struct statfs stfs;
+#elif defined(HAVE_FSTATVFS)
+    struct statvfs stfs;
+#endif
+    NTSTATUS status;
+    DWORD flags = 0;
+
+    status = wine_nt_to_unix_file_name( nt_name, &unix_name, FILE_OPEN, FALSE );
+    if (status != STATUS_SUCCESS)
+        return flags;
+#if defined(HAVE_FSTATFS)
+    if (statfs(unix_name.Buffer, &stfs))
+        return flags;
+#elif defined(HAVE_FSTATVFS)
+    if (statvfs(unix_name.Buffer, &stfs))
+        return flags;
+#endif
+#if defined(HAVE_FSTATFS) && defined(linux)
+    switch (stfs.f_type)
+    {
+    case 0x6969:      /* nfs */
+    case 0xff534d42:  /* cifs */
+    case 0x564c:      /* ncpfs */
+    case 0x01021994:  /* tmpfs */
+    case 0x28cd3d45:  /* cramfs */
+    case 0x1373:      /* devfs */
+    case 0x9fa0:      /* procfs */
+    case 0xef51:      /* old ext2 */
+    case 0xef53:      /* ext2/3/4 */
+    case 0x4244:      /* hfs */
+    case 0xf995e849:  /* hpfs */
+    case 0x5346544e:  /* ntfs */
+        flags |= FILE_SUPPORTS_REPARSE_POINTS;
+        break;
+    default:
+        break;
+    }
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__) || defined(__NetBSD__)
+    if (!strcmp("apfs", stfs.f_fstypename) ||
+        !strcmp("nfs", stfs.f_fstypename) ||
+        !strcmp("cifs", stfs.f_fstypename) ||
+        !strcmp("ncpfs", stfs.f_fstypename) ||
+        !strcmp("tmpfs", stfs.f_fstypename) ||
+        !strcmp("cramfs", stfs.f_fstypename) ||
+        !strcmp("devfs", stfs.f_fstypename) ||
+        !strcmp("procfs", stfs.f_fstypename) ||
+        !strcmp("ext2", stfs.f_fstypename) ||
+        !strcmp("ext3", stfs.f_fstypename) ||
+        !strcmp("ext4", stfs.f_fstypename) ||
+        !strcmp("hfs", stfs.f_fstypename) ||
+        !strcmp("hpfs", stfs.f_fstypename) ||
+        !strcmp("ntfs", stfs.f_fstypename))
+    {
+        flags |= FILE_SUPPORTS_REPARSE_POINTS;
+    }
+#endif
+    RtlFreeAnsiString( &unix_name );
+    return flags;
+#else
+    return 0;
+#endif
+}
+
+
 /***********************************************************************
  *           GetVolumeInformationW   (kernelbase.@)
  */
@@ -781,7 +850,8 @@ fill_fs_info:  /* now fill in the information that depends on the file system ty
     default:
         if (fsname) lstrcpynW( fsname, L"NTFS", fsname_len );
         if (filename_len) *filename_len = 255;
-        if (flags) *flags = FILE_CASE_PRESERVED_NAMES | FILE_PERSISTENT_ACLS;
+        if (flags) *flags = FILE_CASE_PRESERVED_NAMES | FILE_PERSISTENT_ACLS
+                            | get_fs_flags( &nt_name );
         break;
     }
     ret = TRUE;
-- 
2.17.1

