You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-12-15 08:03:15 -08:00
Rebase against a3d49dbc8db25fdd5907b497f7993d214bf8d0b8.
This commit is contained in:
@@ -1,214 +0,0 @@
|
||||
From 09318135fc87cd27e9df660958dcda6fe7d6f997 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
|
||||
Date: Sat, 12 Dec 2020 17:28:31 -0700
|
||||
Subject: [PATCH] kernel32: Advertise reparse point support.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
dlls/mountmgr.sys/device.c | 33 ++++++++++++-
|
||||
dlls/mountmgr.sys/unixlib.c | 97 +++++++++++++++++++++++++++++++++++++
|
||||
dlls/mountmgr.sys/unixlib.h | 8 +++
|
||||
3 files changed, 137 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
|
||||
index 6c62ac78c76..1ee82e92c97 100644
|
||||
--- a/dlls/mountmgr.sys/device.c
|
||||
+++ b/dlls/mountmgr.sys/device.c
|
||||
@@ -177,6 +177,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, ¶ms )) 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
|
||||
@@ -1704,7 +1734,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;
|
||||
}
|
||||
diff --git a/dlls/mountmgr.sys/unixlib.c b/dlls/mountmgr.sys/unixlib.c
|
||||
index 80e7c850854..55489d9965b 100644
|
||||
--- a/dlls/mountmgr.sys/unixlib.c
|
||||
+++ b/dlls/mountmgr.sys/unixlib.c
|
||||
@@ -38,6 +38,21 @@
|
||||
#endif
|
||||
#include <termios.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"
|
||||
#include "wine/debug.h"
|
||||
@@ -463,6 +478,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;
|
||||
@@ -607,6 +703,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
|
||||
write_credential,
|
||||
delete_credential,
|
||||
enumerate_credentials,
|
||||
+ get_volume_filesystem,
|
||||
};
|
||||
|
||||
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
|
||||
diff --git a/dlls/mountmgr.sys/unixlib.h b/dlls/mountmgr.sys/unixlib.h
|
||||
index 7a3d0038512..ac7e6a553c7 100644
|
||||
--- a/dlls/mountmgr.sys/unixlib.h
|
||||
+++ b/dlls/mountmgr.sys/unixlib.h
|
||||
@@ -107,6 +107,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;
|
||||
@@ -173,6 +180,7 @@ enum mountmgr_funcs
|
||||
unix_write_credential,
|
||||
unix_delete_credential,
|
||||
unix_enumerate_credentials,
|
||||
+ unix_get_volume_filesystem,
|
||||
unix_funcs_count
|
||||
};
|
||||
|
||||
--
|
||||
2.40.1
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
From 8ceb056ccdf36bdf8a8692bd5882fc686aace5f6 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 15:18:50 -0600
|
||||
Subject: wcmd: Display reparse point type in directory listings.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
programs/cmd/directory.c | 26 ++++++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
|
||||
index 8417687939a..a849807c76e 100644
|
||||
--- a/programs/cmd/directory.c
|
||||
+++ b/programs/cmd/directory.c
|
||||
@@ -395,6 +395,32 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
|
||||
WCMD_output(L"%1!*s!", cur_width - tmp_width, L"");
|
||||
}
|
||||
|
||||
+ } else if (fd[i].dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
+ if (!bare) {
|
||||
+ const WCHAR *type;
|
||||
+
|
||||
+ switch(fd[i].dwReserved0) {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ type = L"<JUNCTION>";
|
||||
+ break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ default:
|
||||
+ type = (fd[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? L"<SYMLINKD>" : L"<SYMLINK>";
|
||||
+ break;
|
||||
+ }
|
||||
+ WCMD_output (L"%1!10s! %2!8s! %3!-14s!", datestring, timestring, type);
|
||||
+ if (shortname) WCMD_output (L"%1!-13s!", fd[i].cAlternateFileName);
|
||||
+ if (usernames) WCMD_output (L"%1!-23s!", username);
|
||||
+ WCMD_output(L"%1",fd[i].cFileName);
|
||||
+ } else {
|
||||
+ if (!((lstrcmpW(fd[i].cFileName, L".") == 0) ||
|
||||
+ (lstrcmpW(fd[i].cFileName, L"..") == 0))) {
|
||||
+ WCMD_output (L"%1%2", recurse?inputparms->dirName : L"", fd[i].cFileName);
|
||||
+ } else {
|
||||
+ addNewLine = FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
} else if (fd[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
dir_count++;
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
From 563bc2fc3c48b2341a08a662e27e27a904702121 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 15:38:30 -0600
|
||||
Subject: wcmd: Show reparse point target in directory listing.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
programs/cmd/directory.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 35 insertions(+)
|
||||
|
||||
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
|
||||
index a849807c76e..5b0a19b442d 100644
|
||||
--- a/programs/cmd/directory.c
|
||||
+++ b/programs/cmd/directory.c
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include "wcmd.h"
|
||||
#include "wine/debug.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "ddk/ntifs.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cmd);
|
||||
|
||||
@@ -412,6 +414,39 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
|
||||
if (shortname) WCMD_output (L"%1!-13s!", fd[i].cAlternateFileName);
|
||||
if (usernames) WCMD_output (L"%1!-23s!", username);
|
||||
WCMD_output(L"%1",fd[i].cFileName);
|
||||
+ if (fd[i].dwReserved0) {
|
||||
+ REPARSE_DATA_BUFFER *buffer = NULL;
|
||||
+ WCHAR *target = NULL;
|
||||
+ INT buffer_len;
|
||||
+ HANDLE hlink;
|
||||
+ DWORD dwret;
|
||||
+ BOOL bret;
|
||||
+
|
||||
+ lstrcpyW(string, inputparms->dirName);
|
||||
+ lstrcatW(string, fd[i].cFileName);
|
||||
+ hlink = CreateFileW(string, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
+ buffer_len = sizeof(*buffer) + 2*MAX_PATH*sizeof(WCHAR);
|
||||
+ buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_len);
|
||||
+ bret = DeviceIoControl(hlink, FSCTL_GET_REPARSE_POINT, NULL, 0, (LPVOID)buffer,
|
||||
+ buffer_len, &dwret, 0);
|
||||
+ if (bret) {
|
||||
+ INT offset;
|
||||
+ switch(buffer->ReparseTag) {
|
||||
+ case IO_REPARSE_TAG_MOUNT_POINT:
|
||||
+ offset = buffer->MountPointReparseBuffer.PrintNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->MountPointReparseBuffer.PathBuffer[offset];
|
||||
+ break;
|
||||
+ case IO_REPARSE_TAG_SYMLINK:
|
||||
+ offset = buffer->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
|
||||
+ target = &buffer->SymbolicLinkReparseBuffer.PathBuffer[offset];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ CloseHandle(hlink);
|
||||
+ if (target) WCMD_output(L" [%1]", target);
|
||||
+ HeapFree(GetProcessHeap(), 0, buffer);
|
||||
+ }
|
||||
} else {
|
||||
if (!((lstrcmpW(fd[i].cFileName, L".") == 0) ||
|
||||
(lstrcmpW(fd[i].cFileName, L"..") == 0))) {
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
From be1665ad0d88598c409f6a1d699562c2dd0d525a Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Wed, 29 May 2019 16:01:45 -0600
|
||||
Subject: [PATCH] wcmd: Add junction point support to mklink.
|
||||
|
||||
Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com>
|
||||
---
|
||||
programs/cmd/builtins.c | 48 ++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 47 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
|
||||
index 5b15c0f397a..6d7512275ce 100644
|
||||
--- a/programs/cmd/builtins.c
|
||||
+++ b/programs/cmd/builtins.c
|
||||
@@ -31,6 +31,9 @@
|
||||
#include "wcmd.h"
|
||||
#include <shellapi.h>
|
||||
#include "wine/debug.h"
|
||||
+#include "winternl.h"
|
||||
+#include "winioctl.h"
|
||||
+#include "ddk/ntifs.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cmd);
|
||||
|
||||
@@ -4091,6 +4094,49 @@ RETURN_CODE WCMD_color(void)
|
||||
return errorlevel = return_code;
|
||||
}
|
||||
|
||||
+BOOL WCMD_create_junction(WCHAR *link, WCHAR *target) {
|
||||
+ static INT struct_size = offsetof(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer[0]);
|
||||
+ static INT header_size = offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer);
|
||||
+ INT buffer_size, data_size, string_len, prefix_len;
|
||||
+ WCHAR *subst_dest, *print_dest, *string;
|
||||
+ REPARSE_DATA_BUFFER *buffer;
|
||||
+ UNICODE_STRING nt_name;
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE hlink;
|
||||
+ DWORD dwret;
|
||||
+ BOOL ret;
|
||||
+
|
||||
+ if (!CreateDirectoryW(link, NULL ))
|
||||
+ return FALSE;
|
||||
+ hlink = CreateFileW(link, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
|
||||
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
|
||||
+ if (hlink == INVALID_HANDLE_VALUE)
|
||||
+ return FALSE;
|
||||
+ status = RtlDosPathNameToNtPathName_U_WithStatus(target, &nt_name, NULL, NULL);
|
||||
+ if (status)
|
||||
+ return FALSE;
|
||||
+ prefix_len = strlen("\\??\\");
|
||||
+ string = nt_name.Buffer;
|
||||
+ string_len = lstrlenW( &string[prefix_len] );
|
||||
+ data_size = (prefix_len + 2 * string_len + 2) * sizeof(WCHAR);
|
||||
+ buffer_size = struct_size + data_size;
|
||||
+ buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size );
|
||||
+ buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
+ buffer->ReparseDataLength = struct_size - header_size + data_size;
|
||||
+ buffer->MountPointReparseBuffer.SubstituteNameLength = (prefix_len + string_len) * sizeof(WCHAR);
|
||||
+ buffer->MountPointReparseBuffer.PrintNameOffset = (prefix_len + string_len + 1) * sizeof(WCHAR);
|
||||
+ buffer->MountPointReparseBuffer.PrintNameLength = string_len * sizeof(WCHAR);
|
||||
+ subst_dest = &buffer->MountPointReparseBuffer.PathBuffer[0];
|
||||
+ print_dest = &buffer->MountPointReparseBuffer.PathBuffer[prefix_len + string_len + 1];
|
||||
+ lstrcpyW(subst_dest, string);
|
||||
+ lstrcpyW(print_dest, &string[prefix_len]);
|
||||
+ RtlFreeUnicodeString(&nt_name );
|
||||
+ ret = DeviceIoControl(hlink, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_size, NULL, 0,
|
||||
+ &dwret, 0 );
|
||||
+ HeapFree(GetProcessHeap(), 0, buffer);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/****************************************************************************
|
||||
* WCMD_mklink
|
||||
*/
|
||||
@@ -4141,7 +4187,7 @@ RETURN_CODE WCMD_mklink(WCHAR *args)
|
||||
else if(!junction)
|
||||
ret = CreateSymbolicLinkW(file1, file2, isdir);
|
||||
else
|
||||
- TRACE("Junction links currently not supported.\n");
|
||||
+ ret = WCMD_create_junction(file1, file2);
|
||||
}
|
||||
|
||||
if (ret) return errorlevel = NO_ERROR;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Reference in New Issue
Block a user