- From b793054640a0cad5de7b652d30805a4a5fc48b6b Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 13:14:29 +0100
 - Subject: [PATCH 1/8] build.vc19,include,sys: Add infrastructure to support
 - more types of reparse points
 - Add infrastructure to support more types of reparse points than
 - just |IO_REPARSE_TAG_SYMLINK|.
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - build.vc19/nfs41_driver/nfs41_driver.vcxproj | 2 +
 - .../nfs41_driver/nfs41_driver.vcxproj.filters | 6 +
 - include/win_reparse.h | 185 ++++++++++++++++++
 - sys/nfs41sys_debug.c | 67 +++++++
 - sys/nfs41sys_debug.h | 1 +
 - sys/nfs41sys_driver.h | 6 +
 - sys/nfs41sys_reparse.c | 117 +++++++++++
 - sys/nfs41sys_symlink.c | 12 +-
 - 8 files changed, 394 insertions(+), 2 deletions(-)
 - create mode 100644 include/win_reparse.h
 - create mode 100644 sys/nfs41sys_reparse.c
 - diff --git a/build.vc19/nfs41_driver/nfs41_driver.vcxproj b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - index 0fe0199..1148548 100644
 - --- a/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - +++ b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - @@ -218,6 +218,7 @@
 - <ClCompile Include="..\..\sys\nfs41sys_mount.c" />
 - <ClCompile Include="..\..\sys\nfs41sys_openclose.c" />
 - <ClCompile Include="..\..\sys\nfs41sys_readwrite.c" />
 - + <ClCompile Include="..\..\sys\nfs41sys_reparse.c" />
 - <ClCompile Include="..\..\sys\nfs41sys_symlink.c" />
 - <ClCompile Include="..\..\sys\nfs41sys_util.c" />
 - <ClCompile Include="..\..\sys\nfs41sys_updowncall.c" />
 - @@ -229,6 +230,7 @@
 - <ClInclude Include="..\..\sys\nfs41_driver.h" />
 - <ClInclude Include="..\..\sys\wmlkm.h" />
 - <ClInclude Include="..\..\daemon\nfs_ea.h" />
 - + <ClInclude Include="..\..\include\win_reparse.h" />
 - </ItemGroup>
 - <ItemGroup>
 - <ResourceCompile Include="..\..\sys\nfs41_driver.rc" />
 - diff --git a/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters b/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - index 2ecd6f3..49049a7 100644
 - --- a/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - +++ b/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - @@ -61,6 +61,9 @@
 - <ClCompile Include="..\..\sys\nfs41sys_readwrite.c">
 - <Filter>Source Files</Filter>
 - </ClCompile>
 - + <ClCompile Include="..\..\sys\nfs41sys_reparse.c">
 - + <Filter>Source Files</Filter>
 - + </ClCompile>
 - <ClCompile Include="..\..\sys\nfs41sys_symlink.c">
 - <Filter>Source Files</Filter>
 - </ClCompile>
 - @@ -87,6 +90,9 @@
 - <ClInclude Include="..\..\daemon\nfs_ea.h">
 - <Filter>Header Files</Filter>
 - </ClInclude>
 - + <ClInclude Include="..\..\include\win_reparse.h">
 - + <Filter>Header Files</Filter>
 - + </ClInclude>
 - </ItemGroup>
 - <ItemGroup>
 - <ResourceCompile Include="..\..\sys\nfs41_driver.rc">
 - diff --git a/include/win_reparse.h b/include/win_reparse.h
 - new file mode 100644
 - index 0000000..0f4cd8d
 - --- /dev/null
 - +++ b/include/win_reparse.h
 - @@ -0,0 +1,185 @@
 - +/* NFSv4.1 client for Windows
 - + * Copyright (C) 2024-2025 Roland Mainz <roland.mainz@nrubsig.org>
 - + *
 - + * Roland Mainz <roland.mainz@nrubsig.org>
 - + *
 - + * This library is free software; you can redistribute it and/or modify it
 - + * under the terms of the GNU Lesser General Public License as published by
 - + * the Free Software Foundation; either version 2.1 of the License, or (at
 - + * your option) any later version.
 - + *
 - + * This library is distributed in the hope that it will be useful, but
 - + * without any warranty; without even the implied warranty of merchantability
 - + * or fitness for a particular purpose. See the GNU Lesser General Public
 - + * License for more details.
 - + *
 - + * You should have received a copy of the GNU Lesser General Public License
 - + * along with this library; if not, write to the Free Software Foundation,
 - + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 - + */
 - +
 - +#ifndef _NFS41_WIN_REPARSE_
 - +#define _NFS41_WIN_REPARSE_ 1
 - +
 - +/*
 - + * Header for Windows reparse point info
 - + */
 - +
 - +#ifndef IO_REPARSE_TAG_MOUNT_POINT
 - +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_HSM
 - +#define IO_REPARSE_TAG_HSM (0xC0000004)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_DRIVE_EXTENDER
 - +#define IO_REPARSE_TAG_DRIVE_EXTENDER (0x80000005)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_HSM2
 - +#define IO_REPARSE_TAG_HSM2 (0x80000006)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_SIS
 - +#define IO_REPARSE_TAG_SIS (0x80000007)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WIM
 - +#define IO_REPARSE_TAG_WIM (0x80000008)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CSV
 - +#define IO_REPARSE_TAG_CSV (0x80000009)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_DFS
 - +#define IO_REPARSE_TAG_DFS (0x8000000A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_FILTER_MANAGER
 - +#define IO_REPARSE_TAG_FILTER_MANAGER (0x8000000B)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_SYMLINK
 - +#define IO_REPARSE_TAG_SYMLINK (0xA000000C)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_IIS_CACHE
 - +#define IO_REPARSE_TAG_IIS_CACHE (0xA0000010)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_DFSR
 - +#define IO_REPARSE_TAG_DFSR (0x80000012)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_DEDUP
 - +#define IO_REPARSE_TAG_DEDUP (0x80000013)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_APPXSTRM
 - +#define IO_REPARSE_TAG_APPXSTRM (0xC0000014)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_NFS
 - +#define IO_REPARSE_TAG_NFS (0x80000014)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_FILE_PLACEHOLDER
 - +#define IO_REPARSE_TAG_FILE_PLACEHOLDER (0x80000015)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_DFM
 - +#define IO_REPARSE_TAG_DFM (0x80000016)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WOF
 - +#define IO_REPARSE_TAG_WOF (0x80000017)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WCI
 - +#define IO_REPARSE_TAG_WCI (0x80000018)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WCI_1
 - +#define IO_REPARSE_TAG_WCI_1 (0x90001018)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_GLOBAL_REPARSE
 - +#define IO_REPARSE_TAG_GLOBAL_REPARSE (0xA0000019)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD
 - +#define IO_REPARSE_TAG_CLOUD (0x9000001A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_1
 - +#define IO_REPARSE_TAG_CLOUD_1 (0x9000101A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_2
 - +#define IO_REPARSE_TAG_CLOUD_2 (0x9000201A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_3
 - +#define IO_REPARSE_TAG_CLOUD_3 (0x9000301A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_4
 - +#define IO_REPARSE_TAG_CLOUD_4 (0x9000401A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_5
 - +#define IO_REPARSE_TAG_CLOUD_5 (0x9000501A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_6
 - +#define IO_REPARSE_TAG_CLOUD_6 (0x9000601A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_7
 - +#define IO_REPARSE_TAG_CLOUD_7 (0x9000701A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_8
 - +#define IO_REPARSE_TAG_CLOUD_8 (0x9000801A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_9
 - +#define IO_REPARSE_TAG_CLOUD_9 (0x9000901A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_A
 - +#define IO_REPARSE_TAG_CLOUD_A (0x9000A01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_B
 - +#define IO_REPARSE_TAG_CLOUD_B (0x9000B01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_C
 - +#define IO_REPARSE_TAG_CLOUD_C (0x9000C01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_D
 - +#define IO_REPARSE_TAG_CLOUD_D (0x9000D01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_E
 - +#define IO_REPARSE_TAG_CLOUD_E (0x9000E01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_CLOUD_F
 - +#define IO_REPARSE_TAG_CLOUD_F (0x9000F01A)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_APPEXECLINK
 - +#define IO_REPARSE_TAG_APPEXECLINK (0x8000001B)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_PROJFS
 - +#define IO_REPARSE_TAG_PROJFS (0x9000001C)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_LX_SYMLINK
 - +#define IO_REPARSE_TAG_LX_SYMLINK (0xA000001D)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_STORAGE_SYNC
 - +#define IO_REPARSE_TAG_STORAGE_SYNC (0x8000001E)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_STORAGE_SYNC_FOLDER
 - +#define IO_REPARSE_TAG_STORAGE_SYNC_FOLDER (0x90000027)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WCI_TOMBSTONE
 - +#define IO_REPARSE_TAG_WCI_TOMBSTONE (0xA000001F)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_UNHANDLED
 - +#define IO_REPARSE_TAG_UNHANDLED (0x80000020)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_ONEDRIVE
 - +#define IO_REPARSE_TAG_ONEDRIVE (0x80000021)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_PROJFS_TOMBSTONE
 - +#define IO_REPARSE_TAG_PROJFS_TOMBSTONE (0xA0000022)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_AF_UNIX
 - +#define IO_REPARSE_TAG_AF_UNIX (0x80000023)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_LX_FIFO
 - +#define IO_REPARSE_TAG_LX_FIFO (0x80000024)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_LX_CHR
 - +#define IO_REPARSE_TAG_LX_CHR (0x80000025)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_LX_BLK
 - +#define IO_REPARSE_TAG_LX_BLK (0x80000026)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WCI_LINK
 - +#define IO_REPARSE_TAG_WCI_LINK (0xA0000027)
 - +#endif
 - +#ifndef IO_REPARSE_TAG_WCI_LINK_1
 - +#define IO_REPARSE_TAG_WCI_LINK_1 (0xA0001027)
 - +#endif
 - +
 - +#endif /* !_NFS41_WIN_REPARSE_ */
 - diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
 - index eb7ab0e..8706565 100644
 - --- a/sys/nfs41sys_debug.c
 - +++ b/sys/nfs41sys_debug.c
 - @@ -55,6 +55,8 @@
 - #include <ntstrsafe.h>
 - #include <winerror.h>
 - +#include "win_reparse.h"
 - +
 - //#define INCLUDE_TIMESTAMPS
 - ULONG __cdecl DbgP(IN PCCH fmt, ...)
 - @@ -1028,6 +1030,71 @@ const char *fsctl2string(ULONG fscontrolcode)
 - /* not reached */
 - }
 - +const char *reparsetag2string(ULONG tag)
 - +{
 - +#define REPARSETAG2STR_RET(x) case (x): return #x ; break
 - + switch(tag) {
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_MOUNT_POINT);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_HSM);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_DRIVE_EXTENDER);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_HSM2);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_SIS);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WIM);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CSV);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_DFS);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_FILTER_MANAGER);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_SYMLINK);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_IIS_CACHE);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_DFSR);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_DEDUP);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_APPXSTRM);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_NFS);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_FILE_PLACEHOLDER);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_DFM);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WOF);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WCI);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WCI_1);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_GLOBAL_REPARSE);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_1);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_2);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_3);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_4);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_5);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_6);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_7);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_8);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_9);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_A);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_B);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_C);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_D);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_E);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_CLOUD_F);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_APPEXECLINK);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_PROJFS);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_LX_SYMLINK);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_STORAGE_SYNC);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_STORAGE_SYNC_FOLDER);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WCI_TOMBSTONE);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_UNHANDLED);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_ONEDRIVE);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_PROJFS_TOMBSTONE);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_AF_UNIX);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_LX_FIFO);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_LX_CHR);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_LX_BLK);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WCI_LINK);
 - + REPARSETAG2STR_RET(IO_REPARSE_TAG_WCI_LINK_1);
 - + default:
 - + return "<unknown reparse tag>";
 - + break;
 - + }
 - +
 - + /* not reached */
 - +}
 - +
 - +
 - #ifdef USE_LOOKASIDELISTS_FOR_UPDOWNCALLENTRY_MEM
 - void print_lookasidelist_stat(const char *label, PNPAGED_LOOKASIDE_LIST ll)
 - {
 - diff --git a/sys/nfs41sys_debug.h b/sys/nfs41sys_debug.h
 - index 29bb339..4570cde 100644
 - --- a/sys/nfs41sys_debug.h
 - +++ b/sys/nfs41sys_debug.h
 - @@ -56,6 +56,7 @@ void print_wait_status(int on, const char *str, NTSTATUS status,
 - const char *opcode, PVOID entry, LONGLONG xid);
 - void print_acl_args(SECURITY_INFORMATION info);
 - const char *fsctl2string(ULONG fsctl);
 - +const char *reparsetag2string(ULONG tag);
 - #ifdef USE_LOOKASIDELISTS_FOR_UPDOWNCALLENTRY_MEM
 - void print_lookasidelist_stat(const char *label, PNPAGED_LOOKASIDE_LIST ll);
 - #endif /* USE_LOOKASIDELISTS_FOR_UPDOWNCALLENTRY_MEM */
 - diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
 - index 8bb88bc..f14beb5 100644
 - --- a/sys/nfs41sys_driver.h
 - +++ b/sys/nfs41sys_driver.h
 - @@ -774,6 +774,12 @@ NTSTATUS marshal_nfs41_symlink(
 - void unmarshal_nfs41_symlink(
 - nfs41_updowncall_entry *cur,
 - unsigned char **buf);
 - +NTSTATUS nfs41_SetSymlinkReparsePoint(
 - + IN OUT PRX_CONTEXT RxContext);
 - +NTSTATUS nfs41_GetSymlinkReparsePoint(
 - + IN OUT PRX_CONTEXT RxContext);
 - +
 - +/* nfs41sys_reparse.c */
 - NTSTATUS nfs41_SetReparsePoint(
 - IN OUT PRX_CONTEXT RxContext);
 - NTSTATUS nfs41_GetReparsePoint(
 - diff --git a/sys/nfs41sys_reparse.c b/sys/nfs41sys_reparse.c
 - new file mode 100644
 - index 0000000..0b1e726
 - --- /dev/null
 - +++ b/sys/nfs41sys_reparse.c
 - @@ -0,0 +1,117 @@
 - +/* NFSv4.1 client for Windows
 - + * Copyright (C) 2012 The Regents of the University of Michigan
 - + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
 - + *
 - + * Olga Kornievskaia <aglo@umich.edu>
 - + * Casey Bodley <cbodley@umich.edu>
 - + * Roland Mainz <roland.mainz@nrubsig.org>
 - + *
 - + * This library is free software; you can redistribute it and/or modify it
 - + * under the terms of the GNU Lesser General Public License as published by
 - + * the Free Software Foundation; either version 2.1 of the License, or (at
 - + * your option) any later version.
 - + *
 - + * This library is distributed in the hope that it will be useful, but
 - + * without any warranty; without even the implied warranty of merchantability
 - + * or fitness for a particular purpose. See the GNU Lesser General Public
 - + * License for more details.
 - + *
 - + * You should have received a copy of the GNU Lesser General Public License
 - + * along with this library; if not, write to the Free Software Foundation,
 - + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 - + */
 - +
 - +#ifndef _KERNEL_MODE
 - +#error module requires kernel mode
 - +#endif
 - +
 - +#if ((__STDC_VERSION__-0) < 201710L)
 - +#error Code requires ISO C17
 - +#endif
 - +
 - +/* FIXME: Why does VS22 need this, but not VC19 ? */
 - +#if _MSC_VER >= 1900
 - +#if defined(_WIN64) && defined(_M_X64)
 - +#ifndef _AMD64_
 - +#define _AMD64_
 - +#endif
 - +#elif defined(_WIN32) && defined(_M_IX86)
 - +#ifndef _X86_
 - +#define _X86_
 - +#endif
 - +#elif defined(_WIN64) && defined(_M_ARM64)
 - +#ifndef _ARM64_
 - +#define _ARM64_
 - +#endif
 - +#elif defined(_WIN32) && defined(_M_ARM)
 - +#ifndef _ARM_
 - +#define _ARM_
 - +#endif
 - +#else
 - +#error Unsupported arch
 - +#endif
 - +#endif /* _MSC_VER >= 1900 */
 - +
 - +#define MINIRDR__NAME "Value is ignored, only fact of definition"
 - +#include <rx.h>
 - +#include <windef.h>
 - +#include <winerror.h>
 - +
 - +#include <Ntstrsafe.h>
 - +
 - +#include "nfs41sys_buildconfig.h"
 - +
 - +#include "nfs41_driver.h"
 - +#include "nfs41sys_debug.h"
 - +#include "nfs41_build_features.h"
 - +
 - +#include "nfs41sys_driver.h"
 - +#include "nfs41sys_util.h"
 - +
 - +#include "win_reparse.h"
 - +
 - +
 - +
 - +NTSTATUS nfs41_SetReparsePoint(
 - + IN OUT PRX_CONTEXT RxContext)
 - +{
 - + NTSTATUS status;
 - + __notnull XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
 - + __notnull PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
 - +
 - + DbgEn();
 - +
 - + DbgP("nfs41_SetReparsePoint: ReparseTag: '%s'/0x%04lx\n",
 - + reparsetag2string(Reparse->ReparseTag),
 - + (long)Reparse->ReparseTag);
 - +
 - + switch(Reparse->ReparseTag) {
 - + case IO_REPARSE_TAG_SYMLINK:
 - + status = nfs41_SetSymlinkReparsePoint(RxContext);
 - + break;
 - + default:
 - + status = STATUS_NOT_IMPLEMENTED;
 - + DbgP("nfs41_SetReparsePoint: "
 - + "Unsupported ReparseTag: '%s'/0x%04lx\n",
 - + reparsetag2string(Reparse->ReparseTag),
 - + (long)Reparse->ReparseTag);
 - + break;
 - + }
 - +
 - + DbgEx();
 - + return status;
 - +}
 - +
 - +
 - +NTSTATUS nfs41_GetReparsePoint(
 - + IN OUT PRX_CONTEXT RxContext)
 - +{
 - + NTSTATUS status;
 - +
 - + DbgEn();
 - +
 - + status = nfs41_GetSymlinkReparsePoint(RxContext);
 - +
 - + DbgEx();
 - + return status;
 - +}
 - diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
 - index b6cacd5..f44f0bd 100644
 - --- a/sys/nfs41sys_symlink.c
 - +++ b/sys/nfs41sys_symlink.c
 - @@ -68,6 +68,8 @@
 - #include "nfs41sys_driver.h"
 - #include "nfs41sys_util.h"
 - +#include "win_reparse.h"
 - +
 - NTSTATUS marshal_nfs41_symlink(
 - nfs41_updowncall_entry *entry,
 - @@ -248,7 +250,7 @@ out:
 - return status;
 - }
 - -NTSTATUS nfs41_SetReparsePoint(
 - +NTSTATUS nfs41_SetSymlinkReparsePoint(
 - IN OUT PRX_CONTEXT RxContext)
 - {
 - NTSTATUS status;
 - @@ -268,9 +270,15 @@ NTSTATUS nfs41_SetReparsePoint(
 - print_debug_header(RxContext);
 - print_reparse_buffer(Reparse);
 - #endif
 - +
 - + DbgP("nfs41_SetSymlinkReparsePoint: ReparseTag: '%s'/0x%04lx\n",
 - + reparsetag2string(Reparse->ReparseTag),
 - + (long)Reparse->ReparseTag);
 - +
 - status = check_nfs41_setreparse_args(RxContext);
 - if (status) goto out;
 - +
 - TargetName.MaximumLength = TargetName.Length =
 - Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
 - TargetName.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
 - @@ -337,7 +345,7 @@ out:
 - return status;
 - }
 - -NTSTATUS nfs41_GetReparsePoint(
 - +NTSTATUS nfs41_GetSymlinkReparsePoint(
 - IN OUT PRX_CONTEXT RxContext)
 - {
 - NTSTATUS status;
 - --
 - 2.45.1
 - From af78a97ded864d4a2ba5322140e853535ae03539 Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 13:24:22 +0100
 - Subject: [PATCH 2/8] build.vc19: Fix vcxproj include references
 - Fix vcxproj include references
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - build.vc19/nfs41_driver/nfs41_driver.vcxproj | 4 ++--
 - build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters | 6 +++---
 - 2 files changed, 5 insertions(+), 5 deletions(-)
 - diff --git a/build.vc19/nfs41_driver/nfs41_driver.vcxproj b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - index 1148548..44dd01f 100644
 - --- a/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - +++ b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
 - @@ -227,9 +227,9 @@
 - </ItemGroup>
 - <ItemGroup>
 - <ClInclude Include="..\..\sys\nfs41_debug.h" />
 - - <ClInclude Include="..\..\sys\nfs41_driver.h" />
 - <ClInclude Include="..\..\sys\wmlkm.h" />
 - - <ClInclude Include="..\..\daemon\nfs_ea.h" />
 - + <ClInclude Include="..\..\include\nfs41_driver.h" />
 - + <ClInclude Include="..\..\include\nfs_ea.h" />
 - <ClInclude Include="..\..\include\win_reparse.h" />
 - </ItemGroup>
 - <ItemGroup>
 - diff --git a/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters b/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - index 49049a7..f055bf0 100644
 - --- a/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - +++ b/build.vc19/nfs41_driver/nfs41_driver.vcxproj.filters
 - @@ -81,13 +81,13 @@
 - <ClInclude Include="..\..\sys\nfs41_debug.h">
 - <Filter>Header Files</Filter>
 - </ClInclude>
 - - <ClInclude Include="..\..\sys\nfs41_driver.h">
 - + <ClInclude Include="..\..\sys\wmlkm.h">
 - <Filter>Header Files</Filter>
 - </ClInclude>
 - - <ClInclude Include="..\..\sys\wmlkm.h">
 - + <ClInclude Include="..\..\include\nfs41_driver.h">
 - <Filter>Header Files</Filter>
 - </ClInclude>
 - - <ClInclude Include="..\..\daemon\nfs_ea.h">
 - + <ClInclude Include="..\..\include\nfs_ea.h">
 - <Filter>Header Files</Filter>
 - </ClInclude>
 - <ClInclude Include="..\..\include\win_reparse.h">
 - --
 - 2.45.1
 - From b0cb9a9dde22cd1f8d4924ad8dcabd579f456cd7 Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 13:34:15 +0100
 - Subject: [PATCH 3/8] tests: Document how to install WSL for testing
 - Document how to install WSL for testing
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - tests/manual_testing.txt | 30 +++++++++++++++++++++++++++++-
 - 1 file changed, 29 insertions(+), 1 deletion(-)
 - diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
 - index 3f5b115..df99ad5 100644
 - --- a/tests/manual_testing.txt
 - +++ b/tests/manual_testing.txt
 - @@ -1,5 +1,5 @@
 - #
 - -# ms-nfs41-client manual testing sequence, 2025-01-08
 - +# ms-nfs41-client manual testing sequence, 2025-02-03
 - #
 - # Draft version, needs to be turned into automated tests
 - # if possible
 - @@ -513,5 +513,33 @@ bash /usr/share/msnfs41client/tests/misc/wintartest_comparewinvsgnu001.bash myta
 - bash -c 'set -o errexit ; rm -Rf sillytestdir ; mkdir sillytestdir ; cd sillytestdir ; touch sillytest ; ( command exec {n}<"sillytest" ; printf "fd=%d\n" $n ; sleep 10) & sleep 1 ; ls -la ; cmd /C "del sillytest" ; ls -la ; if [[ "$(ls -1 .nfs*)" != "" ]] ; then echo "# test OK" ; else echo "# test FAILED" ; fi ; wait'
 - bash -c 'set -o errexit ; rm -Rf sillytestdir ; mkdir sillytestdir ; cd sillytestdir ; touch sillytest ; ( command exec {n}<"sillytest" ; printf "fd=%d\n" $n ; sleep 10) & sleep 1 ; ls -la ; rm -f sillytest ; ls -la ; if [[ "$(ls -1 .nfs*)" != "" ]] ; then echo "# test OK" ; else echo "# test FAILED" ; fi ; wait'
 - +#
 - +# WSL install for testing
 - +#
 - +
 - +# install WSL
 - +# (from Admin powershell)
 - +wsl --install --web-download -d Debian
 - +
 - +# Update Debian Linux
 - +# wsl # (enter WSL environment)
 - +
 - +$ sudo root
 - +
 - +# update /etc/apt/sources.list to include "contrib"+"non-free"
 - +$ cat /etc/apt/sources.list
 - +deb http://ftp.gwdg.de/debian/ bullseye main contrib non-free
 - +deb-src http://ftp.gwdg.de/debian/ bullseye main contrib non-free
 - +
 - +deb http://security.debian.org/debian-security bullseye-security main contrib non-free
 - +deb-src http://security.debian.org/debian-security bullseye-security main contrib non-free
 - +
 - +# update package lists+update packages
 - +$ apt-get update
 - +$ apt-get upgrade
 - +
 - +# install packages for testing
 - +$ apt-get install clang gcc gdb nedit emacs vim x11-apps xterm ksh traceroute strace ddd mesa-utils tk xpdf xmpuzzles mwm xutils-dev valgrind crash libhugetlbfs-bin wireguard xtron x11-xserver-utils sunclock moreutils iproute2 inetutils-tools build-essential linux-source libncurses5-dev xvkbd ethtool tshark xmldiff krb5-user krb5-kdc libkrb5-dev keyutils info bc kmod cpio flex libncurses5-dev libelf-dev libssl-dev inkscape xdmx xdmx-tools twm mwm sbuild autoconf automake openbsd-inetd rwho rwhod finger fingerd cronutils at nfs-kernel-server nfs-common nfs4-acl-tools autofs openjdk-17-jdk openjdk-17-demo python talk talkd libcurl4 libc6-dbg sysvbanner powertop iftop acpidump linux-perf ltrace locales task-german task-japanese schroot groff squashfs-tools dpkg-dev devscripts kernel-wedge sbsigntool git-svn apt-file module-assistant dwarves tree net-tools bridge-utils xnest uml-utilities inxi libxaw7-dev whois extrace kexec-tools dos2unix pkg-config libglib2.0-dev libpixman-1-dev qemu qemu-utils qemu-system-\* qemu-system-gui libsixel-bin w3m-img sharutils freerdp2-x11 nscd debconf-utils iotop 'manpages-posix*' konsole lsof
 - +
 - #
 - # EOF.
 - --
 - 2.45.1
 - From f61ca8306888cbac868af61a32b45eb3ae27fb79 Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 14:44:59 +0100
 - Subject: [PATCH 4/8] sys: Improve symlink reparse point debug output
 - Improve symlink reparse point debug output
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - sys/nfs41sys_symlink.c | 45 +++++++++++++++++++++++++++++++++++-------
 - 1 file changed, 38 insertions(+), 7 deletions(-)
 - diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
 - index f44f0bd..d01e8c9 100644
 - --- a/sys/nfs41sys_symlink.c
 - +++ b/sys/nfs41sys_symlink.c
 - @@ -189,7 +189,7 @@ static void print_reparse_buffer(
 - }
 - static
 - -NTSTATUS check_nfs41_setreparse_args(
 - +NTSTATUS check_nfs41_setsymlinkreparse_args(
 - IN PRX_CONTEXT RxContext)
 - {
 - NTSTATUS status = STATUS_SUCCESS;
 - @@ -214,36 +214,50 @@ NTSTATUS check_nfs41_setreparse_args(
 - * or it's trying to operate on the volume itself */
 - if (is_root_directory(RxContext)) {
 - status = STATUS_INVALID_PARAMETER;
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "is_root_directory() == TRUE\n");
 - goto out;
 - }
 - +
 - if (FsCtl->pOutputBuffer != NULL) {
 - status = STATUS_INVALID_PARAMETER;
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "FsCtl->pOutputBuffer == NULL\n");
 - goto out;
 - }
 - /* validate input buffer and length */
 - if (!Reparse) {
 - status = STATUS_INVALID_BUFFER_SIZE;
 - + DbgP("check_nfs41_setsymlinkreparse_args: Reparse == NULL\n");
 - goto out;
 - }
 - if (FsCtl->InputBufferLength < HeaderLen ||
 - FsCtl->InputBufferLength > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) {
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "InputBufferLength too small/large\n");
 - status = STATUS_IO_REPARSE_DATA_INVALID;
 - goto out;
 - }
 - if (FsCtl->InputBufferLength != HeaderLen + Reparse->ReparseDataLength) {
 - status = STATUS_IO_REPARSE_DATA_INVALID;
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "InputBufferLength != HeaderLen + ReparseDataLength\n");
 - goto out;
 - }
 - /* validate reparse tag */
 - if (!IsReparseTagValid(Reparse->ReparseTag)) {
 - status = STATUS_IO_REPARSE_TAG_INVALID;
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "IsReparseTagValid() failed\n");
 - goto out;
 - }
 - if (Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
 - status = STATUS_IO_REPARSE_TAG_MISMATCH;
 - + DbgP("check_nfs41_setsymlinkreparse_args: "
 - + "Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK\n");
 - goto out;
 - }
 - out:
 - @@ -275,9 +289,14 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
 - reparsetag2string(Reparse->ReparseTag),
 - (long)Reparse->ReparseTag);
 - - status = check_nfs41_setreparse_args(RxContext);
 - - if (status) goto out;
 - -
 - + status = check_nfs41_setsymlinkreparse_args(RxContext);
 - + if (status) {
 - + DbgP("nfs41_SetSymlinkReparsePoint: "
 - + "check_nfs41_setsymlinkreparse_args() failed, "
 - + "status=0xlx\n",
 - + (long)status);
 - + goto out;
 - + }
 - TargetName.MaximumLength = TargetName.Length =
 - Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
 - @@ -305,7 +324,7 @@ out:
 - }
 - static
 - -NTSTATUS check_nfs41_getreparse_args(
 - +NTSTATUS check_nfs41_getsymlinkreparse_args(
 - PRX_CONTEXT RxContext)
 - {
 - NTSTATUS status = STATUS_SUCCESS;
 - @@ -317,6 +336,8 @@ NTSTATUS check_nfs41_getreparse_args(
 - * or it's trying to operate on the volume itself */
 - if (is_root_directory(RxContext)) {
 - status = STATUS_INVALID_PARAMETER;
 - + DbgP("check_nfs41_getsymlinkreparse_args: "
 - + "is_root_directory() == TRUE\n");
 - goto out;
 - }
 - /* ifs reparse tests expect STATUS_INVALID_PARAMETER,
 - @@ -327,6 +348,8 @@ NTSTATUS check_nfs41_getreparse_args(
 - } */
 - if (!FsCtl->pOutputBuffer) {
 - status = STATUS_INVALID_USER_BUFFER;
 - + DbgP("check_nfs41_getsymlinkreparse_args: "
 - + "FsCtl->pOutputBuffer == NULL\n");
 - goto out;
 - }
 - if (!BooleanFlagOn(RxContext->pFcb->Attributes,
 - @@ -339,6 +362,8 @@ NTSTATUS check_nfs41_getreparse_args(
 - if (FsCtl->OutputBufferLength < HeaderLen) {
 - RxContext->InformationToReturn = HeaderLen;
 - status = STATUS_BUFFER_TOO_SMALL;
 - + DbgP("check_nfs41_getsymlinkreparse_args: "
 - + "FsCtl->OutputBufferLength < HeaderLen\n");
 - goto out;
 - }
 - out:
 - @@ -364,8 +389,14 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
 - #ifdef DEBUG_SYMLINK
 - DbgEn();
 - #endif
 - - status = check_nfs41_getreparse_args(RxContext);
 - - if (status) goto out;
 - + status = check_nfs41_getsymlinkreparse_args(RxContext);
 - + if (status) {
 - + DbgP("nfs41_GetSymlinkReparsePoint: "
 - + "check_nfs41_getsymlinkreparse_args() failed, "
 - + "status=0xlx\n",
 - + (long)status);
 - + goto out;
 - + }
 - TargetName.Buffer = (PWCH)((PBYTE)FsCtl->pOutputBuffer + HeaderLen);
 - TargetName.MaximumLength = (USHORT)min(FsCtl->OutputBufferLength -
 - --
 - 2.45.1
 - From df131fabe4d7d58879691bd029f0a98f796dd80d Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 15:02:05 +0100
 - Subject: [PATCH 5/8] sys,tests: cmd /C "mklink" builtin&co. should be able to
 - create symbolic links
 - cmd /C "mklink" builtin&co. should be able to create symbolic links.
 - This failed because we were looking for an output buffer
 - which is only required for |FSCTL_GET_REPARSE_POINT|, but not
 - for |FSCTL_SET_REPARSE_POINT|.
 - Reported-by: Takeshi Nishimura <takeshi.nishimura.linux@gmail.com>
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - sys/nfs41sys_symlink.c | 7 -------
 - tests/manual_testing.txt | 20 ++++++++++++++++++++
 - 2 files changed, 20 insertions(+), 7 deletions(-)
 - diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
 - index d01e8c9..6e04074 100644
 - --- a/sys/nfs41sys_symlink.c
 - +++ b/sys/nfs41sys_symlink.c
 - @@ -219,13 +219,6 @@ NTSTATUS check_nfs41_setsymlinkreparse_args(
 - goto out;
 - }
 - - if (FsCtl->pOutputBuffer != NULL) {
 - - status = STATUS_INVALID_PARAMETER;
 - - DbgP("check_nfs41_setsymlinkreparse_args: "
 - - "FsCtl->pOutputBuffer == NULL\n");
 - - goto out;
 - - }
 - -
 - /* validate input buffer and length */
 - if (!Reparse) {
 - status = STATUS_INVALID_BUFFER_SIZE;
 - diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
 - index df99ad5..f8a006c 100644
 - --- a/tests/manual_testing.txt
 - +++ b/tests/manual_testing.txt
 - @@ -159,6 +159,26 @@ ksh93 -c 'builtin id ; rm -f x ; touch x ; chown "$(id -u -n):$(id -g -n)" x &&
 - ksh93 -c 'builtin id ; rm -f x ; touch x ; chgrp "$(id -g -n)" x && print OK'
 - ---- snip ----
 - +#
 - +# Test for native mklink && powershell New-Item -ItemType SymbolicLink
 - +#
 - +# Notes:
 - +# - powershell might require admin rights depending on Windows
 - +# registry settings)
 - +#
 - +
 - +# 1. cmd.exe mklink dir
 - +mkdir mydir1
 - +cmd /C 'mklink /D symLinkmydir1 mydir1'
 - +# 2. cmd.exe mklink file
 - +touch myfile1
 - +cmd /C 'mklink symLinkmyfile myfile1'
 - +# 3. powershell mklink dir
 - +mkdir mypsdir1
 - +powershell -Command 'New-Item -Path sym_mypsdir1 -ItemType SymbolicLink -Value mypsdir1'
 - +# 4. powershell mklink file
 - +mkdir mypsfile1
 - +powershell -Command 'New-Item -Path sym_mypsfile1 -ItemType SymbolicLink -Value mypsfile1'
 - #
 - # Tests for groups
 - --
 - 2.45.1
 - From fef28d909cc0a29c1c1cc8b333aea2d644797900 Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 18:43:13 +0100
 - Subject: [PATCH 6/8] daemon: Improve EA error reporting
 - Improve EA error reporting, e.g for Solaris and WSL support.
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - daemon/ea.c | 33 +++++++++++++++++++++++++--------
 - 1 file changed, 25 insertions(+), 8 deletions(-)
 - diff --git a/daemon/ea.c b/daemon/ea.c
 - index bedd860..3151b25 100644
 - --- a/daemon/ea.c
 - +++ b/daemon/ea.c
 - @@ -52,7 +52,8 @@ static int set_ea_value(
 - /* don't allow values larger than NFS4_EASIZE */
 - if (ea->EaValueLength > NFS4_EASIZE) {
 - - eprintf("trying to write extended attribute value of size %d, "
 - + eprintf("set_ea_value: "
 - + "trying to write extended attribute value of size %d, "
 - "max allowed %d\n", ea->EaValueLength, NFS4_EASIZE);
 - status = NFS4ERR_FBIG;
 - goto out;
 - @@ -83,7 +84,11 @@ static int set_ea_value(
 - OPEN4_SHARE_DENY_BOTH, OPEN4_CREATE, UNCHECKED4,
 - &createattrs, TRUE, &stateid.stateid, &delegation, NULL);
 - if (status) {
 - - eprintf("nfs41_open() failed with '%s'\n", nfs_error_string(status));
 - + eprintf("set_ea_value: "
 - + "nfs41_open(ea_name='%.*s') failed with '%s'\n",
 - + (int)ea->EaNameLength,
 - + ea->EaName,
 - + nfs_error_string(status));
 - goto out;
 - }
 - @@ -92,7 +97,11 @@ static int set_ea_value(
 - ea->EaValueLength, 0, FILE_SYNC4, &bytes_written,
 - &verf, NULL);
 - if (status) {
 - - eprintf("nfs41_write() failed with '%s'\n", nfs_error_string(status));
 - + eprintf("set_ea_value: "
 - + "nfs41_write(ea_name='%.*s') failed with '%s'\n",
 - + (int)ea->EaNameLength,
 - + ea->EaName,
 - + nfs_error_string(status));
 - goto out_close;
 - }
 - @@ -125,7 +134,8 @@ int nfs41_ea_set(
 - status = nfs41_rpc_openattr(state->session, &state->file, TRUE, &attrdir.fh);
 - if (status) {
 - - eprintf("nfs41_rpc_openattr() failed with error '%s'\n",
 - + eprintf("nfs41_ea_set: "
 - + "nfs41_rpc_openattr() failed with error '%s'\n",
 - nfs_error_string(status));
 - goto out;
 - }
 - @@ -447,7 +457,11 @@ static int get_ea_value(
 - OPEN4_SHARE_DENY_WRITE, OPEN4_NOCREATE, UNCHECKED4, NULL, TRUE,
 - &stateid.stateid, &delegation, &info);
 - if (status) {
 - - eprintf("nfs41_open() failed with '%s'\n", nfs_error_string(status));
 - + eprintf("get_ea_value: "
 - + "nfs41_open(ea_name='%.*s') failed with '%s'\n",
 - + (int)ea->EaNameLength,
 - + ea->EaName,
 - + nfs_error_string(status));
 - if (status == NFS4ERR_NOENT)
 - goto out_empty;
 - goto out;
 - @@ -455,7 +469,8 @@ static int get_ea_value(
 - if (info.size > NFS4_EASIZE) {
 - status = NFS4ERR_FBIG;
 - - eprintf("EA value for '%s' longer than maximum %u "
 - + eprintf("get_ea_value: "
 - + "EA value for '%s' longer than maximum %u "
 - "(%llu bytes), returning %s\n", ea->EaName, NFS4_EASIZE,
 - info.size, nfs_error_string(status));
 - goto out_close;
 - @@ -476,7 +491,8 @@ static int get_ea_value(
 - status = nfs41_read(session, &file, &stateid,
 - 0, length - diff, buffer, &bytes_read, &eof);
 - if (status) {
 - - eprintf("nfs41_read() failed with '%s'\n", nfs_error_string(status));
 - + eprintf("get_ea_value: nfs41_read() failed with '%s'\n",
 - + nfs_error_string(status));
 - goto out_close;
 - }
 - if (!eof) {
 - @@ -551,7 +567,8 @@ static int handle_getexattr(void *daemon_context, nfs41_upcall *upcall)
 - goto out;
 - }
 - } else if (status) {
 - - eprintf("nfs41_rpc_openattr() failed with '%s'\n",
 - + eprintf("handle_getexattr: "
 - + "nfs41_rpc_openattr() failed with '%s'\n",
 - nfs_error_string(status));
 - status = nfs_to_windows_error(status, ERROR_EAS_NOT_SUPPORTED);
 - goto out;
 - --
 - 2.45.1
 - From 11bcd4201d597feb01a0364fd6d3145246ccea8e Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 18:45:04 +0100
 - Subject: [PATCH 7/8] daemon: Add |debug_print_ea()| for |handle_open()&co. to
 - print EA info
 - Add |debug_print_ea()| for |handle_open()&co. to print EA info
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - daemon/daemon_debug.c | 31 +++++++++++++++++++++++++++++++
 - daemon/daemon_debug.h | 3 +++
 - daemon/open.c | 7 +++++++
 - 3 files changed, 41 insertions(+)
 - diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
 - index 03eeda7..5c48f78 100644
 - --- a/daemon/daemon_debug.c
 - +++ b/daemon/daemon_debug.c
 - @@ -1360,3 +1360,34 @@ void debug_delayed_free(void *in_ptr)
 - debug_delay_free_data.free_ptrs[i] = in_ptr;
 - ReleaseSRWLockExclusive(&debug_delay_free_data.lock);
 - }
 - +
 - +void debug_print_ea(PFILE_FULL_EA_INFORMATION ea)
 - +{
 - + PFILE_FULL_EA_INFORMATION print_ea = ea;
 - +
 - + dprintf_out("--> debug_print_ea(ea=0x%p)\n", ea);
 - + if (ea == NULL)
 - + goto out;
 - +
 - +#define EA_NEXT_ENTRY(ea) ((PBYTE)(ea) + (ea)->NextEntryOffset)
 - +#define EA_VALUE(ea) \
 - + ((void *)((unsigned char*)(ea)->EaName + (ea)->EaNameLength + 1))
 - +
 - + while (1) {
 - + const char *ea_name = print_ea->EaName;
 - + size_t ea_name_len = print_ea->EaNameLength;
 - +
 - + dprintf_out("EA name='%.*s', value_len=%d\n",
 - + (int)print_ea->EaNameLength,
 - + print_ea->EaName,
 - + (int)print_ea->EaValueLength);
 - +
 - + if (print_ea->NextEntryOffset == 0)
 - + break;
 - + print_ea = (PFILE_FULL_EA_INFORMATION)EA_NEXT_ENTRY(print_ea);
 - + }
 - +
 - +out:
 - + dprintf_out("<-- debug_print_ea()\n");
 - +
 - +}
 - \ No newline at end of file
 - diff --git a/daemon/daemon_debug.h b/daemon/daemon_debug.h
 - index 2d4cc93..b39a312 100644
 - --- a/daemon/daemon_debug.h
 - +++ b/daemon/daemon_debug.h
 - @@ -175,4 +175,7 @@ void debug_ptr_add_recently_deleted(void *in_ptr);
 - void debug_delayed_free(void *in_ptr);
 - +typedef struct _FILE_FULL_EA_INFORMATION FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
 - +void debug_print_ea(PFILE_FULL_EA_INFORMATION ea);
 - +
 - #endif
 - diff --git a/daemon/open.c b/daemon/open.c
 - index 9ef5335..f3bf048 100644
 - --- a/daemon/open.c
 - +++ b/daemon/open.c
 - @@ -1072,6 +1072,13 @@ create_chgrp_out:
 - }
 - /* set extended attributes on file creation */
 - + if (DPRINTF_LEVEL_ENABLED(1)) {
 - + if (args->ea)
 - + debug_print_ea(args->ea);
 - + else
 - + DPRINTF(1, ("handle_open: No EA\n"));
 - + }
 - +
 - if (args->ea && create_with_ea(args->disposition, lookup_status)) {
 - status = nfs41_ea_set(state, args->ea);
 - status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
 - --
 - 2.45.1
 - From ed6bc4b30e68531305793c7571ca736c36944bc6 Mon Sep 17 00:00:00 2001
 - From: Roland Mainz <roland.mainz@nrubsig.org>
 - Date: Mon, 3 Feb 2025 18:46:47 +0100
 - Subject: [PATCH 8/8] daemon: Add WSL support to |debug_print_ea()|
 - Add WSL support to |debug_print_ea()|.
 - Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
 - ---
 - daemon/daemon_debug.c | 39 +++++++++++++++++++++++++++++++++++----
 - 1 file changed, 35 insertions(+), 4 deletions(-)
 - diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
 - index 5c48f78..74f26bc 100644
 - --- a/daemon/daemon_debug.c
 - +++ b/daemon/daemon_debug.c
 - @@ -1377,10 +1377,41 @@ void debug_print_ea(PFILE_FULL_EA_INFORMATION ea)
 - const char *ea_name = print_ea->EaName;
 - size_t ea_name_len = print_ea->EaNameLength;
 - - dprintf_out("EA name='%.*s', value_len=%d\n",
 - - (int)print_ea->EaNameLength,
 - - print_ea->EaName,
 - - (int)print_ea->EaValueLength);
 - +#ifdef NFS41_DRIVER_WSL_SUPPORT
 - + /*
 - + * WSL EAs: See
 - + * https://learn.microsoft.com/en-us/windows/wsl/file-permissions
 - + * for a description
 - + */
 - + if (!strncmp(ea_name, "$LXUID", ea_name_len)) {
 - + dprintf_out("EA name='%.*s', value_len=%d type=WSL_UID uid=%ld\n",
 - + (int)print_ea->EaNameLength,
 - + print_ea->EaName,
 - + (int)print_ea->EaValueLength,
 - + (long)(*((DWORD *)EA_VALUE(ea))));
 - + }
 - + else if (!strncmp(ea_name, "$LXGID", ea_name_len)) {
 - + dprintf_out("EA name='%.*s', value_len=%d type=WSL_GID gid=%ld\n",
 - + (int)print_ea->EaNameLength,
 - + print_ea->EaName,
 - + (int)print_ea->EaValueLength,
 - + (long)(*((DWORD *)EA_VALUE(ea))));
 - + }
 - + else if (!strncmp(ea_name, "$LXMOD", ea_name_len)) {
 - + dprintf_out("EA name='%.*s', value_len=%d type=WSL_MODE mode=0%lo\n",
 - + (int)print_ea->EaNameLength,
 - + print_ea->EaName,
 - + (int)print_ea->EaValueLength,
 - + (long)(*((DWORD *)EA_VALUE(ea))));
 - + }
 - + else
 - +#endif /* NFS41_DRIVER_WSL_SUPPORT */
 - + {
 - + dprintf_out("EA name='%.*s', value_len=%d\n",
 - + (int)print_ea->EaNameLength,
 - + print_ea->EaName,
 - + (int)print_ea->EaValueLength);
 - + }
 - if (print_ea->NextEntryOffset == 0)
 - break;
 - --
 - 2.45.1
 
msnfs41client: Patch for better WSL support, reparse rework, fix cmd_mklink/softlinks, EA debugging+misc, 2025-02-03
Posted by Anonymous on Mon 3rd Feb 2025 18:04
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
 nrubsig.kpaste.net RSS