pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patches for Win32 symlink/reparse point to/from POSIX symlink translation, compiler opt cleanup, FCL aliasing+misc, 2025-02-05
Posted by Anonymous on Wed 5th Feb 2025 20:30
raw | new post

  1. From ce00adbaf85ebd004584ccb5ed423a102b0cad6c Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Tue, 4 Feb 2025 14:10:46 +0100
  4. Subject: [PATCH 1/6] build.vc19: Sync debug+release compiler options between
  5.  platforms
  6.  
  7. Sync debug+release compiler options between platforms, so all
  8. platforms uniformly use the same compiler flags.
  9.  
  10. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  11. ---
  12. build.vc19/libtirpc/libtirpc.vcxproj         | 26 +++++++++++++++++---
  13.  build.vc19/nfs41_driver/nfs41_driver.vcxproj | 15 +++++++++++
  14.  build.vc19/nfs41_np/nfs41_np.vcxproj         | 13 ++++++++++
  15.  build.vc19/nfsd/nfsd.vcxproj                 | 22 +++++++++++++++--
  16.  4 files changed, 71 insertions(+), 5 deletions(-)
  17.  
  18. diff --git a/build.vc19/libtirpc/libtirpc.vcxproj b/build.vc19/libtirpc/libtirpc.vcxproj
  19. index c6ba375..e9234ff 100644
  20. --- a/build.vc19/libtirpc/libtirpc.vcxproj
  21. +++ b/build.vc19/libtirpc/libtirpc.vcxproj
  22. @@ -129,6 +129,9 @@
  23.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  24.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  25.        <SupportJustMyCode>false</SupportJustMyCode>
  26. +      <OmitFramePointers>false</OmitFramePointers>
  27. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  28. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  29.      </ClCompile>
  30.      <Link>
  31.        <SubSystem>Windows</SubSystem>
  32. @@ -153,6 +156,8 @@
  33.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  34.        <SupportJustMyCode>false</SupportJustMyCode>
  35.        <OmitFramePointers>false</OmitFramePointers>
  36. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  37. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  38.      </ClCompile>
  39.      <Link>
  40.        <SubSystem>Windows</SubSystem>
  41. @@ -176,6 +181,8 @@
  42.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  43.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  44.        <SupportJustMyCode>false</SupportJustMyCode>
  45. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  46. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  47.      </ClCompile>
  48.      <Link>
  49.        <SubSystem>Windows</SubSystem>
  50. @@ -191,7 +198,6 @@
  51.        </PrecompiledHeader>
  52.        <Optimization>MaxSpeed</Optimization>
  53.        <FunctionLevelLinking>true</FunctionLevelLinking>
  54. -      <IntrinsicFunctions>true</IntrinsicFunctions>
  55.        <PreprocessorDefinitions>FD_SETSIZE=1024;INET6;NO_CB_4_KRB5P;PORTMAP;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;_CRT_STDIO_ISO_WIDE_SPECIFIERS=1;UNICODE;_UNICODE;NDEBUG;_WINDOWS;_USRDLL;LIBTIRPC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  56.        <AdditionalIncludeDirectories>..\..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  57.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  58. @@ -199,6 +205,11 @@
  59.        <BufferSecurityCheck>false</BufferSecurityCheck>
  60.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  61.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  62. +      <OmitFramePointers>false</OmitFramePointers>
  63. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  64. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  65. +      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
  66. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  67.      </ClCompile>
  68.      <Link>
  69.        <SubSystem>Windows</SubSystem>
  70. @@ -207,6 +218,7 @@
  71.        <OptimizeReferences>true</OptimizeReferences>
  72.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  73.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  74. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  75.      </Link>
  76.    </ItemDefinitionGroup>
  77.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  78. @@ -216,7 +228,6 @@
  79.        </PrecompiledHeader>
  80.        <Optimization>MaxSpeed</Optimization>
  81.        <FunctionLevelLinking>true</FunctionLevelLinking>
  82. -      <IntrinsicFunctions>true</IntrinsicFunctions>
  83.        <PreprocessorDefinitions>FD_SETSIZE=1024;INET6;NO_CB_4_KRB5P;PORTMAP;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;_CRT_STDIO_ISO_WIDE_SPECIFIERS=1;UNICODE;_UNICODE;NDEBUG;_WINDOWS;_USRDLL;LIBTIRPC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  84.        <AdditionalIncludeDirectories>..\..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  85.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  86. @@ -225,6 +236,10 @@
  87.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  88.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  89.        <OmitFramePointers>false</OmitFramePointers>
  90. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  91. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  92. +      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
  93. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  94.      </ClCompile>
  95.      <Link>
  96.        <SubSystem>Windows</SubSystem>
  97. @@ -233,6 +248,7 @@
  98.        <OptimizeReferences>true</OptimizeReferences>
  99.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  100.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  101. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  102.      </Link>
  103.    </ItemDefinitionGroup>
  104.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
  105. @@ -241,7 +257,6 @@
  106.        <PrecompiledHeader>
  107.        </PrecompiledHeader>
  108.        <Optimization>MaxSpeed</Optimization>
  109. -      <FunctionLevelLinking>true</FunctionLevelLinking>
  110.        <IntrinsicFunctions>true</IntrinsicFunctions>
  111.        <PreprocessorDefinitions>FD_SETSIZE=1024;INET6;NO_CB_4_KRB5P;PORTMAP;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;_CRT_STDIO_ISO_WIDE_SPECIFIERS=1;UNICODE;_UNICODE;NDEBUG;_WINDOWS;_USRDLL;LIBTIRPC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  112.        <AdditionalIncludeDirectories>..\..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  113. @@ -250,6 +265,10 @@
  114.        <BufferSecurityCheck>false</BufferSecurityCheck>
  115.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  116.        <AdditionalOptions>/wd4100 /wd4131 /wd4389</AdditionalOptions>
  117. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  118. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  119. +      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
  120. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  121.      </ClCompile>
  122.      <Link>
  123.        <SubSystem>Windows</SubSystem>
  124. @@ -258,6 +277,7 @@
  125.        <OptimizeReferences>true</OptimizeReferences>
  126.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  127.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  128. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  129.      </Link>
  130.    </ItemDefinitionGroup>
  131.    <ItemGroup>
  132. diff --git a/build.vc19/nfs41_driver/nfs41_driver.vcxproj b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
  133. index bd97fb1..afd079e 100644
  134. --- a/build.vc19/nfs41_driver/nfs41_driver.vcxproj
  135. +++ b/build.vc19/nfs41_driver/nfs41_driver.vcxproj
  136. @@ -114,6 +114,8 @@
  137.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  138.        <StringPooling>true</StringPooling>
  139.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  140. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  141. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  142.      </ClCompile>
  143.      <Link>
  144.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  145. @@ -128,9 +130,12 @@
  146.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  147.        <StringPooling>true</StringPooling>
  148.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  149. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  150. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  151.      </ClCompile>
  152.      <Link>
  153.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  154. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  155.      </Link>
  156.    </ItemDefinitionGroup>
  157.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  158. @@ -142,6 +147,8 @@
  159.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  160.        <StringPooling>true</StringPooling>
  161.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  162. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  163. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  164.      </ClCompile>
  165.      <Link>
  166.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  167. @@ -159,9 +166,12 @@
  168.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  169.        <StringPooling>true</StringPooling>
  170.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  171. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  172. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  173.      </ClCompile>
  174.      <Link>
  175.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  176. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  177.      </Link>
  178.      <DriverSign>
  179.        <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
  180. @@ -176,6 +186,8 @@
  181.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  182.        <StringPooling>true</StringPooling>
  183.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  184. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  185. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  186.      </ClCompile>
  187.      <Link>
  188.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  189. @@ -193,9 +205,12 @@
  190.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  191.        <StringPooling>true</StringPooling>
  192.        <AdditionalOptions>/std:c17 /Zc:preprocessor- /kernel /wd4100 /wd4201 /wd5104</AdditionalOptions>
  193. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  194. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  195.      </ClCompile>
  196.      <Link>
  197.        <AdditionalDependencies>$(DDK_LIB_PATH)\ntoskrnl.lib;$(DDK_LIB_PATH)\hal.lib;$(DDK_LIB_PATH)\BufferOverflowfastfailK.lib;$(DDK_LIB_PATH)\ksecdd.lib;$(DDK_LIB_PATH)\rxce.lib;$(DDK_LIB_PATH)\rdbsslib.lib</AdditionalDependencies>
  198. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  199.      </Link>
  200.      <DriverSign>
  201.        <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
  202. diff --git a/build.vc19/nfs41_np/nfs41_np.vcxproj b/build.vc19/nfs41_np/nfs41_np.vcxproj
  203. index c61e65a..89cb2e3 100644
  204. --- a/build.vc19/nfs41_np/nfs41_np.vcxproj
  205. +++ b/build.vc19/nfs41_np/nfs41_np.vcxproj
  206. @@ -37,6 +37,7 @@
  207.      <ConfigurationType>DynamicLibrary</ConfigurationType>
  208.      <UseDebugLibraries>true</UseDebugLibraries>
  209.      <PlatformToolset>v142</PlatformToolset>
  210. +    <WholeProgramOptimization>false</WholeProgramOptimization>
  211.      <CharacterSet>Unicode</CharacterSet>
  212.    </PropertyGroup>
  213.    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
  214. @@ -50,6 +51,7 @@
  215.      <ConfigurationType>DynamicLibrary</ConfigurationType>
  216.      <UseDebugLibraries>true</UseDebugLibraries>
  217.      <PlatformToolset>v142</PlatformToolset>
  218. +    <WholeProgramOptimization>false</WholeProgramOptimization>
  219.      <CharacterSet>Unicode</CharacterSet>
  220.    </PropertyGroup>
  221.    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
  222. @@ -63,6 +65,7 @@
  223.      <ConfigurationType>DynamicLibrary</ConfigurationType>
  224.      <UseDebugLibraries>true</UseDebugLibraries>
  225.      <PlatformToolset>v142</PlatformToolset>
  226. +    <WholeProgramOptimization>false</WholeProgramOptimization>
  227.      <CharacterSet>Unicode</CharacterSet>
  228.    </PropertyGroup>
  229.    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
  230. @@ -126,6 +129,8 @@
  231.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  232.        <AdditionalOptions>/wd4100</AdditionalOptions>
  233.        <SupportJustMyCode>false</SupportJustMyCode>
  234. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  235. +      <OmitFramePointers>false</OmitFramePointers>
  236.      </ClCompile>
  237.      <Link>
  238.        <SubSystem>Windows</SubSystem>
  239. @@ -145,6 +150,8 @@
  240.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  241.        <AdditionalOptions>/wd4100</AdditionalOptions>
  242.        <SupportJustMyCode>false</SupportJustMyCode>
  243. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  244. +      <OmitFramePointers>false</OmitFramePointers>
  245.      </ClCompile>
  246.      <Link>
  247.        <SubSystem>Windows</SubSystem>
  248. @@ -164,6 +171,7 @@
  249.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  250.        <AdditionalOptions>/wd4100</AdditionalOptions>
  251.        <SupportJustMyCode>false</SupportJustMyCode>
  252. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  253.      </ClCompile>
  254.      <Link>
  255.        <SubSystem>Windows</SubSystem>
  256. @@ -184,6 +192,7 @@
  257.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  258.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  259.        <AdditionalOptions>/wd4100</AdditionalOptions>
  260. +      <OmitFramePointers>false</OmitFramePointers>
  261.      </ClCompile>
  262.      <Link>
  263.        <SubSystem>Windows</SubSystem>
  264. @@ -191,6 +200,7 @@
  265.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  266.        <OptimizeReferences>true</OptimizeReferences>
  267.        <ModuleDefinitionFile>..\..\dll\nfs41_np.def</ModuleDefinitionFile>
  268. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  269.      </Link>
  270.    </ItemDefinitionGroup>
  271.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  272. @@ -206,6 +216,7 @@
  273.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  274.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  275.        <AdditionalOptions>/wd4100</AdditionalOptions>
  276. +      <OmitFramePointers>false</OmitFramePointers>
  277.      </ClCompile>
  278.      <Link>
  279.        <SubSystem>Windows</SubSystem>
  280. @@ -213,6 +224,7 @@
  281.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  282.        <OptimizeReferences>true</OptimizeReferences>
  283.        <ModuleDefinitionFile>..\..\dll\nfs41_np.def</ModuleDefinitionFile>
  284. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  285.      </Link>
  286.    </ItemDefinitionGroup>
  287.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
  288. @@ -235,6 +247,7 @@
  289.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  290.        <OptimizeReferences>true</OptimizeReferences>
  291.        <ModuleDefinitionFile>..\..\dll\nfs41_np.def</ModuleDefinitionFile>
  292. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  293.      </Link>
  294.    </ItemDefinitionGroup>
  295.    <ItemGroup>
  296. diff --git a/build.vc19/nfsd/nfsd.vcxproj b/build.vc19/nfsd/nfsd.vcxproj
  297. index c871777..3005f90 100644
  298. --- a/build.vc19/nfsd/nfsd.vcxproj
  299. +++ b/build.vc19/nfsd/nfsd.vcxproj
  300. @@ -135,6 +135,9 @@
  301.        <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
  302.        <AdditionalOptions>/wd4100</AdditionalOptions>
  303.        <SupportJustMyCode>false</SupportJustMyCode>
  304. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  305. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  306. +      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
  307.      </ClCompile>
  308.      <Link>
  309.        <SubSystem>Console</SubSystem>
  310. @@ -158,6 +161,9 @@
  311.        <AdditionalOptions>/wd4100</AdditionalOptions>
  312.        <SupportJustMyCode>false</SupportJustMyCode>
  313.        <OmitFramePointers>false</OmitFramePointers>
  314. +      <IntrinsicFunctions>true</IntrinsicFunctions>
  315. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  316. +      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
  317.      </ClCompile>
  318.      <Link>
  319.        <SubSystem>Console</SubSystem>
  320. @@ -170,7 +176,7 @@
  321.        <PrecompiledHeader>
  322.        </PrecompiledHeader>
  323.        <WarningLevel>Level4</WarningLevel>
  324. -      <Optimization>MaxSpeed</Optimization>
  325. +      <Optimization>Disabled</Optimization>
  326.        <PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;FD_SETSIZE=1024;INET6;NO_CB_4_KRB5P;STANDALONE_NFSD;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;_CRT_STDIO_ISO_WIDE_SPECIFIERS=1;UNICODE;_UNICODE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
  327.        <AdditionalIncludeDirectories>..\..\include;..\..\libtirpc\tirpc;..\..\dll;..\..;$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
  328.        <LanguageStandard_C>stdc17</LanguageStandard_C>
  329. @@ -181,7 +187,8 @@
  330.        <AdditionalOptions>/wd4100</AdditionalOptions>
  331.        <SupportJustMyCode>false</SupportJustMyCode>
  332.        <IntrinsicFunctions>true</IntrinsicFunctions>
  333. -      <WholeProgramOptimization>true</WholeProgramOptimization>
  334. +      <WholeProgramOptimization>false</WholeProgramOptimization>
  335. +      <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
  336.      </ClCompile>
  337.      <Link>
  338.        <SubSystem>Console</SubSystem>
  339. @@ -204,6 +211,9 @@
  340.        <StringPooling>true</StringPooling>
  341.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  342.        <AdditionalOptions>/wd4100</AdditionalOptions>
  343. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  344. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  345. +      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
  346.      </ClCompile>
  347.      <Link>
  348.        <SubSystem>Console</SubSystem>
  349. @@ -211,6 +221,7 @@
  350.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  351.        <OptimizeReferences>true</OptimizeReferences>
  352.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  353. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  354.      </Link>
  355.    </ItemDefinitionGroup>
  356.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  357. @@ -229,6 +240,9 @@
  358.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  359.        <AdditionalOptions>/wd4100</AdditionalOptions>
  360.        <OmitFramePointers>false</OmitFramePointers>
  361. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  362. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  363. +      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
  364.      </ClCompile>
  365.      <Link>
  366.        <SubSystem>Console</SubSystem>
  367. @@ -236,6 +250,7 @@
  368.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  369.        <OptimizeReferences>true</OptimizeReferences>
  370.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Platform)\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  371. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  372.      </Link>
  373.    </ItemDefinitionGroup>
  374.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
  375. @@ -253,6 +268,8 @@
  376.        <StringPooling>true</StringPooling>
  377.        <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
  378.        <AdditionalOptions>/wd4100</AdditionalOptions>
  379. +      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
  380. +      <WholeProgramOptimization>true</WholeProgramOptimization>
  381.      </ClCompile>
  382.      <Link>
  383.        <SubSystem>Console</SubSystem>
  384. @@ -260,6 +277,7 @@
  385.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  386.        <OptimizeReferences>true</OptimizeReferences>
  387.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Platform)\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  388. +      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
  389.      </Link>
  390.    </ItemDefinitionGroup>
  391.    <ItemGroup>
  392. --
  393. 2.45.1
  394.  
  395. From 74b9b0c58c75153a510577b1cc878762bf15dddc Mon Sep 17 00:00:00 2001
  396. From: Roland Mainz <roland.mainz@nrubsig.org>
  397. Date: Tue, 4 Feb 2025 14:11:51 +0100
  398. Subject: [PATCH 2/6] sys: Implement |nfs41_AreFilesAliased()|
  399.  
  400. Implement |nfs41_AreFilesAliased()|, now that we have the
  401. fileid+fsid information available in the kernel.
  402.  
  403. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  404. ---
  405. sys/nfs41sys_driver.c | 33 ++++++++++++++++++++++++++++++---
  406.  1 file changed, 30 insertions(+), 3 deletions(-)
  407.  
  408. diff --git a/sys/nfs41sys_driver.c b/sys/nfs41sys_driver.c
  409. index dd7975c..9457ddb 100644
  410. --- a/sys/nfs41sys_driver.c
  411. +++ b/sys/nfs41sys_driver.c
  412. @@ -1009,9 +1009,36 @@ NTSTATUS nfs41_AreFilesAliased(
  413.      PFCB a,
  414.      PFCB b)
  415.  {
  416. -    DbgP("nfs41_AreFilesAliased: a=0x%p b=0x%p\n",
  417. -        (void *)a, (void *)b);
  418. -    return STATUS_NOT_IMPLEMENTED;
  419. +    __notnull PNFS41_FCB nfs41_fcb_a = (PNFS41_FCB)a;
  420. +    __notnull PNFS41_FCB nfs41_fcb_b = (PNFS41_FCB)b;
  421. +
  422. +    if ((nfs41_fcb_a->fileid == nfs41_fcb_b->fileid) &&
  423. +        (nfs41_fcb_a->fsid_major == nfs41_fcb_b->fsid_major) &&
  424. +        (nfs41_fcb_a->fsid_minor == nfs41_fcb_b->fsid_minor)) {
  425. +
  426. +        DbgP("nfs41_AreFilesAliased: "
  427. +            "a=0x%p b=0x%p aliases, fileid=0x%llx "
  428. +            "fsid_major=0x%llx fsid_minor=0x%llx\n",
  429. +            (void *)a, (void *)b,
  430. +            (long long)nfs41_fcb_a->fileid,
  431. +            (long long)nfs41_fcb_a->fsid_major,
  432. +            (long long)nfs41_fcb_a->fsid_minor);
  433. +        return STATUS_MORE_PROCESSING_REQUIRED;
  434. +    }
  435. +    else {
  436. +        DbgP("nfs41_AreFilesAliased: "
  437. +            "a=0x%p b=0x%p NOT aliases, "
  438. +            "a=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx) "
  439. +            "b=(fileid=0x%llx fsid_major=0x%llx fsid_minor=0x%llx)\n",
  440. +            (void *)a, (void *)b,
  441. +            (long long)nfs41_fcb_a->fileid,
  442. +            (long long)nfs41_fcb_a->fsid_major,
  443. +            (long long)nfs41_fcb_a->fsid_minor,
  444. +            (long long)nfs41_fcb_b->fileid,
  445. +            (long long)nfs41_fcb_b->fsid_major,
  446. +            (long long)nfs41_fcb_b->fsid_minor);
  447. +        return STATUS_SUCCESS;
  448. +    }
  449.  }
  450.  
  451.  static
  452. --
  453. 2.45.1
  454.  
  455. From d30bdfc7a74b643485fdb77b2c6360fb6e540556 Mon Sep 17 00:00:00 2001
  456. From: Roland Mainz <roland.mainz@nrubsig.org>
  457. Date: Wed, 5 Feb 2025 11:22:15 +0100
  458. Subject: [PATCH 3/6] daemon,include,sys: Split |NFS41_SYSOP_SYMLINK| into
  459.  |*GET|/|*SET|
  460.  
  461. Split |NFS41_SYSOP_SYMLINK| into |NFS41_SYSOP_SYMLINK_GET| and
  462. |NFS41_SYSOP_SYMLINK_SET|
  463.  
  464. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  465. ---
  466. daemon/daemon_debug.c     |  6 ++++--
  467.  daemon/symlink.c          | 45 +++++++++++++++++++++++++++++----------
  468.  daemon/upcall.c           |  9 +++++---
  469.  daemon/upcall.h           |  1 -
  470.  include/nfs41_driver.h    |  5 +++--
  471.  sys/nfs41sys_debug.c      |  6 ++++--
  472.  sys/nfs41sys_driver.h     |  1 -
  473.  sys/nfs41sys_ea.c         |  5 ++---
  474.  sys/nfs41sys_symlink.c    | 35 +++++++++++++++++-------------
  475.  sys/nfs41sys_updowncall.c |  8 ++++---
  476.  10 files changed, 78 insertions(+), 43 deletions(-)
  477.  
  478. diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
  479. index 74f26bc..0a027ac 100644
  480. --- a/daemon/daemon_debug.c
  481. +++ b/daemon/daemon_debug.c
  482. @@ -1,5 +1,6 @@
  483.  /* NFSv4.1 client for Windows
  484. - * Copyright (C) 2012 The Regents of the University of Michigan
  485. + * Copyright (C) 2012 The Regents of the University of Michigan
  486. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  487.   *
  488.   * Olga Kornievskaia <aglo@umich.edu>
  489.   * Casey Bodley <cbodley@umich.edu>
  490. @@ -460,7 +461,8 @@ const char* opcode2string(nfs41_opcodes opcode)
  491.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_FILE_SET)
  492.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_EA_SET)
  493.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_EA_GET)
  494. -        NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_SYMLINK)
  495. +        NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_SYMLINK_GET)
  496. +        NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_SYMLINK_SET)
  497.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_VOLUME_QUERY)
  498.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_ACL_QUERY)
  499.          NFSOPCODE_TO_STRLITERAL(NFS41_SYSOP_ACL_SET)
  500. diff --git a/daemon/symlink.c b/daemon/symlink.c
  501. index 87be302..b601f01 100644
  502. --- a/daemon/symlink.c
  503. +++ b/daemon/symlink.c
  504. @@ -1,8 +1,10 @@
  505.  /* NFSv4.1 client for Windows
  506. - * Copyright (C) 2012 The Regents of the University of Michigan
  507. + * Copyright (C) 2012 The Regents of the University of Michigan
  508. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  509.   *
  510.   * Olga Kornievskaia <aglo@umich.edu>
  511.   * Casey Bodley <cbodley@umich.edu>
  512. + * Roland Mainz <roland.mainz@nrubsig.org>
  513.   *
  514.   * This library is free software; you can redistribute it and/or modify it
  515.   * under the terms of the GNU Lesser General Public License as published by
  516. @@ -22,6 +24,7 @@
  517.  #include <Windows.h>
  518.  #include <strsafe.h>
  519.  
  520. +#include "nfs41_driver.h"
  521.  #include "nfs41_ops.h"
  522.  #include "upcall.h"
  523.  #include "util.h"
  524. @@ -186,7 +189,7 @@ out:
  525.  }
  526.  
  527.  
  528. -/* NFS41_SYSOP_SYMLINK */
  529. +/* NFS41_SYSOP_SYMLINK_GET, NFS41_SYSOP_SYMLINK_SET */
  530.  static int parse_symlink(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
  531.  {
  532.      symlink_upcall_args *args = &upcall->args.symlink;
  533. @@ -194,21 +197,34 @@ static int parse_symlink(unsigned char *buffer, uint32_t length, nfs41_upcall *u
  534.  
  535.      status = get_name(&buffer, &length, &args->path);
  536.      if (status) goto out;
  537. -    status = safe_read(&buffer, &length, &args->set, sizeof(BOOLEAN));
  538. -    if (status) goto out;
  539.  
  540. -    if (args->set)
  541. +    if (upcall->opcode == NFS41_SYSOP_SYMLINK_SET) {
  542.          /*
  543.           * args->target_set is not const because handle_symlink() might
  544.           * have to replace '\\' with '/'
  545.           */
  546.          status = get_name(&buffer, &length,
  547.              (const char **)(&args->target_set));
  548. -    else
  549. +
  550. +        DPRINTF(1,
  551. +            ("parsing NFS41_SYSOP_SYMLINK_SET: "
  552. +            "path='%s' target='%s'\n",
  553. +            args->path, args->target_set));
  554. +    }
  555. +    else if (upcall->opcode == NFS41_SYSOP_SYMLINK_GET) {
  556.          args->target_set = NULL;
  557.  
  558. -    DPRINTF(1, ("parsing NFS41_SYSOP_SYMLINK: path='%s' set=%u target='%s'\n",
  559. -        args->path, args->set, args->target_set));
  560. +        DPRINTF(1,
  561. +            ("parsing NFS41_SYSOP_SYMLINK_GET: "
  562. +            "path='%s' target='%s'\n",
  563. +            args->path, args->target_set));
  564. +    }
  565. +    else {
  566. +        status = ERROR_INVALID_PARAMETER;
  567. +        eprintf("parse_symlink: Unknown upcall->opcode=%d\n",
  568. +            (int)upcall->opcode);
  569. +    }
  570. +
  571.  out:
  572.      return status;
  573.  }
  574. @@ -219,7 +235,7 @@ static int handle_symlink(void *daemon_context, nfs41_upcall *upcall)
  575.      nfs41_open_state *state = upcall->state_ref;
  576.      int status = NO_ERROR;
  577.  
  578. -    if (args->set) {
  579. +    if (upcall->opcode == NFS41_SYSOP_SYMLINK_SET) {
  580.          nfs41_file_info info, createattrs;
  581.  
  582.          /* don't send windows slashes to the server */
  583. @@ -280,7 +296,7 @@ static int marshall_symlink(unsigned char *buffer, uint32_t *length, nfs41_upcal
  584.      unsigned short len = (args->target_get.len + 1) * sizeof(WCHAR);
  585.      int status = NO_ERROR;
  586.  
  587. -    if (args->set)
  588. +    if (upcall->opcode == NFS41_SYSOP_SYMLINK_SET)
  589.          goto out;
  590.  
  591.      status = safe_write(&buffer, length, &len, sizeof(len));
  592. @@ -306,7 +322,14 @@ out:
  593.  }
  594.  
  595.  
  596. -const nfs41_upcall_op nfs41_op_symlink = {
  597. +const nfs41_upcall_op nfs41_op_symlink_get = {
  598. +    .parse = parse_symlink,
  599. +    .handle = handle_symlink,
  600. +    .marshall = marshall_symlink,
  601. +    .arg_size = sizeof(symlink_upcall_args)
  602. +};
  603. +
  604. +const nfs41_upcall_op nfs41_op_symlink_set = {
  605.      .parse = parse_symlink,
  606.      .handle = handle_symlink,
  607.      .marshall = marshall_symlink,
  608. diff --git a/daemon/upcall.c b/daemon/upcall.c
  609. index 67d6ef3..40cfdea 100644
  610. --- a/daemon/upcall.c
  611. +++ b/daemon/upcall.c
  612. @@ -1,5 +1,6 @@
  613.  /* NFSv4.1 client for Windows
  614. - * Copyright (C) 2012 The Regents of the University of Michigan
  615. + * Copyright (C) 2012 The Regents of the University of Michigan
  616. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  617.   *
  618.   * Olga Kornievskaia <aglo@umich.edu>
  619.   * Casey Bodley <cbodley@umich.edu>
  620. @@ -43,7 +44,8 @@ extern const nfs41_upcall_op nfs41_op_getattr;
  621.  extern const nfs41_upcall_op nfs41_op_setattr;
  622.  extern const nfs41_upcall_op nfs41_op_getexattr;
  623.  extern const nfs41_upcall_op nfs41_op_setexattr;
  624. -extern const nfs41_upcall_op nfs41_op_symlink;
  625. +extern const nfs41_upcall_op nfs41_op_symlink_get;
  626. +extern const nfs41_upcall_op nfs41_op_symlink_set;
  627.  extern const nfs41_upcall_op nfs41_op_volume;
  628.  extern const nfs41_upcall_op nfs41_op_getacl;
  629.  extern const nfs41_upcall_op nfs41_op_setacl;
  630. @@ -65,7 +67,8 @@ static const nfs41_upcall_op *g_upcall_op_table[] = {
  631.      &nfs41_op_setattr,
  632.      &nfs41_op_getexattr,
  633.      &nfs41_op_setexattr,
  634. -    &nfs41_op_symlink,
  635. +    &nfs41_op_symlink_get,
  636. +    &nfs41_op_symlink_set,
  637.      &nfs41_op_volume,
  638.      &nfs41_op_getacl,
  639.      &nfs41_op_setacl,
  640. diff --git a/daemon/upcall.h b/daemon/upcall.h
  641. index e601e3b..982471e 100644
  642. --- a/daemon/upcall.h
  643. +++ b/daemon/upcall.h
  644. @@ -161,7 +161,6 @@ typedef struct __symlink_upcall_args {
  645.      nfs41_abs_path target_get;
  646.      char *target_set;
  647.      const char *path;
  648. -    BOOLEAN set;
  649.  } symlink_upcall_args;
  650.  
  651.  typedef struct __volume_upcall_args {
  652. diff --git a/include/nfs41_driver.h b/include/nfs41_driver.h
  653. index 8b569d0..bddf5cc 100644
  654. --- a/include/nfs41_driver.h
  655. +++ b/include/nfs41_driver.h
  656. @@ -1,6 +1,6 @@
  657.  /* NFSv4.1 client for Windows
  658.   * Copyright (C) 2012 The Regents of the University of Michigan
  659. - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  660. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  661.   *
  662.   * Olga Kornievskaia <aglo@umich.edu>
  663.   * Casey Bodley <cbodley@umich.edu>
  664. @@ -77,7 +77,8 @@ typedef enum _nfs41_opcodes {
  665.      NFS41_SYSOP_FILE_SET,
  666.      NFS41_SYSOP_EA_GET,
  667.      NFS41_SYSOP_EA_SET,
  668. -    NFS41_SYSOP_SYMLINK,
  669. +    NFS41_SYSOP_SYMLINK_GET,
  670. +    NFS41_SYSOP_SYMLINK_SET,
  671.      NFS41_SYSOP_VOLUME_QUERY,
  672.      NFS41_SYSOP_ACL_QUERY,
  673.      NFS41_SYSOP_ACL_SET,
  674. diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
  675. index 8706565..33b801c 100644
  676. --- a/sys/nfs41sys_debug.c
  677. +++ b/sys/nfs41sys_debug.c
  678. @@ -1,5 +1,6 @@
  679.  /* NFSv4.1 client for Windows
  680. - * Copyright (C) 2012 The Regents of the University of Michigan
  681. + * Copyright (C) 2012 The Regents of the University of Michigan
  682. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  683.   *
  684.   * Olga Kornievskaia <aglo@umich.edu>
  685.   * Casey Bodley <cbodley@umich.edu>
  686. @@ -671,7 +672,8 @@ const char *opcode2string(int opcode)
  687.      case NFS41_SYSOP_FILE_SET: return "NFS41_SYSOP_FILE_SET";
  688.      case NFS41_SYSOP_EA_SET: return "NFS41_SYSOP_EA_SET";
  689.      case NFS41_SYSOP_EA_GET: return "NFS41_SYSOP_EA_GET";
  690. -    case NFS41_SYSOP_SYMLINK: return "NFS41_SYSOP_SYMLINK";
  691. +    case NFS41_SYSOP_SYMLINK_GET: return "NFS41_SYSOP_SYMLINK_GET";
  692. +    case NFS41_SYSOP_SYMLINK_SET: return "NFS41_SYSOP_SYMLINK_SET";
  693.      case NFS41_SYSOP_VOLUME_QUERY: return "NFS41_SYSOP_VOLUME_QUERY";
  694.      case NFS41_SYSOP_ACL_QUERY: return "NFS41_SYSOP_ACL_QUERY";
  695.      case NFS41_SYSOP_ACL_SET: return "NFS41_SYSOP_ACL_SET";
  696. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  697. index f14beb5..f4d3130 100644
  698. --- a/sys/nfs41sys_driver.h
  699. +++ b/sys/nfs41sys_driver.h
  700. @@ -261,7 +261,6 @@ typedef struct _updowncall_entry {
  701.          } QueryEa;
  702.          struct {
  703.              PUNICODE_STRING target;
  704. -            BOOLEAN set;
  705.          } Symlink;
  706.          struct {
  707.              FS_INFORMATION_CLASS query;
  708. diff --git a/sys/nfs41sys_ea.c b/sys/nfs41sys_ea.c
  709. index 629f3d8..0803f1b 100644
  710. --- a/sys/nfs41sys_ea.c
  711. +++ b/sys/nfs41sys_ea.c
  712. @@ -1,6 +1,6 @@
  713.  /* NFSv4.1 client for Windows
  714.   * Copyright (C) 2012 The Regents of the University of Michigan
  715. - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  716. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  717.   *
  718.   * Olga Kornievskaia <aglo@umich.edu>
  719.   * Casey Bodley <cbodley@umich.edu>
  720. @@ -473,13 +473,12 @@ NTSTATUS QueryCygwinSymlink(
  721.      TargetName.MaximumLength = (USHORT)min(RxContext->Info.LengthRemaining -
  722.          HeaderLen, 0xFFFF);
  723.  
  724. -    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK, &Fobx->sec_ctx,
  725. +    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_GET, &Fobx->sec_ctx,
  726.          VNetRootContext->session, Fobx->nfs41_open_state,
  727.          NetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
  728.      if (status) goto out;
  729.  
  730.      entry->u.Symlink.target = &TargetName;
  731. -    entry->u.Symlink.set = FALSE;
  732.  
  733.      status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
  734.      if (status) goto out;
  735. diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
  736. index 6e04074..6fb15e4 100644
  737. --- a/sys/nfs41sys_symlink.c
  738. +++ b/sys/nfs41sys_symlink.c
  739. @@ -1,6 +1,6 @@
  740.  /* NFSv4.1 client for Windows
  741.   * Copyright (C) 2012 The Regents of the University of Michigan
  742. - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  743. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  744.   *
  745.   * Olga Kornievskaia <aglo@umich.edu>
  746.   * Casey Bodley <cbodley@umich.edu>
  747. @@ -85,8 +85,8 @@ NTSTATUS marshal_nfs41_symlink(
  748.      if (status) goto out;
  749.      else tmp += *len;
  750.  
  751. -    header_len = *len + sizeof(BOOLEAN) + length_as_utf8(entry->filename);
  752. -    if (entry->u.Symlink.set)
  753. +    header_len = *len + length_as_utf8(entry->filename);
  754. +    if (entry->opcode == NFS41_SYSOP_SYMLINK_SET)
  755.          header_len += length_as_utf8(entry->u.Symlink.target);
  756.      if (header_len > buf_len) {
  757.          status = STATUS_INSUFFICIENT_RESOURCES;
  758. @@ -95,19 +95,25 @@ NTSTATUS marshal_nfs41_symlink(
  759.  
  760.      status = marshall_unicode_as_utf8(&tmp, entry->filename);
  761.      if (status) goto out;
  762. -    RtlCopyMemory(tmp, &entry->u.Symlink.set, sizeof(BOOLEAN));
  763. -    tmp += sizeof(BOOLEAN);
  764. -    if (entry->u.Symlink.set) {
  765. +    if (entry->opcode == NFS41_SYSOP_SYMLINK_SET) {
  766.          status = marshall_unicode_as_utf8(&tmp, entry->u.Symlink.target);
  767.          if (status) goto out;
  768.      }
  769.      *len = header_len;
  770.  
  771.  #ifdef DEBUG_MARSHAL_DETAIL
  772. -    DbgP("marshal_nfs41_symlink: name '%wZ' symlink target '%wZ'\n",
  773. -         entry->filename,
  774. -         entry->u.Symlink.set?entry->u.Symlink.target : NULL);
  775. -#endif
  776. +    if (entry->opcode == NFS41_SYSOP_SYMLINK_SET) {
  777. +        DbgP("marshal_nfs41_symlink: "
  778. +            "SET: name '%wZ' symlink target '%wZ'\n",
  779. +            entry->filename,
  780. +            entry->u.Symlink.target);
  781. +    }
  782. +    else {
  783. +        DbgP("marshal_nfs41_symlink: "
  784. +            "GET: name '%wZ'\n",
  785. +            entry->filename);
  786. +    }
  787. +#endif /* DEBUG_MARSHAL_DETAIL */
  788.  out:
  789.      return status;
  790.  }
  791. @@ -116,7 +122,8 @@ void unmarshal_nfs41_symlink(
  792.      nfs41_updowncall_entry *cur,
  793.      unsigned char **buf)
  794.  {
  795. -    if (cur->u.Symlink.set) return;
  796. +    if (cur->opcode == NFS41_SYSOP_SYMLINK_SET)
  797. +        return;
  798.  
  799.      RtlCopyMemory(&cur->u.Symlink.target->Length, *buf, sizeof(USHORT));
  800.      *buf += sizeof(USHORT);
  801. @@ -296,13 +303,12 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
  802.      TargetName.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
  803.          Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
  804.  
  805. -    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK, &Fobx->sec_ctx,
  806. +    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_SET, &Fobx->sec_ctx,
  807.          VNetRootContext->session, Fobx->nfs41_open_state,
  808.          pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
  809.      if (status) goto out;
  810.  
  811.      entry->u.Symlink.target = &TargetName;
  812. -    entry->u.Symlink.set = TRUE;
  813.  
  814.      status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
  815.      if (status) goto out;
  816. @@ -395,13 +401,12 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
  817.      TargetName.MaximumLength = (USHORT)min(FsCtl->OutputBufferLength -
  818.          HeaderLen, 0xFFFF);
  819.  
  820. -    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK, &Fobx->sec_ctx,
  821. +    status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_GET, &Fobx->sec_ctx,
  822.          VNetRootContext->session, Fobx->nfs41_open_state,
  823.          pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
  824.      if (status) goto out;
  825.  
  826.      entry->u.Symlink.target = &TargetName;
  827. -    entry->u.Symlink.set = FALSE;
  828.  
  829.      status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
  830.      if (status) goto out;
  831. diff --git a/sys/nfs41sys_updowncall.c b/sys/nfs41sys_updowncall.c
  832. index b359d2a..0f2afa6 100644
  833. --- a/sys/nfs41sys_updowncall.c
  834. +++ b/sys/nfs41sys_updowncall.c
  835. @@ -1,6 +1,6 @@
  836.  /* NFSv4.1 client for Windows
  837.   * Copyright (C) 2012 The Regents of the University of Michigan
  838. - * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  839. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  840.   *
  841.   * Olga Kornievskaia <aglo@umich.edu>
  842.   * Casey Bodley <cbodley@umich.edu>
  843. @@ -289,7 +289,8 @@ NTSTATUS handle_upcall(
  844.      case NFS41_SYSOP_EA_GET:
  845.          status = marshal_nfs41_eaget(entry, pbOut, cbOut, len);
  846.          break;
  847. -    case NFS41_SYSOP_SYMLINK:
  848. +    case NFS41_SYSOP_SYMLINK_GET:
  849. +    case NFS41_SYSOP_SYMLINK_SET:
  850.          status = marshal_nfs41_symlink(entry, pbOut, cbOut, len);
  851.          break;
  852.      case NFS41_SYSOP_VOLUME_QUERY:
  853. @@ -631,7 +632,8 @@ NTSTATUS nfs41_downcall(
  854.          case NFS41_SYSOP_EA_GET:
  855.              unmarshal_nfs41_eaget(cur, &buf);
  856.              break;
  857. -        case NFS41_SYSOP_SYMLINK:
  858. +        case NFS41_SYSOP_SYMLINK_GET:
  859. +        case NFS41_SYSOP_SYMLINK_SET:
  860.              unmarshal_nfs41_symlink(cur, &buf);
  861.              break;
  862.          case NFS41_SYSOP_VOLUME_QUERY:
  863. --
  864. 2.45.1
  865.  
  866. From 77cd75950da001e4807c0feb4bee6283cca2a72e Mon Sep 17 00:00:00 2001
  867. From: Roland Mainz <roland.mainz@nrubsig.org>
  868. Date: Wed, 5 Feb 2025 11:28:08 +0100
  869. Subject: [PATCH 4/6] sys: |map_symlink_errors()| should handle
  870.  |ERROR_*_NOT_FOUND|
  871.  
  872. |map_symlink_errors()| should handle |ERROR_FILE_NOT_FOUND| and
  873. |ERROR_PATH_NOT_FOUND|.
  874.  
  875. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  876. ---
  877. sys/nfs41sys_symlink.c | 2 ++
  878.  1 file changed, 2 insertions(+)
  879.  
  880. diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
  881. index 6fb15e4..1480ace 100644
  882. --- a/sys/nfs41sys_symlink.c
  883. +++ b/sys/nfs41sys_symlink.c
  884. @@ -142,6 +142,8 @@ NTSTATUS map_symlink_errors(
  885.  {
  886.      switch (status) {
  887.      case NO_ERROR:                  return STATUS_SUCCESS;
  888. +    case ERROR_FILE_NOT_FOUND:      return STATUS_OBJECT_NAME_NOT_FOUND;
  889. +    case ERROR_PATH_NOT_FOUND:      return STATUS_OBJECT_PATH_NOT_FOUND;
  890.      case ERROR_INVALID_REPARSE_DATA: return STATUS_IO_REPARSE_DATA_INVALID;
  891.      case ERROR_NOT_A_REPARSE_POINT: return STATUS_NOT_A_REPARSE_POINT;
  892.      case ERROR_ACCESS_DENIED:       return STATUS_ACCESS_DENIED;
  893. --
  894. 2.45.1
  895.  
  896. From a71e2b790377bddc069bb2c32c161806bf0c5475 Mon Sep 17 00:00:00 2001
  897. From: Roland Mainz <roland.mainz@nrubsig.org>
  898. Date: Wed, 5 Feb 2025 11:53:28 +0100
  899. Subject: [PATCH 5/6] sys: Move(+cleanup) |print_reparse_buffer()| to
  900.  nfs41sys_reparse.c
  901.  
  902. Move(+cleanup) |print_reparse_buffer()| to nfs41sys_reparse.c
  903.  
  904. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  905. ---
  906. sys/nfs41sys_driver.h  |  2 ++
  907.  sys/nfs41sys_reparse.c | 57 ++++++++++++++++++++++++++++++++++++++++++
  908.  sys/nfs41sys_symlink.c | 31 -----------------------
  909.  3 files changed, 59 insertions(+), 31 deletions(-)
  910.  
  911. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  912. index f4d3130..4b875ee 100644
  913. --- a/sys/nfs41sys_driver.h
  914. +++ b/sys/nfs41sys_driver.h
  915. @@ -777,6 +777,8 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
  916.      IN OUT PRX_CONTEXT RxContext);
  917.  NTSTATUS nfs41_GetSymlinkReparsePoint(
  918.      IN OUT PRX_CONTEXT RxContext);
  919. +void print_reparse_buffer(
  920. +    PREPARSE_DATA_BUFFER r);
  921.  
  922.  /* nfs41sys_reparse.c */
  923.  NTSTATUS nfs41_SetReparsePoint(
  924. diff --git a/sys/nfs41sys_reparse.c b/sys/nfs41sys_reparse.c
  925. index 0b1e726..df4fa1f 100644
  926. --- a/sys/nfs41sys_reparse.c
  927. +++ b/sys/nfs41sys_reparse.c
  928. @@ -115,3 +115,60 @@ NTSTATUS nfs41_GetReparsePoint(
  929.      DbgEx();
  930.      return status;
  931.  }
  932. +
  933. +void print_reparse_buffer(
  934. +    PREPARSE_DATA_BUFFER r)
  935. +{
  936. +    UNICODE_STRING name;
  937. +    DbgP("ReparseTag: 0x%lx\n", (long)r->ReparseTag);
  938. +    DbgP("ReparseDataLength: %u\n", (int)r->ReparseDataLength);
  939. +    DbgP("Reserved: %u\n", (int)r->Reserved);
  940. +    if (r->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
  941. +        DbgP("IO_REPARSE_TAG_SYMLINK:\n");
  942. +        DbgP("SubstituteNameOffset: %u\n",
  943. +            r->SymbolicLinkReparseBuffer.SubstituteNameOffset);
  944. +        DbgP("SubstituteNameLength: %u\n",
  945. +            r->SymbolicLinkReparseBuffer.SubstituteNameLength);
  946. +        DbgP("PrintNameOffset: %u\n",
  947. +            r->SymbolicLinkReparseBuffer.PrintNameOffset);
  948. +        DbgP("PrintNameLength: %u\n",
  949. +            r->SymbolicLinkReparseBuffer.PrintNameLength);
  950. +        DbgP("Flags: 0x%lx\n",
  951. +            (long)r->SymbolicLinkReparseBuffer.Flags);
  952. +
  953. +        name.Buffer = &r->SymbolicLinkReparseBuffer.PathBuffer[
  954. +            r->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
  955. +        name.MaximumLength = name.Length =
  956. +            r->SymbolicLinkReparseBuffer.SubstituteNameLength;
  957. +        DbgP("SubstituteName: '%wZ'\n", &name);
  958. +
  959. +        name.Buffer = &r->SymbolicLinkReparseBuffer.PathBuffer[
  960. +            r->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
  961. +        name.MaximumLength = name.Length =
  962. +            r->SymbolicLinkReparseBuffer.PrintNameLength;
  963. +            DbgP("PrintName: '%wZ'\n", &name);
  964. +    }
  965. +    else if (r->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
  966. +        DbgP("IO_REPARSE_TAG_MOUNT_POINT:\n");
  967. +        DbgP("SubstituteNameOffset: %u\n",
  968. +            r->MountPointReparseBuffer.SubstituteNameOffset);
  969. +        DbgP("SubstituteNameLength: %u\n",
  970. +            r->MountPointReparseBuffer.SubstituteNameLength);
  971. +        DbgP("PrintNameOffset: %u\n",
  972. +            r->MountPointReparseBuffer.PrintNameOffset);
  973. +        DbgP("PrintNameLength: %u\n",
  974. +            r->MountPointReparseBuffer.PrintNameLength);
  975. +
  976. +        name.Buffer = &r->MountPointReparseBuffer.PathBuffer[
  977. +            r->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
  978. +        name.MaximumLength = name.Length =
  979. +            r->MountPointReparseBuffer.SubstituteNameLength;
  980. +        DbgP("SubstituteName: '%wZ'\n", &name);
  981. +
  982. +        name.Buffer = &r->MountPointReparseBuffer.PathBuffer[
  983. +            r->MountPointReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
  984. +        name.MaximumLength = name.Length =
  985. +            r->MountPointReparseBuffer.PrintNameLength;
  986. +            DbgP("PrintName: '%wZ'\n", &name);
  987. +    }
  988. +}
  989. diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
  990. index 1480ace..cb57082 100644
  991. --- a/sys/nfs41sys_symlink.c
  992. +++ b/sys/nfs41sys_symlink.c
  993. @@ -166,37 +166,6 @@ NTSTATUS map_symlink_errors(
  994.      }
  995.  }
  996.  
  997. -static void print_reparse_buffer(
  998. -    PREPARSE_DATA_BUFFER Reparse)
  999. -{
  1000. -    UNICODE_STRING name;
  1001. -    DbgP("ReparseTag:           %08X\n", Reparse->ReparseTag);
  1002. -    DbgP("ReparseDataLength:    %8u\n", Reparse->ReparseDataLength);
  1003. -    DbgP("Reserved:             %8u\n", Reparse->Reserved);
  1004. -    DbgP("SubstituteNameOffset: %8u\n",
  1005. -         Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset);
  1006. -    DbgP("SubstituteNameLength: %8u\n",
  1007. -         Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength);
  1008. -    DbgP("PrintNameOffset:      %8u\n",
  1009. -         Reparse->SymbolicLinkReparseBuffer.PrintNameOffset);
  1010. -    DbgP("PrintNameLength:      %8u\n",
  1011. -         Reparse->SymbolicLinkReparseBuffer.PrintNameLength);
  1012. -    DbgP("Flags:                %08X\n",
  1013. -         Reparse->SymbolicLinkReparseBuffer.Flags);
  1014. -
  1015. -    name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
  1016. -        Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
  1017. -    name.MaximumLength = name.Length =
  1018. -        Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
  1019. -    DbgP("SubstituteName:       '%wZ'\n", &name);
  1020. -
  1021. -    name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
  1022. -        Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
  1023. -    name.MaximumLength = name.Length =
  1024. -        Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
  1025. -    DbgP("PrintName:            '%wZ'\n", &name);
  1026. -}
  1027. -
  1028.  static
  1029.  NTSTATUS check_nfs41_setsymlinkreparse_args(
  1030.      IN PRX_CONTEXT RxContext)
  1031. --
  1032. 2.45.1
  1033.  
  1034. From 0d84cbd51ea9abc30f5c69558a8ce626335a9c90 Mon Sep 17 00:00:00 2001
  1035. From: Roland Mainz <roland.mainz@nrubsig.org>
  1036. Date: Wed, 5 Feb 2025 21:18:27 +0100
  1037. Subject: [PATCH 6/6] sys: Convert Windows (deviceletter, UNC, relative)
  1038.  symlinks to/from POSIX symlinks
  1039.  
  1040. Convert Windows (deviceletter, UNC, relative) symlinks into POSIX symlinks
  1041. and POSIX symlinks into Windows (deviceletter, UNC, relative) symlinks,
  1042. and reject malformed POSIX symlinks (e.g. POSIX "X:/foo" will be rejected).
  1043.  
  1044. Reported-by: Lionel Cons <lionelcons1972@gmail.com>
  1045. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  1046. ---
  1047. sys/nfs41sys_symlink.c | 401 ++++++++++++++++++++++++++++++++++++++---
  1048.  1 file changed, 375 insertions(+), 26 deletions(-)
  1049.  
  1050. diff --git a/sys/nfs41sys_symlink.c b/sys/nfs41sys_symlink.c
  1051. index cb57082..eea2db8 100644
  1052. --- a/sys/nfs41sys_symlink.c
  1053. +++ b/sys/nfs41sys_symlink.c
  1054. @@ -58,6 +58,7 @@
  1055.  #include <winerror.h>
  1056.  
  1057.  #include <Ntstrsafe.h>
  1058. +#include <stdbool.h>
  1059.  
  1060.  #include "nfs41sys_buildconfig.h"
  1061.  
  1062. @@ -248,7 +249,8 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
  1063.          NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
  1064.      __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
  1065.          NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
  1066. -    nfs41_updowncall_entry *entry;
  1067. +    nfs41_updowncall_entry *entry = NULL;
  1068. +    PWSTR prefixed_targetname = NULL;
  1069.  
  1070.  #ifdef DEBUG_SYMLINK
  1071.      DbgEn();
  1072. @@ -269,10 +271,110 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
  1073.          goto out;
  1074.      }
  1075.  
  1076. +    if (Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
  1077. +        status = IO_REPARSE_TAG_SYMLINK;
  1078. +        DbgP("nfs41_SetSymlinkReparsePoint: "
  1079. +            "Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK\n");
  1080. +        goto out;
  1081. +    }
  1082. +
  1083.      TargetName.MaximumLength = TargetName.Length =
  1084. -        Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
  1085. +        Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
  1086.      TargetName.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
  1087. -        Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
  1088. +        Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
  1089. +
  1090. +    if (TargetName.Buffer[0] == L'.') {
  1091. +        DbgP("nfs41_SetSymlinkReparsePoint: "
  1092. +            "relative path TargetName='%wZ'\n",
  1093. +            &TargetName);
  1094. +    }
  1095. +    else {
  1096. +        DbgP("nfs41_SetSymlinkReparsePoint: "
  1097. +            "absolute path TargetName='%wZ'\n",
  1098. +            &TargetName);
  1099. +
  1100. +        /* Strip "\\??\\" prefix */
  1101. +        if (!memcmp(&TargetName.Buffer[0], L"\\??\\",
  1102. +            (4*sizeof(wchar_t)))) {
  1103. +            TargetName.Buffer += 4;
  1104. +            TargetName.MaximumLength = TargetName.Length =
  1105. +                TargetName.Length-(4*sizeof(wchar_t));
  1106. +        }
  1107. +
  1108. +        /* UNC path ? */
  1109. +        if (!memcmp(&TargetName.Buffer[0], L"UNC\\",
  1110. +            (4*sizeof(wchar_t)))) {
  1111. +
  1112. +            /*
  1113. +             * Turn "UNC\" into "\\"
  1114. +             * (userland daemon will convert the backslashes in UNC
  1115. +             * path to slashes)
  1116. +             */
  1117. +            TargetName.Buffer += 2;
  1118. +            TargetName.MaximumLength = TargetName.Length =
  1119. +                TargetName.Length-(2*sizeof(wchar_t));
  1120. +            TargetName.Buffer[0] = L'\\';
  1121. +
  1122. +            DbgP("nfs41_SetSymlinkReparsePoint: "
  1123. +                "UNC TargetName='%wZ'\n",
  1124. +                &TargetName);
  1125. +        }
  1126. +        else {
  1127. +            wchar_t devletter;
  1128. +
  1129. +            DbgP("nfs41_SetSymlinkReparsePoint: "
  1130. +                "DEVLETTER TargetName='%wZ'\n",
  1131. +                &TargetName);
  1132. +
  1133. +            if ((TargetName.Buffer[1] != L':') ||
  1134. +                (TargetName.Buffer[2] != L'\\')) {
  1135. +                status = STATUS_INVALID_PARAMETER;
  1136. +                DbgP("nfs41_SetSymlinkReparsePoint: "
  1137. +                    "DEVLETTER path '%wZ' should start with 'L:\\'\n",
  1138. +                    &TargetName);
  1139. +                goto out;
  1140. +            }
  1141. +
  1142. +            /* Get devletter and skip "L:\" "*/
  1143. +            devletter = towlower(TargetName.Buffer[0]);
  1144. +            TargetName.Buffer += 3;
  1145. +            TargetName.MaximumLength = TargetName.Length =
  1146. +                TargetName.Length-(3*sizeof(wchar_t));
  1147. +
  1148. +            DbgP("nfs41_SetSymlinkReparsePoint: "
  1149. +                "deviceletter='%C' path='%wZ'\n",
  1150. +                devletter,
  1151. +                &TargetName);
  1152. +
  1153. +            size_t prefixed_targetname_len = 4096*sizeof(wchar_t);
  1154. +
  1155. +            prefixed_targetname = RxAllocatePoolWithTag(NonPagedPoolNx,
  1156. +                prefixed_targetname_len, NFS41_MM_POOLTAG);
  1157. +            if (prefixed_targetname == NULL) {
  1158. +                status = STATUS_INSUFFICIENT_RESOURCES;
  1159. +                goto out;
  1160. +            }
  1161. +
  1162. +            /*
  1163. +             * Stuff Cygwin /cygdrive/<deviceletter>/ prefix in front
  1164. +             * of path, userland daemon will convert the backslashes
  1165. +             * to slashes
  1166. +             */
  1167. +            (void)_snwprintf(prefixed_targetname,
  1168. +                prefixed_targetname_len, L"\\cygdrive\\%C\\%wZ",
  1169. +                devletter,
  1170. +                &TargetName);
  1171. +
  1172. +            /* Put new buffer into target name */
  1173. +            TargetName.MaximumLength = TargetName.Length =
  1174. +                (USHORT)(wcslen(prefixed_targetname)*sizeof(wchar_t));
  1175. +            TargetName.Buffer = prefixed_targetname;
  1176. +
  1177. +            DbgP("nfs41_SetSymlinkReparsePoint: "
  1178. +                "new TargetName='%wZ'\n",
  1179. +                &TargetName);
  1180. +        }
  1181. +    }
  1182.  
  1183.      status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_SET, &Fobx->sec_ctx,
  1184.          VNetRootContext->session, Fobx->nfs41_open_state,
  1185. @@ -285,8 +387,12 @@ NTSTATUS nfs41_SetSymlinkReparsePoint(
  1186.      if (status) goto out;
  1187.  
  1188.      status = map_symlink_errors(entry->status);
  1189. -    nfs41_UpcallDestroy(entry);
  1190.  out:
  1191. +    if (entry)
  1192. +        nfs41_UpcallDestroy(entry);
  1193. +    if (prefixed_targetname)
  1194. +        RxFreePool(prefixed_targetname);
  1195. +
  1196.  #ifdef DEBUG_SYMLINK
  1197.      DbgEx();
  1198.  #endif
  1199. @@ -340,6 +446,75 @@ out:
  1200.      return status;
  1201.  }
  1202.  
  1203. +static
  1204. +bool is_us_relative_path(UNICODE_STRING *restrict us)
  1205. +{
  1206. +    /* Match exactly "." (single dot) */
  1207. +    if ((us->Length == (1*sizeof(wchar_t))) &&
  1208. +        (us->Buffer[0] == L'.'))
  1209. +        return true;
  1210. +
  1211. +    /* Match exactly ".." (double dot) */
  1212. +    if ((us->Length == (2*sizeof(wchar_t)) &&
  1213. +        (!memcmp(&us->Buffer[0], L"..", (2*sizeof(wchar_t))))))
  1214. +        return true;
  1215. +
  1216. +    /* Match "..\..." */
  1217. +    if ((us->Length >= (3*sizeof(wchar_t))) &&
  1218. +        (!memcmp(&us->Buffer[0], L"..\\", (3*sizeof(wchar_t)))))
  1219. +        return true;
  1220. +
  1221. +    /* Match ".\..." */
  1222. +    if ((us->Length >= (2*sizeof(wchar_t))) &&
  1223. +        (!memcmp(&us->Buffer[0], L".\\", (2*sizeof(wchar_t)))))
  1224. +        return true;
  1225. +
  1226. +    /* Reject any absolute paths or similar stuff */
  1227. +    if ((us->Length >= (1*sizeof(wchar_t)) &&
  1228. +        (
  1229. +            (us->Buffer[0] == L'\\') ||
  1230. +            (us->Buffer[0] == L'/')
  1231. +        ))) {
  1232. +        return false;
  1233. +    }
  1234. +
  1235. +    /*
  1236. +     * Reject paths like L: (':' is an illegal filesystem name
  1237. +     * character, reserved for alternate data streams only)
  1238. +     */
  1239. +    if ((us->Length >= (2*sizeof(wchar_t)) &&
  1240. +        (us->Buffer[1] == L':'))) {
  1241. +        return false;
  1242. +    }
  1243. +
  1244. +    /*
  1245. +     * Handle the case of symlink foo --> bar (and foo -->bar/baz),
  1246. +     * e.g. symlinking one name to a file/dir in the same directory
  1247. +     */
  1248. +    return true;
  1249. +}
  1250. +
  1251. +static
  1252. +bool is_us_unc_path(UNICODE_STRING *restrict us)
  1253. +{
  1254. +    if (!memcmp(&us->Buffer[0], L"\\\\", (2*sizeof(wchar_t))))
  1255. +        return true;
  1256. +    return false;
  1257. +}
  1258. +
  1259. +static
  1260. +bool is_us_cygdrive_path(UNICODE_STRING *restrict us)
  1261. +{
  1262. +    /* Fixme: What about MSYS2 ? */
  1263. +
  1264. +    /* "/cygdrive/l" == 11 characters */
  1265. +    if ((us->Length >= (11*sizeof(wchar_t))) &&
  1266. +        (!memcmp(&us->Buffer[0],
  1267. +            L"\\cygdrive\\", (10*sizeof(wchar_t)))))
  1268. +        return true;
  1269. +    return false;
  1270. +}
  1271. +
  1272.  NTSTATUS nfs41_GetSymlinkReparsePoint(
  1273.      IN OUT PRX_CONTEXT RxContext)
  1274.  {
  1275. @@ -352,9 +527,8 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
  1276.          NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
  1277.      __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
  1278.          NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
  1279. -    nfs41_updowncall_entry *entry;
  1280. -    const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1281. -        SymbolicLinkReparseBuffer.PathBuffer);
  1282. +    nfs41_updowncall_entry *entry = NULL;
  1283. +    PWSTR targetname_buffer = NULL;
  1284.  
  1285.  #ifdef DEBUG_SYMLINK
  1286.      DbgEn();
  1287. @@ -368,9 +542,16 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
  1288.          goto out;
  1289.      }
  1290.  
  1291. -    TargetName.Buffer = (PWCH)((PBYTE)FsCtl->pOutputBuffer + HeaderLen);
  1292. -    TargetName.MaximumLength = (USHORT)min(FsCtl->OutputBufferLength -
  1293. -        HeaderLen, 0xFFFF);
  1294. +    size_t targetname_buffer_len = 4096*sizeof(wchar_t);
  1295. +    targetname_buffer = RxAllocatePoolWithTag(NonPagedPoolNx,
  1296. +        targetname_buffer_len, NFS41_MM_POOLTAG);
  1297. +    if (targetname_buffer == NULL) {
  1298. +        status = STATUS_INSUFFICIENT_RESOURCES;
  1299. +        goto out;
  1300. +    }
  1301. +
  1302. +    TargetName.Buffer = targetname_buffer;
  1303. +    TargetName.MaximumLength = (USHORT)targetname_buffer_len;
  1304.  
  1305.      status = nfs41_UpcallCreate(NFS41_SYSOP_SYMLINK_GET, &Fobx->sec_ctx,
  1306.          VNetRootContext->session, Fobx->nfs41_open_state,
  1307. @@ -387,27 +568,195 @@ NTSTATUS nfs41_GetSymlinkReparsePoint(
  1308.          /* fill in the output buffer */
  1309.          PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)
  1310.              FsCtl->pOutputBuffer;
  1311. -        Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
  1312. -        Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
  1313. +
  1314. +        DbgP("nfs41_GetSymlinkReparsePoint: "
  1315. +            "got TargetName='%wZ', len=%d\n",
  1316. +            &TargetName, (int)TargetName.Length);
  1317. +
  1318. +        /* POSIX slash to Win32 backslash */
  1319. +        size_t i;
  1320. +        for (i=0 ; i < TargetName.Length ; i++) {
  1321. +            if (TargetName.Buffer[i] == L'/')
  1322. +                TargetName.Buffer[i] = L'\\';
  1323. +        }
  1324. +
  1325. +        DbgP("nfs41_GetSymlinkReparsePoint: "
  1326. +            "TargetName='%wZ' with '/'-->'\\' conversion\n",
  1327. +            &TargetName);
  1328. +
  1329. +        if (is_us_cygdrive_path(&TargetName)) {
  1330. +            const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1331. +                SymbolicLinkReparseBuffer.PathBuffer);
  1332. +
  1333. +            DbgP("nfs41_GetSymlinkReparsePoint: /cygdrive/ codepath\n");
  1334. +
  1335. +            wchar_t dosletter;
  1336. +            dosletter = towupper(TargetName.Buffer[10]);
  1337. +            TargetName.Buffer += 9;
  1338. +            TargetName.MaximumLength = TargetName.Length =
  1339. +                TargetName.Length-(9*sizeof(wchar_t));
  1340. +
  1341. +            /* If we only have "L:" turn this into "L:\" */
  1342. +            if (TargetName.Length == (2*sizeof(wchar_t))) {
  1343. +                TargetName.MaximumLength = TargetName.Length =
  1344. +                    TargetName.Length + (1*sizeof(wchar_t));
  1345. +            }
  1346. +
  1347. +            TargetName.Buffer[0] = dosletter;
  1348. +            TargetName.Buffer[1] = L':';
  1349. +            TargetName.Buffer[2] = L'\\';
  1350. +
  1351. +            DbgP("nfs41_GetSymlinkReparsePoint: new TargetName='%wZ'\n",
  1352. +                &TargetName);
  1353. +
  1354. +            /* Copy data into FsCtl buffer  */
  1355. +            PWCH outbuff = (PWCH)(((PBYTE)FsCtl->pOutputBuffer) + HeaderLen);
  1356. +            (void)memcpy(outbuff, TargetName.Buffer, TargetName.Length);
  1357. +            TargetName.Buffer = outbuff;
  1358. +
  1359. +            DbgP("nfs41_GetSymlinkReparsePoint: new TargetName='%wZ'\n",
  1360. +                &TargetName);
  1361. +
  1362. +            Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
  1363. +            Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
  1364. +                REPARSE_DATA_BUFFER_HEADER_SIZE;
  1365. +            Reparse->Reserved = 0;
  1366. +            /* /cygwin/<devletter>/ are absolute paths */
  1367. +#define CYGWIN_WANTS_SYMLINKFLAGRELATIVE_FOR_ABS_PATHS 1 /* FIXME: Why ? */
  1368. +
  1369. +#ifdef CYGWIN_WANTS_SYMLINKFLAGRELATIVE_FOR_ABS_PATHS
  1370. +            Reparse->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;
  1371. +#else
  1372. +            Reparse->SymbolicLinkReparseBuffer.Flags = 0;
  1373. +#endif
  1374. +
  1375. +            /* PrintName and SubstituteName point to the same string */
  1376. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
  1377. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
  1378. +                TargetName.Length;
  1379. +            Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
  1380. +            Reparse->SymbolicLinkReparseBuffer.PrintNameLength =
  1381. +                TargetName.Length;
  1382. +
  1383. +            print_reparse_buffer(Reparse);
  1384. +
  1385. +            RxContext->IoStatusBlock.Information =
  1386. +                (ULONG_PTR)HeaderLen + TargetName.Length;
  1387. +        }
  1388. +        else if (is_us_unc_path(&TargetName)) {
  1389. +            /*
  1390. +             * FIXME: UNC paths should return
  1391. +             * |IO_REPARSE_TAG_MOUNT_POINT|, but Cygwin does not
  1392. +             * support |IO_REPARSE_TAG_MOUNT_POINT| for remote
  1393. +             * filesystems.
  1394. +             * Note that we if we switch this over to
  1395. +             * |IO_REPARSE_TAG_MOUNT_POINT| we also have to teach
  1396. +             * daemon/readdir.c&co that we have more than one type
  1397. +             * of reparse tag
  1398. +             */
  1399. +            const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1400. +                SymbolicLinkReparseBuffer.PathBuffer);
  1401. +
  1402. +            DbgP("nfs41_GetSymlinkReparsePoint: UNC codepath\n");
  1403. +
  1404. +            /* Copy data into FsCtl buffer  */
  1405. +            PWCH outbuff = (PWCH)(((PBYTE)FsCtl->pOutputBuffer) + HeaderLen);
  1406. +            (void)memcpy(outbuff, TargetName.Buffer, TargetName.Length);
  1407. +            TargetName.Buffer = outbuff;
  1408. +
  1409. +
  1410. +            DbgP("nfs41_GetSymlinkReparsePoint: "
  1411. +                "new UNC TargetName='%wZ'\n",
  1412. +                &TargetName);
  1413. +
  1414. +            Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
  1415. +            Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
  1416.              REPARSE_DATA_BUFFER_HEADER_SIZE;
  1417. -        Reparse->Reserved = 0;
  1418. -        Reparse->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;
  1419. -        /* PrintName and SubstituteName point to the same string */
  1420. -        Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
  1421. -        Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
  1422. -            TargetName.Length;
  1423. -        Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
  1424. -        Reparse->SymbolicLinkReparseBuffer.PrintNameLength = TargetName.Length;
  1425. -        print_reparse_buffer(Reparse);
  1426. -
  1427. -        RxContext->IoStatusBlock.Information =
  1428. -            (ULONG_PTR)HeaderLen + TargetName.Length;
  1429. +            Reparse->Reserved = 0;
  1430. +            /* UNC paths are absolute paths */
  1431. +#ifdef CYGWIN_WANTS_SYMLINKFLAGRELATIVE_FOR_ABS_PATHS
  1432. +            Reparse->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;
  1433. +#else
  1434. +            Reparse->SymbolicLinkReparseBuffer.Flags = 0;
  1435. +#endif
  1436. +
  1437. +            /* PrintName and SubstituteName point to the same string */
  1438. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
  1439. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
  1440. +                TargetName.Length;
  1441. +            Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
  1442. +            Reparse->SymbolicLinkReparseBuffer.PrintNameLength =
  1443. +                TargetName.Length;
  1444. +
  1445. +            print_reparse_buffer(Reparse);
  1446. +
  1447. +            RxContext->IoStatusBlock.Information =
  1448. +                (ULONG_PTR)HeaderLen + TargetName.Length;
  1449. +        }
  1450. +        else if (is_us_relative_path(&TargetName)) {
  1451. +            const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1452. +                SymbolicLinkReparseBuffer.PathBuffer);
  1453. +
  1454. +            DbgP("nfs41_GetSymlinkReparsePoint: relative symlink codepath\n");
  1455. +
  1456. +            /* Copy data into FsCtl buffer  */
  1457. +            (void)memcpy(((PBYTE)FsCtl->pOutputBuffer + HeaderLen),
  1458. +                TargetName.Buffer, TargetName.Length);
  1459. +            TargetName.Buffer =
  1460. +                (PWCH)((PBYTE)FsCtl->pOutputBuffer + HeaderLen);
  1461. +
  1462. +            DbgP("nfs41_GetSymlinkReparsePoint: "
  1463. +                "new relative TargetName='%wZ'\n",
  1464. +                &TargetName);
  1465. +
  1466. +            Reparse->ReparseTag = IO_REPARSE_TAG_SYMLINK;
  1467. +            Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
  1468. +            REPARSE_DATA_BUFFER_HEADER_SIZE;
  1469. +            Reparse->Reserved = 0;
  1470. +            Reparse->SymbolicLinkReparseBuffer.Flags =
  1471. +                SYMLINK_FLAG_RELATIVE;
  1472. +            /* PrintName and SubstituteName point to the same string */
  1473. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
  1474. +            Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
  1475. +                TargetName.Length;
  1476. +            Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
  1477. +            Reparse->SymbolicLinkReparseBuffer.PrintNameLength =
  1478. +                TargetName.Length;
  1479. +
  1480. +            print_reparse_buffer(Reparse);
  1481. +
  1482. +            RxContext->IoStatusBlock.Information =
  1483. +                (ULONG_PTR)HeaderLen + TargetName.Length;
  1484. +        }
  1485. +        else {
  1486. +            status = STATUS_IO_REPARSE_DATA_INVALID;
  1487. +            DbgP("nfs41_GetSymlinkReparsePoint: "
  1488. +                "cannot parse symlink data TargetName='%wZ'\n",
  1489. +                &TargetName);
  1490. +        }
  1491.      } else if (status == STATUS_BUFFER_TOO_SMALL) {
  1492. +        const size_t sym_hdr_len =
  1493. +            FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1494. +                MountPointReparseBuffer.PathBuffer);
  1495. +        const size_t mnt_hdr_len =
  1496. +            FIELD_OFFSET(REPARSE_DATA_BUFFER,
  1497. +                SymbolicLinkReparseBuffer.PathBuffer);
  1498. +        /*
  1499. +         * We don't know whether we have to return
  1500. +         * |IO_REPARSE_TAG_MOUNT_POINT| or |IO_REPARSE_TAG_SYMLINK|,
  1501. +         * so we return a size which can fit both
  1502. +         */
  1503. +#define MAX(a, b) (((a) > (b)) ? (a) : (b))
  1504.          RxContext->InformationToReturn =
  1505. -            (ULONG_PTR)HeaderLen + TargetName.Length;
  1506. +            MAX(sym_hdr_len, mnt_hdr_len) + TargetName.Length;
  1507.      }
  1508. -    nfs41_UpcallDestroy(entry);
  1509. +
  1510.  out:
  1511. +    if (entry)
  1512. +        nfs41_UpcallDestroy(entry);
  1513. +    if (targetname_buffer)
  1514. +        RxFreePool(targetname_buffer);
  1515. +
  1516.  #ifdef DEBUG_SYMLINK
  1517.      DbgEx();
  1518.  #endif
  1519. --
  1520. 2.45.1

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at