pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Long path support and misc stuff, 2023-12-05
Posted by Anonymous on Tue 5th Dec 2023 14:59
raw | new post

  1. From 60bb8f7497b7b17695a91364ef43c93463bc5a87 Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Fri, 1 Dec 2023 16:06:15 +0100
  4. Subject: [PATCH 1/4] daemon: Enable FileSystemAttributes FILE_UNICODE_ON_DISK
  5.  
  6. Enable FileSystemAttributes |FILE_UNICODE_ON_DISK|, as the NFSv4
  7. protocol supports Unicode by default (assuming that the underlying
  8. storage filesystem used by the NFSv4 server supports that too),
  9. so that |GetVolumeInformationByHandleW()| will return it.
  10.  
  11. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  12. ---
  13.  cygwin/Makefile              |   8 ++-
  14.  daemon/nfs41_superblock.c    |  28 ++++++--
  15.  tests/winfsinfo1/Makefile    |  15 ++++
  16.  tests/winfsinfo1/winfsinfo.c | 131 +++++++++++++++++++++++++++++++++++
  17.  4 files changed, 175 insertions(+), 7 deletions(-)
  18.  create mode 100644 tests/winfsinfo1/Makefile
  19.  create mode 100644 tests/winfsinfo1/winfsinfo.c
  20.  
  21. diff --git a/cygwin/Makefile b/cygwin/Makefile
  22. index 301ea56..b7a3b1e 100644
  23. --- a/cygwin/Makefile
  24. +++ b/cygwin/Makefile
  25. @@ -31,13 +31,14 @@ build:
  26.         which MSBuild.exe
  27.         MSBuild.exe '$(shell cygpath -w "$(PROJECT_BASEDIR_DIR)/build.vc19/nfs41-client.sln")' -t:Build  -p:Configuration=Debug -p:Platform=x64
  28.         #MSBuild.exe $(PROJECT_BASEDIR_DIR)/build.vc19/nfs41-client.sln -t:Build  -p:Configuration=Debug -p:Platform=x64
  29. -
  30. +       (cd tests/winfsinfo1 && make all)
  31.  
  32.  #
  33.  # clean target
  34.  #
  35.  clean:
  36.         rm -vRf $$(find "$(PROJECT_BASEDIR_DIR)/build.vc19" -name Debug -o -name Release)
  37. +       (cd tests/winfsinfo1 && make clean)
  38.  
  39.  # install in DESTDIR
  40.  installdest: $(VS_BUILD_DIR)/nfsd.exe \
  41. @@ -73,10 +74,13 @@ installdest: $(VS_BUILD_DIR)/nfsd.exe \
  42.         chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/mount_sshnfs
  43.         cp $(CYGWIN_MAKEFILE_DIR)/utils/sshnfs/sshnfs.ksh $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
  44.         chmod a+x $(DESTDIR)/cygdrive/c/cygwin64/sbin/sshnfs
  45. -       (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ ; chmod a+x *.exe *.dll *.sys *.bash)
  46. +       @ printf "# Package tests\n"
  47. +       cp tests/winfsinfo1/winfsinfo.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/winfsinfo.exe
  48.         @ printf "# Package ksh93&co (if available) since Cygwin does not ship with it yet\n"
  49.         [[ -x /usr/bin/ksh93.exe ]] && cp /usr/bin/ksh93.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/ksh93.exe
  50.         [[ -x /usr/bin/shcomp.exe ]] && cp /usr/bin/shcomp.exe $(DESTDIR)/cygdrive/c/cygwin64/usr/bin/shcomp.exe
  51. +       @ printf "# Set file flags\n"
  52. +       (cd $(DESTDIR)/cygdrive/c/cygwin64/sbin/ ; chmod a+x *.exe *.dll *.sys *.bash)
  53.         @printf "\n#\n# TEST sbin dir is %s\n#\n" "$(DESTDIR)/cygdrive/c/cygwin64/sbin/"
  54.         @printf '\n'
  55.         @printf "\n#\n# Now use\n# $$ cd '%s' && bash ./msnfs41client.bash install #\n# to install the kernel driver as Admin\n#\n" \
  56. diff --git a/daemon/nfs41_superblock.c b/daemon/nfs41_superblock.c
  57. index effd02a..b2f77fd 100644
  58. --- a/daemon/nfs41_superblock.c
  59. +++ b/daemon/nfs41_superblock.c
  60. @@ -165,7 +165,11 @@ void nfs41_superblock_fs_attributes(
  61.      IN const nfs41_superblock *superblock,
  62.      OUT PFILE_FS_ATTRIBUTE_INFORMATION FsAttrs)
  63.  {
  64. -    FsAttrs->FileSystemAttributes = FILE_SUPPORTS_REMOTE_STORAGE;
  65. +    FsAttrs->FileSystemAttributes = 0;
  66. +    FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_REMOTE_STORAGE;
  67. +    /* NFSv4 protocol uses Unicode by default */
  68. +    FsAttrs->FileSystemAttributes |= FILE_UNICODE_ON_DISK;
  69. +
  70.      if (superblock->link_support)
  71.          FsAttrs->FileSystemAttributes |= FILE_SUPPORTS_HARD_LINKS;
  72.      if (superblock->symlink_support)
  73. @@ -179,15 +183,29 @@ void nfs41_superblock_fs_attributes(
  74.      if (superblock->aclsupport)
  75.          FsAttrs->FileSystemAttributes |= FILE_PERSISTENT_ACLS;
  76.  
  77. +    /* gisburn: Fixme: We should someone query this (NFSv4.2 ?) */
  78.      FsAttrs->MaximumComponentNameLength = NFS41_MAX_COMPONENT_LEN;
  79.  
  80.      /* let the driver fill in FileSystemName */
  81.      FsAttrs->FileSystemNameLength = 0;
  82.  
  83. -    dprintf(SBLVL, "FileFsAttributeInformation: case_preserving %u, "
  84. -        "case_insensitive %u, max component %u\n",
  85. -        superblock->case_preserving, superblock->case_insensitive,
  86. -        FsAttrs->MaximumComponentNameLength);
  87. +    dprintf(SBLVL, "FileFsAttributeInformation: "
  88. +        "link_support=%u, "
  89. +        "symlink_support=%u, "
  90. +        "ea_support=%u, "
  91. +        "case_preserving=%u, "
  92. +        "case_insensitive=%u, "
  93. +        "aclsupport=%u, "
  94. +        "MaximumComponentNameLength=%u, "
  95. +        "FileSystemAttributes=%lx\n",
  96. +        superblock->link_support,
  97. +        superblock->symlink_support,
  98. +        superblock->ea_support,
  99. +        superblock->case_preserving,
  100. +        superblock->case_insensitive,
  101. +        superblock->aclsupport,
  102. +        (unsigned int)FsAttrs->MaximumComponentNameLength,
  103. +        (unsigned long)FsAttrs->FileSystemAttributes);
  104.  }
  105.  
  106.  
  107. diff --git a/tests/winfsinfo1/Makefile b/tests/winfsinfo1/Makefile
  108. new file mode 100644
  109. index 0000000..8e7d10a
  110. --- /dev/null
  111. +++ b/tests/winfsinfo1/Makefile
  112. @@ -0,0 +1,15 @@
  113. +#
  114. +# Makefile for winfsinfo
  115. +#
  116. +
  117. +# POSIX Makefile
  118. +
  119. +winfsinfo: winfsinfo.c
  120. +       gcc -Wall -g winfsinfo.c -o winfsinfo
  121. +
  122. +all: winfsinfo
  123. +
  124. +clean:
  125. +       rm -fv \
  126. +               winfsinfo.exe
  127. +# EOF.
  128. diff --git a/tests/winfsinfo1/winfsinfo.c b/tests/winfsinfo1/winfsinfo.c
  129. new file mode 100644
  130. index 0000000..361e2d2
  131. --- /dev/null
  132. +++ b/tests/winfsinfo1/winfsinfo.c
  133. @@ -0,0 +1,131 @@
  134. +/*
  135. + * MIT License
  136. + *
  137. + * Copyright (c) 2023 Roland Mainz <roland.mainz@nrubsig.org>
  138. + *
  139. + * Permission is hereby granted, free of charge, to any person obtaining a copy
  140. + * of this software and associated documentation files (the "Software"), to deal
  141. + * in the Software without restriction, including without limitation the rights
  142. + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  143. + * copies of the Software, and to permit persons to whom the Software is
  144. + * furnished to do so, subject to the following conditions:
  145. + *
  146. + * The above copyright notice and this permission notice shall be included in all
  147. + * copies or substantial portions of the Software.
  148. + *
  149. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  150. + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  151. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  152. + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  153. + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  154. + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  155. + * SOFTWARE.
  156. + */
  157. +
  158. +/*
  159. + * winfsinfo1.c - print Windows filesystem info
  160. + *
  161. + * Written by Roland Mainz <roland.mainz@nrubsig.org>
  162. + */
  163. +
  164. +#define UNICODE 1
  165. +#define _UNICODE 1
  166. +
  167. +#include <stdio.h>
  168. +#include <windows.h>
  169. +#include <stdlib.h>
  170. +#include <stdbool.h>
  171. +
  172. +static
  173. +bool print_volume_info(const char *progname, const char *filename)
  174. +{
  175. +    bool ok = false;
  176. +
  177. +    HANDLE fileHandle = CreateFileA(filename,
  178. +        GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  179. +        FILE_FLAG_BACKUP_SEMANTICS, NULL);
  180. +    if (fileHandle == INVALID_HANDLE_VALUE) {
  181. +        (void)fprintf(stderr,
  182. +            "%s: Error opening file '%s'. Last error was %d.\n",
  183. +            progname,
  184. +            filename,
  185. +            GetLastError());
  186. +        return false;
  187. +    }
  188. +
  189. +    (void)printf("filename='%s'\n", filename);
  190. +
  191. +    DWORD volumeFlags = 0;
  192. +    ok = GetVolumeInformationByHandleW(fileHandle, NULL, 0,
  193. +        NULL, NULL, &volumeFlags, NULL, 0);
  194. +
  195. +    if (!ok) {
  196. +        (void)fprintf(stderr, "%s: GetVolumeInformationByHandleW() "
  197. +            "error. GetLastError()==%d.\n",
  198. +            progname,
  199. +            GetLastError());
  200. +        ok = false;
  201. +        goto done;
  202. +    }
  203. +
  204. +#define TESTFSATTR(s) \
  205. +    if (volumeFlags & (s)) { \
  206. +        (void)puts("volumeflag="#s); \
  207. +        volumeFlags &= ~(s); \
  208. +    }
  209. +
  210. +    TESTFSATTR(FILE_SUPPORTS_USN_JOURNAL);
  211. +    TESTFSATTR(FILE_SUPPORTS_OPEN_BY_FILE_ID);
  212. +    TESTFSATTR(FILE_SUPPORTS_EXTENDED_ATTRIBUTES);
  213. +    TESTFSATTR(FILE_SUPPORTS_HARD_LINKS);
  214. +    TESTFSATTR(FILE_SUPPORTS_TRANSACTIONS);
  215. +    TESTFSATTR(FILE_SEQUENTIAL_WRITE_ONCE);
  216. +    TESTFSATTR(FILE_READ_ONLY_VOLUME);
  217. +    TESTFSATTR(FILE_NAMED_STREAMS);
  218. +    TESTFSATTR(FILE_SUPPORTS_ENCRYPTION);
  219. +    TESTFSATTR(FILE_SUPPORTS_OBJECT_IDS);
  220. +    TESTFSATTR(FILE_VOLUME_IS_COMPRESSED);
  221. +    TESTFSATTR(FILE_SUPPORTS_REMOTE_STORAGE);
  222. +    TESTFSATTR(FILE_RETURNS_CLEANUP_RESULT_INFO);
  223. +    TESTFSATTR(FILE_SUPPORTS_POSIX_UNLINK_RENAME);
  224. +    TESTFSATTR(FILE_SUPPORTS_REPARSE_POINTS);
  225. +    TESTFSATTR(FILE_SUPPORTS_SPARSE_FILES);
  226. +    TESTFSATTR(FILE_VOLUME_QUOTAS);
  227. +    TESTFSATTR(FILE_FILE_COMPRESSION);
  228. +    TESTFSATTR(FILE_PERSISTENT_ACLS);
  229. +    TESTFSATTR(FILE_UNICODE_ON_DISK);
  230. +    TESTFSATTR(FILE_CASE_PRESERVED_NAMES);
  231. +    TESTFSATTR(FILE_CASE_SENSITIVE_SEARCH);
  232. +    TESTFSATTR(FILE_SUPPORTS_INTEGRITY_STREAMS);
  233. +#ifdef FILE_SUPPORTS_BLOCK_REFCOUNTING
  234. +    TESTFSATTR(FILE_SUPPORTS_BLOCK_REFCOUNTING);
  235. +#endif
  236. +#ifdef FILE_SUPPORTS_SPARSE_VDL
  237. +    TESTFSATTR(FILE_SUPPORTS_SPARSE_VDL);
  238. +#endif
  239. +#ifdef FILE_DAX_VOLUME
  240. +    TESTFSATTR(FILE_DAX_VOLUME);
  241. +#endif
  242. +#ifdef FILE_SUPPORTS_GHOSTING
  243. +    TESTFSATTR(FILE_SUPPORTS_GHOSTING);
  244. +#endif
  245. +
  246. +    /*
  247. +     * print any leftover flags not covered by |TESTFSATTR(FILE_*)|
  248. +     * above
  249. +     */
  250. +    if (volumeFlags) {
  251. +        (void)printf("attr=0x%lx\n", (long)volumeFlags);
  252. +    }
  253. +    ok = true;
  254. +
  255. +done:
  256. +    CloseHandle(fileHandle);
  257. +    return ok;
  258. +}
  259. +
  260. +int main(int ac, char *av[])
  261. +{
  262. +    print_volume_info(av[0], av[1]);
  263. +    return EXIT_SUCCESS;
  264. +}
  265. --
  266. 2.42.1
  267.  
  268. From 358221a9713dd2ae0c58b289e2027593be0af5b1 Mon Sep 17 00:00:00 2001
  269. From: Roland Mainz <roland.mainz@nrubsig.org>
  270. Date: Tue, 5 Dec 2023 14:36:58 +0100
  271. Subject: [PATCH 2/4] daemon: Do not spend CPU time with filling buffers with
  272.  debug markers
  273.  
  274. daemon: Set |_CrtSetDebugFillThreshold(0)| so debug builds do
  275. not spend lots of CPU time time filling buffer copies etc with
  276. debug markers (i.e. 0xFE).
  277. We have DrMemory to find such bugs.
  278.  
  279. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  280. ---
  281.  daemon/nfs41_daemon.c | 7 +++++++
  282.  1 file changed, 7 insertions(+)
  283.  
  284. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  285. index cdbad18..fe0683e 100644
  286. --- a/daemon/nfs41_daemon.c
  287. +++ b/daemon/nfs41_daemon.c
  288. @@ -417,6 +417,13 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  289.      /* available only when built in debug mode under visual studio -cbodley */
  290.      _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
  291.      _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
  292. +
  293. +    /*
  294. +     * Do not fill memory with 0xFE for functions like |strcpy_s()|
  295. +     * etc, as it causes bad performance. We have drmemory to find
  296. +     * issues like that instead
  297. +     */
  298. +    (void)_CrtSetDebugFillThreshold(0);
  299.  #pragma warning (push)
  300.  #pragma warning (disable : 4306) /* conversion from 'int' to '_HFILE' of greater size */
  301.      _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  302. --
  303. 2.42.1
  304.  
  305. From 2d788f4fe089378a0deed2a104c4edaacb1ae6b7 Mon Sep 17 00:00:00 2001
  306. From: Roland Mainz <roland.mainz@nrubsig.org>
  307. Date: Tue, 5 Dec 2023 14:45:17 +0100
  308. Subject: [PATCH 3/4] nfs41_driver,daemon,mount,np: Allow long paths (beyond
  309.  260 characters)
  310.  
  311. Starting in Windows 10, version 1607, MAX_PATH limitations have been
  312. removed from common Win32 file and directory functions
  313. (see https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
  314.  
  315. So avoid using MAX_PATH in our code, and use 4096 (to match Cygwin
  316. $ getconf PATH_MAX /cygdrive/c/Users #) as limit where
  317. static limits are required right now now.
  318.  
  319. Tested with CYGWIN_NT-10.0-19045 3.5.0-0.494.gcb21f8bc56c2.x86_64,
  320. /HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/FileSystem/LongPathsEnabled==1
  321. and paths up to 512 characters.
  322.  
  323. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  324. ---
  325.  cygwin/devel/msnfs41client.bash |  5 +++++
  326.  daemon/nfs41_const.h            | 16 ++++++++++++++--
  327.  dll/nfs41_np.c                  | 25 +++++++++++++------------
  328.  dll/nfs41_np.h                  |  8 ++++----
  329.  dll/options.h                   |  3 ++-
  330.  mount/mount.c                   | 18 +++++++++---------
  331.  mount/options.h                 |  2 +-
  332.  sys/nfs41_driver.c              |  4 ++--
  333.  sys/nfs41_driver.h              | 11 +++++++++++
  334.  tests/manual_testing.txt        | 19 +++++++++++++++++--
  335.  10 files changed, 78 insertions(+), 33 deletions(-)
  336.  
  337. diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
  338. index cafd82e..a9782bb 100644
  339. --- a/cygwin/devel/msnfs41client.bash
  340. +++ b/cygwin/devel/msnfs41client.bash
  341. @@ -83,6 +83,10 @@ function nfsclient_install
  342.         fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1
  343.         fsutil behavior query SymlinkEvaluation
  344.  
  345. +       # enable Win32 long paths
  346. +       # (see https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
  347. +       regtool -i set '/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/FileSystem/LongPathsEnabled' 1
  348. +
  349.         # make sure we can load the kernel driver
  350.         # (does not work with SecureBoot)
  351.         bcdedit /set testsigning on
  352. @@ -93,6 +97,7 @@ function nfsclient_install
  353.  
  354.         # set domain name
  355.         regtool -s set '/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/Domain' 'GLOBAL.LOC'
  356. +       od -t x4 <'/proc/registry/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/FileSystem/LongPathsEnabled'
  357.  
  358.         # disable DFS
  359.         sc query Dfsc
  360. diff --git a/daemon/nfs41_const.h b/daemon/nfs41_const.h
  361. index a3c2dd5..252dfbb 100644
  362. --- a/daemon/nfs41_const.h
  363. +++ b/daemon/nfs41_const.h
  364. @@ -41,9 +41,21 @@
  365.  
  366.  #define UPCALL_BUF_SIZE         2048
  367.  
  368. -/* MaximumComponentNameLength reported for FileFsAttributeInformation */
  369. +/*
  370. + * NFS41_MAX_COMPONENT_LEN - MaximumComponentNameLength
  371. + * reported for FileFsAttributeInformation
  372. + */
  373.  #define NFS41_MAX_COMPONENT_LEN     256
  374. -#define NFS41_MAX_PATH_LEN          1280
  375. +/*
  376. + * NFS41_MAX_PATH_LEN - Maximum path length
  377. + * Notes:
  378. + * - Starting in Windows 10, version 1607, MAX_PATH limitations have
  379. + * been removed from common Win32 file and directory functions
  380. + * (see https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
  381. + * - We limit this to 4096 for now, to match Cygwin
  382. + * $ getconf PATH_MAX /cygdrive/c/Users #
  383. + */
  384. +#define NFS41_MAX_PATH_LEN          4096
  385.  
  386.  #define NFS41_HOSTNAME_LEN          64
  387.  #define NFS41_ADDRS_PER_SERVER      4
  388. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  389. index 8b259bb..6432124 100644
  390. --- a/dll/nfs41_np.c
  391. +++ b/dll/nfs41_np.c
  392. @@ -28,6 +28,8 @@
  393.  #include "nfs41_np.h"
  394.  #include "options.h"
  395.  
  396. +#define DBG 1
  397. +
  398.  #ifdef DBG
  399.  #define DbgP(_x_) NFS41DbgPrint _x_
  400.  #else
  401. @@ -40,15 +42,14 @@
  402.  ULONG _cdecl NFS41DbgPrint( __in LPTSTR Format, ... )
  403.  {  
  404.      ULONG rc = 0;
  405. -    TCHAR szbuffer[256];
  406. +#define szbuffer_SIZE 256
  407. +    TCHAR szbuffer[szbuffer_SIZE];
  408.  
  409.      va_list marker;
  410.      va_start( marker, Format );
  411.      {
  412. -
  413. -        //StringCchVPrintfW( szbuffer, 127, Format, marker );
  414. -        StringCchVPrintfW( szbuffer, 256, Format, marker );
  415. -        szbuffer[255] = (TCHAR)0;
  416. +        StringCchVPrintfW( szbuffer, szbuffer_SIZE, Format, marker );
  417. +        szbuffer[szbuffer_SIZE-1] = (TCHAR)0;
  418.          OutputDebugString( TRACE_TAG );
  419.          OutputDebugString( szbuffer );
  420.      }
  421. @@ -416,7 +417,7 @@ NPAddConnection3(
  422.      DWORD   CopyBytes = 0;
  423.      CONNECTION_INFO Connection;
  424.      LPWSTR  ConnectionName;
  425. -    WCHAR ServerName[MAX_PATH];
  426. +    WCHAR ServerName[NFS41_SYS_MAX_PATH_LEN];
  427.      PWCHAR p;
  428.      DWORD i;
  429.  
  430. @@ -444,9 +445,9 @@ NPAddConnection3(
  431.      LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]);
  432.      LocalName[1] = L':';
  433.      LocalName[2] = L'\0';
  434. -    StringCchCopyW( ConnectionName, MAX_PATH, NFS41_DEVICE_NAME );
  435. -    StringCchCatW( ConnectionName, MAX_PATH, L"\\;" );
  436. -    StringCchCatW( ConnectionName, MAX_PATH, LocalName );
  437. +    StringCchCopyW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, NFS41_DEVICE_NAME );
  438. +    StringCchCatW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, L"\\;" );
  439. +    StringCchCatW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, LocalName );
  440.  
  441.      // remote name, must start with "\\"
  442.      if (lpNetResource->lpRemoteName[0] == L'\0' ||
  443. @@ -472,10 +473,10 @@ NPAddConnection3(
  444.          i++;
  445.      }
  446.      ServerName[i] = L'\0';
  447. -    StringCchCatW( ConnectionName, MAX_PATH, ServerName);
  448. +    StringCchCatW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, ServerName);
  449.      /* insert the "nfs4" in between the server name and the path,
  450.       * just to make sure all calls to our driver come thru this */
  451. -    StringCchCatW( ConnectionName, MAX_PATH, L"\\nfs4" );
  452. +    StringCchCatW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, L"\\nfs4" );
  453.  
  454.  #ifdef CONVERT_2_UNIX_SLASHES
  455.      /* convert all windows slashes to unix slashes */
  456. @@ -500,7 +501,7 @@ NPAddConnection3(
  457.          }
  458.      }
  459.  #endif
  460. -    StringCchCatW( ConnectionName, MAX_PATH, &p[i]);
  461. +    StringCchCatW( ConnectionName, NFS41_SYS_MAX_PATH_LEN, &p[i]);
  462.      DbgP(( L"[aglo] Full Connect Name: %s\n", ConnectionName ));
  463.      DbgP(( L"[aglo] Full Connect Name Length: %d %d\n",
  464.          (wcslen(ConnectionName) + 1) * sizeof(WCHAR),
  465. diff --git a/dll/nfs41_np.h b/dll/nfs41_np.h
  466. index aed9c35..738a61b 100644
  467. --- a/dll/nfs41_np.h
  468. +++ b/dll/nfs41_np.h
  469. @@ -35,10 +35,10 @@ typedef struct __NFS41NP_NETRESOURCE {
  470.      DWORD   dwType;
  471.      DWORD   dwDisplayType;
  472.      DWORD   dwUsage;
  473. -    WCHAR   LocalName[MAX_PATH];
  474. -    WCHAR   RemoteName[MAX_PATH];
  475. -    WCHAR   ConnectionName[MAX_PATH];
  476. -    WCHAR   Options[MAX_PATH];
  477. +    WCHAR   LocalName[NFS41_SYS_MAX_PATH_LEN];
  478. +    WCHAR   RemoteName[NFS41_SYS_MAX_PATH_LEN];
  479. +    WCHAR   ConnectionName[NFS41_SYS_MAX_PATH_LEN];
  480. +    WCHAR   Options[NFS41_SYS_MAX_PATH_LEN];
  481.  } NFS41NP_NETRESOURCE, *PNFS41NP_NETRESOURCE;
  482.  
  483.  typedef struct __NFS41NP_SHARED_MEMORY {
  484. diff --git a/dll/options.h b/dll/options.h
  485. index e6f16ff..f05acc7 100644
  486. --- a/dll/options.h
  487. +++ b/dll/options.h
  488. @@ -22,6 +22,7 @@
  489.  #ifndef __NFS41_NP_OPTIONS_H__
  490.  #define __NFS41_NP_OPTIONS_H__
  491.  
  492. +#include "nfs41_driver.h"
  493.  
  494.  #define MOUNT_OPTION_BUFFER_SECRET ('n4')
  495.  
  496. @@ -59,7 +60,7 @@ typedef struct _CONNECTION_INFO {
  497.  } CONNECTION_INFO, *PCONNECTION_INFO;
  498.  
  499.  #define MAX_CONNECTION_BUFFER_SIZE(EaSize) ( \
  500. -       sizeof(CONNECTION_BUFFER) + MAX_PATH + (EaSize) )
  501. +       sizeof(CONNECTION_BUFFER) + NFS41_SYS_MAX_PATH_LEN + (EaSize) )
  502.  
  503.  
  504.  /* options.c */
  505. diff --git a/mount/mount.c b/mount/mount.c
  506. index da0c712..68fc445 100644
  507. --- a/mount/mount.c
  508. +++ b/mount/mount.c
  509. @@ -264,11 +264,11 @@ static DWORD ParseRemoteName(
  510.      LPTSTR pEnd;
  511.      int port = 0;
  512.      PFILE_FULL_EA_INFORMATION port_option_val;
  513. -    wchar_t remotename[MAX_PATH];
  514. +    wchar_t remotename[NFS41_SYS_MAX_PATH_LEN];
  515.      wchar_t *premotename = remotename;
  516. -    wchar_t srvname[MAX_PATH+1+32]; /* sizeof(hostname+'@'+integer) */
  517. +    wchar_t srvname[NFS41_SYS_MAX_PATH_LEN+1+32]; /* sizeof(hostname+'@'+integer) */
  518.  
  519. -    result = StringCchCopy(premotename, MAX_PATH, pRemoteName);
  520. +    result = StringCchCopy(premotename, NFS41_SYS_MAX_PATH_LEN, pRemoteName);
  521.  
  522.      /*
  523.       * gisburn: Fixme: Implement nfs://-URLS per RFC 2224 ("NFS URL
  524. @@ -442,13 +442,13 @@ static DWORD DoMount(
  525.      IN PMOUNT_OPTION_LIST pOptions)
  526.  {
  527.      DWORD result = NO_ERROR;
  528. -    TCHAR szExisting[MAX_PATH];
  529. -    TCHAR szParsedRemoteName[MAX_PATH];
  530. -    TCHAR szRemoteName[MAX_PATH];
  531. +    TCHAR szExisting[NFS41_SYS_MAX_PATH_LEN];
  532. +    TCHAR szParsedRemoteName[NFS41_SYS_MAX_PATH_LEN];
  533. +    TCHAR szRemoteName[NFS41_SYS_MAX_PATH_LEN];
  534.      DWORD dwLength;
  535.  
  536.      *szRemoteName = TEXT('\0');
  537. -    result = ParseRemoteName(pRemoteName, pOptions, szParsedRemoteName, szRemoteName, MAX_PATH);
  538. +    result = ParseRemoteName(pRemoteName, pOptions, szParsedRemoteName, szRemoteName, NFS41_SYS_MAX_PATH_LEN);
  539.      if (result)
  540.          goto out;
  541.  
  542. @@ -464,8 +464,8 @@ static DWORD DoMount(
  543.      else
  544.      {
  545.          NETRESOURCE NetResource;
  546. -        TCHAR szConnection[MAX_PATH];
  547. -        DWORD ConnectSize = MAX_PATH, ConnectResult, Flags = 0;
  548. +        TCHAR szConnection[NFS41_SYS_MAX_PATH_LEN];
  549. +        DWORD ConnectSize = NFS41_SYS_MAX_PATH_LEN, ConnectResult, Flags = 0;
  550.  
  551.          ZeroMemory(&NetResource, sizeof(NETRESOURCE));
  552.          NetResource.dwType = RESOURCETYPE_DISK;
  553. diff --git a/mount/options.h b/mount/options.h
  554. index e23e986..0acfb61 100644
  555. --- a/mount/options.h
  556. +++ b/mount/options.h
  557. @@ -61,7 +61,7 @@ typedef struct _MOUNT_OPTION_LIST {
  558.  /* allocate space for 8 full attributes, but limit options by
  559.   * space rather than count. */
  560.  #define MAX_OPTION_EA_SIZE ( 8 * \
  561. -    (sizeof(FILE_FULL_EA_INFORMATION) + MAX_PATH) )
  562. +    (sizeof(FILE_FULL_EA_INFORMATION) + NFS41_SYS_MAX_PATH_LEN) )
  563.  
  564.  #define MAX_OPTION_BUFFER_SIZE ( sizeof(MOUNT_OPTION_BUFFER) + \
  565.      MAX_OPTION_EA_SIZE - 1 )
  566. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  567. index dcec443..26bfffa 100644
  568. --- a/sys/nfs41_driver.c
  569. +++ b/sys/nfs41_driver.c
  570. @@ -287,7 +287,7 @@ typedef struct _NFS41_MOUNT_CONFIG {
  571.      BOOLEAN nocache;
  572.      WCHAR srv_buffer[SERVER_NAME_BUFFER_SIZE];
  573.      UNICODE_STRING SrvName; /* hostname, or hostname@port */
  574. -    WCHAR mntpt_buffer[MAX_PATH];
  575. +    WCHAR mntpt_buffer[NFS41_SYS_MAX_PATH_LEN];
  576.      UNICODE_STRING MntPt;
  577.      WCHAR sec_flavor[MAX_SEC_FLAVOR_LEN];
  578.      UNICODE_STRING SecFlavor;
  579. @@ -2688,7 +2688,7 @@ void nfs41_MountConfig_InitDefaults(
  580.      Config->SrvName.MaximumLength = SERVER_NAME_BUFFER_SIZE;
  581.      Config->SrvName.Buffer = Config->srv_buffer;
  582.      Config->MntPt.Length = 0;
  583. -    Config->MntPt.MaximumLength = MAX_PATH;
  584. +    Config->MntPt.MaximumLength = NFS41_SYS_MAX_PATH_LEN;
  585.      Config->MntPt.Buffer = Config->mntpt_buffer;
  586.      Config->SecFlavor.Length = 0;
  587.      Config->SecFlavor.MaximumLength = MAX_SEC_FLAVOR_LEN;
  588. diff --git a/sys/nfs41_driver.h b/sys/nfs41_driver.h
  589. index f11eda8..be4faf6 100644
  590. --- a/sys/nfs41_driver.h
  591. +++ b/sys/nfs41_driver.h
  592. @@ -49,6 +49,17 @@
  593.  #define IOCTL_NFS41_WRITE       _RDR_CTL_CODE(7, METHOD_BUFFERED)
  594.  #define IOCTL_NFS41_INVALCACHE  _RDR_CTL_CODE(8, METHOD_BUFFERED)
  595.  
  596. +/*
  597. + * NFS41_SYS_MAX_PATH_LEN - Maximum path length
  598. + * Notes:
  599. + * - Starting in Windows 10, version 1607, MAX_PATH limitations have
  600. + * been removed from common Win32 file and directory functions
  601. + * (see https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation)
  602. + * - We limit this to 4096 for now, to match Cygwin
  603. + * $ getconf PATH_MAX /cygdrive/c/Users #
  604. + */
  605. +#define NFS41_SYS_MAX_PATH_LEN          4096
  606. +
  607.  typedef enum _nfs41_opcodes {
  608.      NFS41_MOUNT,
  609.      NFS41_UNMOUNT,
  610. diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
  611. index 3058c0b..e6a8173 100644
  612. --- a/tests/manual_testing.txt
  613. +++ b/tests/manual_testing.txt
  614. @@ -36,6 +36,11 @@ time ksh93 -c 'export SHELL=/bin/bash HOSTTYPE="cygwin.i386-64"; /bin/bash ./bin
  615.  #
  616.  # bash
  617.  #
  618. +mkdir longpath__________________________________________________________________________________________________________________________________________________________________________________________________________________________1
  619. +cd longpath__________________________________________________________________________________________________________________________________________________________________________________________________________________________1
  620. +mkdir longpath__________________________________________________________________________________________________________________________________________________________________________________________________________________________2
  621. +cd longpath__________________________________________________________________________________________________________________________________________________________________________________________________________________________2
  622. +echo ${#PWD} # (478 is know to work)
  623.  git clone https://git.savannah.gnu.org/git/bash.git
  624.  cd bash/
  625.  ./configure --with-curses
  626. @@ -60,8 +65,18 @@ MSBuild.exe build.vc19/nfs41-client.sln -t:Build  -p:Configuration=Release -p:Pl
  627.  #
  628.  # gcc
  629.  #
  630. -
  631. -
  632. +# * Notes:
  633. +# - The build requires that there are at least 131 characters left in
  634. +#   the path, e.g. $ echo $((260-${#PWD} > 131)) # should be "1",
  635. +#   otherwise the buildcan "randomly" fail with internal gcc errors.
  636. +#   Note that PWD might be the UNC path.
  637. +#   ---- snip ----
  638. +#   $ cd gcc
  639. +#   $ ksh93 -c 'integer pnl pnl_max ; find . | while read pn ; do pnl=${#pn} ; (( pnl_max=fmax(pnl, pnl_max) )) ; done ; printf "max_path_length=%d\n" pnl_max'
  640. +#   max_path_length=131
  641. +#   ---- snip ----
  642. +# - Full build can easily take ~~16 hours minutes
  643. +#
  644.  git clone -b 'releases/gcc-13.2.0' git://gcc.gnu.org/git/gcc.git
  645.  cd gcc/
  646.  # Cygwin: workaround for configure using cp -p where ln -s should be used
  647. --
  648. 2.42.1
  649.  
  650. From 8370dd0851c64eb13b4edc25c66d70d54fc92061 Mon Sep 17 00:00:00 2001
  651. From: Roland Mainz <roland.mainz@nrubsig.org>
  652. Date: Tue, 5 Dec 2023 15:00:53 +0100
  653. Subject: [PATCH 4/4] daemon: Demote "trying to open file/dir as dir/file"
  654.  errors to debug msg
  655.  
  656. daemon: Demote "trying to open directory '%s' as a file" and
  657. "trying to open file '%s' as a directory" errors to debug messages.
  658.  
  659. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  660. ---
  661.  daemon/open.c | 4 ++--
  662.  1 file changed, 2 insertions(+), 2 deletions(-)
  663.  
  664. diff --git a/daemon/open.c b/daemon/open.c
  665. index 4b2a335..8c01ac1 100644
  666. --- a/daemon/open.c
  667. +++ b/daemon/open.c
  668. @@ -556,7 +556,7 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  669.          if (info.type == NF4DIR) {
  670.              dprintf(2, "handle_nfs41_open: DIRECTORY\n");
  671.              if (args->create_opts & FILE_NON_DIRECTORY_FILE) {
  672. -                eprintf("trying to open directory %s as a file\n",
  673. +                dprintf(1, "trying to open directory '%s' as a file\n",
  674.                      state->path.path);
  675.                  status = ERROR_DIRECTORY;
  676.                  goto out_free_state;
  677. @@ -564,7 +564,7 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  678.          } else if (info.type == NF4REG) {
  679.              dprintf(2, "handle nfs41_open: FILE\n");
  680.              if (args->create_opts & FILE_DIRECTORY_FILE) {
  681. -                eprintf("trying to open file %s as a directory\n",
  682. +                dprintf(1, "trying to open file '%s' as a directory\n",
  683.                      state->path.path);
  684.                  status = ERROR_BAD_FILE_TYPE;
  685.                  goto out_free_state;
  686. --
  687. 2.42.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