pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Add WSL support+misc, 2024-10-30
Posted by Anonymous on Wed 30th Oct 2024 15:06
raw | new post

  1. From e18952b1ac72ad15e9433791102729bbe933f787 Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Wed, 30 Oct 2024 11:24:59 +0100
  4. Subject: [PATCH 1/3] build.vc19,daemon: Move |nfs41_file_info| utility
  5.  functions to their own source file
  6.  
  7. Move |nfs41_file_info| utility functions to their own source file
  8.  
  9. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  10. ---
  11. build.vc19/nfsd/nfsd.vcxproj         |   1 +
  12.  build.vc19/nfsd/nfsd.vcxproj.filters |   3 +
  13.  daemon/fileinfoutil.c                | 197 +++++++++++++++++++++++++++
  14.  daemon/util.c                        | 156 ---------------------
  15.  4 files changed, 201 insertions(+), 156 deletions(-)
  16.  create mode 100644 daemon/fileinfoutil.c
  17.  
  18. diff --git a/build.vc19/nfsd/nfsd.vcxproj b/build.vc19/nfsd/nfsd.vcxproj
  19. index dff2257..0c3b2bd 100644
  20. --- a/build.vc19/nfsd/nfsd.vcxproj
  21. +++ b/build.vc19/nfsd/nfsd.vcxproj
  22. @@ -261,6 +261,7 @@
  23.      <ClCompile Include="..\..\daemon\daemon_debug.c" />
  24.      <ClCompile Include="..\..\daemon\delegation.c" />
  25.      <ClCompile Include="..\..\daemon\ea.c" />
  26. +    <ClCompile Include="..\..\daemon\fileinfoutil.c" />
  27.      <ClCompile Include="..\..\daemon\getattr.c" />
  28.      <ClCompile Include="..\..\daemon\idmap.c" />
  29.      <ClCompile Include="..\..\daemon\idmap_cygwin.c" />
  30. diff --git a/build.vc19/nfsd/nfsd.vcxproj.filters b/build.vc19/nfsd/nfsd.vcxproj.filters
  31. index dd45092..46a6b34 100644
  32. --- a/build.vc19/nfsd/nfsd.vcxproj.filters
  33. +++ b/build.vc19/nfsd/nfsd.vcxproj.filters
  34. @@ -36,6 +36,9 @@
  35.      <ClCompile Include="..\..\daemon\ea.c">
  36.        <Filter>Source Files</Filter>
  37.      </ClCompile>
  38. +    <ClCompile Include="..\..\daemon\fileinfoutil.c">
  39. +      <Filter>Source Files</Filter>
  40. +    </ClCompile>
  41.      <ClCompile Include="..\..\daemon\getattr.c">
  42.        <Filter>Source Files</Filter>
  43.      </ClCompile>
  44. diff --git a/daemon/fileinfoutil.c b/daemon/fileinfoutil.c
  45. new file mode 100644
  46. index 0000000..24d547b
  47. --- /dev/null
  48. +++ b/daemon/fileinfoutil.c
  49. @@ -0,0 +1,197 @@
  50. +/* NFSv4.1 client for Windows
  51. + * Copyright (C) 2012 The Regents of the University of Michigan
  52. + * Copyright (C) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  53. + *
  54. + * Olga Kornievskaia <aglo@umich.edu>
  55. + * Casey Bodley <cbodley@umich.edu>
  56. + * Roland Mainz <roland.mainz@nrubsig.org>
  57. + *
  58. + * This library is free software; you can redistribute it and/or modify it
  59. + * under the terms of the GNU Lesser General Public License as published by
  60. + * the Free Software Foundation; either version 2.1 of the License, or (at
  61. + * your option) any later version.
  62. + *
  63. + * This library is distributed in the hope that it will be useful, but
  64. + * without any warranty; without even the implied warranty of merchantability
  65. + * or fitness for a particular purpose.  See the GNU Lesser General Public
  66. + * License for more details.
  67. + *
  68. + * You should have received a copy of the GNU Lesser General Public License
  69. + * along with this library; if not, write to the Free Software Foundation,
  70. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  71. + */
  72. +
  73. +#include <Windows.h>
  74. +#include <strsafe.h>
  75. +#include <stdio.h>
  76. +#include <stdlib.h>
  77. +
  78. +#include "daemon_debug.h"
  79. +#include "util.h"
  80. +#include "nfs41_ops.h"
  81. +
  82. +
  83. +ULONG nfs_file_info_to_attributes(
  84. +    IN const nfs41_file_info *info)
  85. +{
  86. +    ULONG attrs = 0;
  87. +
  88. +    if (info->type == NF4DIR)
  89. +        attrs |= FILE_ATTRIBUTE_DIRECTORY;
  90. +    else if (info->type == NF4LNK) {
  91. +        attrs |= FILE_ATTRIBUTE_REPARSE_POINT;
  92. +        if (info->symlink_dir)
  93. +            attrs |= FILE_ATTRIBUTE_DIRECTORY;
  94. +    }
  95. +    else if (info->type != NF4REG) {
  96. +        DPRINTF(1,
  97. +            ("nfs_file_info_to_attributes: "
  98. +            "unhandled file type %d, defaulting to NF4REG\n",
  99. +            info->type));
  100. +    }
  101. +
  102. +    EASSERT((info->attrmask.count > 0) &&
  103. +        (info->attrmask.arr[1] & FATTR4_WORD1_MODE));
  104. +    if (info->mode == 0444) /* XXX: 0444 for READONLY */
  105. +        attrs |= FILE_ATTRIBUTE_READONLY;
  106. +
  107. +    if (info->hidden)
  108. +        attrs |= FILE_ATTRIBUTE_HIDDEN;
  109. +    if (info->system)
  110. +        attrs |= FILE_ATTRIBUTE_SYSTEM;
  111. +    if (info->archive)
  112. +        attrs |= FILE_ATTRIBUTE_ARCHIVE;
  113. +
  114. +    /*
  115. +     * |FILE_ATTRIBUTE_NORMAL| attribute is only set if no other
  116. +     * attributes are present.
  117. +     * all other override this value.
  118. +     */
  119. +    return attrs ? attrs : FILE_ATTRIBUTE_NORMAL;
  120. +}
  121. +
  122. +void nfs_to_basic_info(
  123. +    IN const char *name,
  124. +    IN const nfs41_file_info *info,
  125. +    OUT PFILE_BASIC_INFO basic_out)
  126. +{
  127. +    EASSERT(info->attrmask.count > 0);
  128. +
  129. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  130. +        nfs_time_to_file_time(&info->time_create, &basic_out->CreationTime);
  131. +    }
  132. +    else {
  133. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  134. +            "time_create not set\n", name));
  135. +        basic_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  136. +    }
  137. +
  138. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  139. +        nfs_time_to_file_time(&info->time_access, &basic_out->LastAccessTime);
  140. +    }
  141. +    else {
  142. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  143. +            "time_access not set\n", name));
  144. +        basic_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  145. +    }
  146. +
  147. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  148. +        nfs_time_to_file_time(&info->time_modify, &basic_out->LastWriteTime);
  149. +    }
  150. +    else {
  151. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  152. +            "time_modify not set\n", name));
  153. +        basic_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  154. +    }
  155. +
  156. +    /* XXX: was using 'change' attr, but that wasn't giving a time */
  157. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  158. +        nfs_time_to_file_time(&info->time_modify, &basic_out->ChangeTime);
  159. +    }
  160. +    else {
  161. +        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  162. +            "time_modify2 not set\n", name));
  163. +        basic_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  164. +    }
  165. +
  166. +    basic_out->FileAttributes = nfs_file_info_to_attributes(info);
  167. +}
  168. +
  169. +void nfs_to_standard_info(
  170. +    IN const nfs41_file_info *info,
  171. +    OUT PFILE_STANDARD_INFO std_out)
  172. +{
  173. +    const ULONG FileAttributes = nfs_file_info_to_attributes(info);
  174. +
  175. +    EASSERT(info->attrmask.arr[0] & FATTR4_WORD0_SIZE);
  176. +    EASSERT((info->attrmask.count > 0) &&
  177. +        (info->attrmask.arr[1] & FATTR4_WORD1_NUMLINKS));
  178. +
  179. +    std_out->AllocationSize.QuadPart =
  180. +        std_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  181. +    std_out->NumberOfLinks = info->numlinks;
  182. +    std_out->DeletePending = FALSE;
  183. +    std_out->Directory = FileAttributes & FILE_ATTRIBUTE_DIRECTORY ?
  184. +        TRUE : FALSE;
  185. +}
  186. +
  187. +void nfs_to_network_openinfo(
  188. +    IN const char *name,
  189. +    IN const nfs41_file_info *info,
  190. +    OUT PFILE_NETWORK_OPEN_INFORMATION net_out)
  191. +{
  192. +    EASSERT(info->attrmask.count > 0);
  193. +
  194. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  195. +        nfs_time_to_file_time(&info->time_create, &net_out->CreationTime);
  196. +    }
  197. +    else {
  198. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  199. +            "time_create not set\n", name));
  200. +        net_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  201. +    }
  202. +
  203. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  204. +        nfs_time_to_file_time(&info->time_access, &net_out->LastAccessTime);
  205. +    }
  206. +    else {
  207. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  208. +            "time_access not set\n", name));
  209. +        net_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  210. +    }
  211. +
  212. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  213. +        nfs_time_to_file_time(&info->time_modify, &net_out->LastWriteTime);
  214. +    }
  215. +    else {
  216. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  217. +            "time_modify not set\n", name));
  218. +        net_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  219. +    }
  220. +
  221. +    /* XXX: was using 'change' attr, but that wasn't giving a time */
  222. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  223. +        nfs_time_to_file_time(&info->time_modify, &net_out->ChangeTime);
  224. +    }
  225. +    else {
  226. +        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  227. +            "time_modify2 not set\n", name));
  228. +        net_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  229. +    }
  230. +
  231. +    net_out->AllocationSize.QuadPart =
  232. +        net_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  233. +    net_out->FileAttributes = nfs_file_info_to_attributes(info);
  234. +}
  235. +
  236. +/* copy |nfs41_file_info| */
  237. +void nfs41_file_info_cpy(
  238. +    OUT nfs41_file_info *dest,
  239. +    IN const nfs41_file_info *src)
  240. +{
  241. +    (void)memcpy(dest, src, sizeof(nfs41_file_info));
  242. +    if (src->owner != NULL)
  243. +        dest->owner = dest->owner_buf;
  244. +    if (src->owner_group != NULL)
  245. +        dest->owner_group = dest->owner_group_buf;
  246. +}
  247. diff --git a/daemon/util.c b/daemon/util.c
  248. index 399fb95..ef41a30 100644
  249. --- a/daemon/util.c
  250. +++ b/daemon/util.c
  251. @@ -142,162 +142,6 @@ bool_t verify_commit(
  252.      return 0;
  253.  }
  254.  
  255. -ULONG nfs_file_info_to_attributes(
  256. -    IN const nfs41_file_info *info)
  257. -{
  258. -    ULONG attrs = 0;
  259. -    if (info->type == NF4DIR)
  260. -        attrs |= FILE_ATTRIBUTE_DIRECTORY;
  261. -    else if (info->type == NF4LNK) {
  262. -        attrs |= FILE_ATTRIBUTE_REPARSE_POINT;
  263. -        if (info->symlink_dir)
  264. -            attrs |= FILE_ATTRIBUTE_DIRECTORY;
  265. -    }
  266. -    else if (info->type != NF4REG) {
  267. -        DPRINTF(1, ("unhandled file type %d, defaulting to NF4REG\n",
  268. -            info->type));
  269. -    }
  270. -
  271. -    EASSERT((info->attrmask.count > 0) &&
  272. -        (info->attrmask.arr[1] & FATTR4_WORD1_MODE));
  273. -    if (info->mode == 0444) /* XXX: 0444 for READONLY */
  274. -        attrs |= FILE_ATTRIBUTE_READONLY;
  275. -
  276. -    if (info->hidden) attrs |= FILE_ATTRIBUTE_HIDDEN;
  277. -    if (info->system) attrs |= FILE_ATTRIBUTE_SYSTEM;
  278. -    if (info->archive) attrs |= FILE_ATTRIBUTE_ARCHIVE;
  279. -
  280. -    // FILE_ATTRIBUTE_NORMAL attribute is only set if no other attributes are present.
  281. -    // all other override this value.
  282. -    return attrs ? attrs : FILE_ATTRIBUTE_NORMAL;
  283. -}
  284. -
  285. -void nfs_to_basic_info(
  286. -    IN const char *name,
  287. -    IN const nfs41_file_info *info,
  288. -    OUT PFILE_BASIC_INFO basic_out)
  289. -{
  290. -    EASSERT(info->attrmask.count > 0);
  291. -
  292. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  293. -        nfs_time_to_file_time(&info->time_create, &basic_out->CreationTime);
  294. -    }
  295. -    else {
  296. -        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  297. -            "time_create not set\n", name));
  298. -        basic_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  299. -    }
  300. -
  301. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  302. -        nfs_time_to_file_time(&info->time_access, &basic_out->LastAccessTime);
  303. -    }
  304. -    else {
  305. -        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  306. -            "time_access not set\n", name));
  307. -        basic_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  308. -    }
  309. -
  310. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  311. -        nfs_time_to_file_time(&info->time_modify, &basic_out->LastWriteTime);
  312. -    }
  313. -    else {
  314. -        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  315. -            "time_modify not set\n", name));
  316. -        basic_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  317. -    }
  318. -
  319. -    /* XXX: was using 'change' attr, but that wasn't giving a time */
  320. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  321. -        nfs_time_to_file_time(&info->time_modify, &basic_out->ChangeTime);
  322. -    }
  323. -    else {
  324. -        DPRINTF(1, ("nfs_to_basic_info(name='%s'): "
  325. -            "time_modify2 not set\n", name));
  326. -        basic_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  327. -    }
  328. -
  329. -    basic_out->FileAttributes = nfs_file_info_to_attributes(info);
  330. -}
  331. -
  332. -void nfs_to_standard_info(
  333. -    IN const nfs41_file_info *info,
  334. -    OUT PFILE_STANDARD_INFO std_out)
  335. -{
  336. -    const ULONG FileAttributes = nfs_file_info_to_attributes(info);
  337. -
  338. -    EASSERT(info->attrmask.arr[0] & FATTR4_WORD0_SIZE);
  339. -    EASSERT((info->attrmask.count > 0) &&
  340. -        (info->attrmask.arr[1] & FATTR4_WORD1_NUMLINKS));
  341. -
  342. -    std_out->AllocationSize.QuadPart =
  343. -        std_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  344. -    std_out->NumberOfLinks = info->numlinks;
  345. -    std_out->DeletePending = FALSE;
  346. -    std_out->Directory = FileAttributes & FILE_ATTRIBUTE_DIRECTORY ?
  347. -        TRUE : FALSE;
  348. -}
  349. -
  350. -void nfs_to_network_openinfo(
  351. -    IN const char *name,
  352. -    IN const nfs41_file_info *info,
  353. -    OUT PFILE_NETWORK_OPEN_INFORMATION net_out)
  354. -{
  355. -    EASSERT(info->attrmask.count > 0);
  356. -
  357. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  358. -        nfs_time_to_file_time(&info->time_create, &net_out->CreationTime);
  359. -    }
  360. -    else {
  361. -        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  362. -            "time_create not set\n", name));
  363. -        net_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  364. -    }
  365. -
  366. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  367. -        nfs_time_to_file_time(&info->time_access, &net_out->LastAccessTime);
  368. -    }
  369. -    else {
  370. -        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  371. -            "time_access not set\n", name));
  372. -        net_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  373. -    }
  374. -
  375. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  376. -        nfs_time_to_file_time(&info->time_modify, &net_out->LastWriteTime);
  377. -    }
  378. -    else {
  379. -        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  380. -            "time_modify not set\n", name));
  381. -        net_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  382. -    }
  383. -
  384. -    /* XXX: was using 'change' attr, but that wasn't giving a time */
  385. -    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  386. -        nfs_time_to_file_time(&info->time_modify, &net_out->ChangeTime);
  387. -    }
  388. -    else {
  389. -        DPRINTF(1, ("nfs_to_network_openinfo(name='%s'): "
  390. -            "time_modify2 not set\n", name));
  391. -        net_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  392. -    }
  393. -
  394. -    net_out->AllocationSize.QuadPart =
  395. -        net_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  396. -    net_out->FileAttributes = nfs_file_info_to_attributes(info);
  397. -}
  398. -
  399. -/* copy |nfs41_file_info| */
  400. -void nfs41_file_info_cpy(
  401. -    OUT nfs41_file_info *dest,
  402. -    IN const nfs41_file_info *src)
  403. -{
  404. -    (void)memcpy(dest, src, sizeof(nfs41_file_info));
  405. -    if (src->owner != NULL)
  406. -        dest->owner = dest->owner_buf;
  407. -    if (src->owner_group != NULL)
  408. -        dest->owner_group = dest->owner_group_buf;
  409. -}
  410. -
  411.  void get_file_time(
  412.      OUT PLARGE_INTEGER file_time)
  413.  {
  414. --
  415. 2.45.1
  416.  
  417. From 9ca1d4cddd88b71a7a731ade31ead8ce4afcd56b Mon Sep 17 00:00:00 2001
  418. From: Roland Mainz <roland.mainz@nrubsig.org>
  419. Date: Wed, 30 Oct 2024 13:07:06 +0100
  420. Subject: [PATCH 2/3] sys: Add new Win10 file/fs info classes to debug
  421.  functions
  422.  
  423. Update |print_file_information_class()| and |print_fs_information_class()|
  424. to include new Windows 10 SDK file/fs info classes.
  425.  
  426. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  427. ---
  428. sys/nfs41sys_debug.c | 169 ++++++++++++++++++++++++-------------------
  429.  1 file changed, 95 insertions(+), 74 deletions(-)
  430.  
  431. diff --git a/sys/nfs41sys_debug.c b/sys/nfs41sys_debug.c
  432. index d19a1f2..e6b22e6 100644
  433. --- a/sys/nfs41sys_debug.c
  434. +++ b/sys/nfs41sys_debug.c
  435. @@ -528,88 +528,109 @@ void print_nt_create_params(int on, NT_CREATE_PARAMETERS params)
  436.          (params.DesiredAccess & SYNCHRONIZE)?"SYNCHRONIZE":"");
  437.  }
  438.  
  439. -const char *print_file_information_class(int InfoClass)
  440. +const char *print_file_information_class(int fic)
  441.  {
  442. -    switch(InfoClass) {
  443. -        case FileBothDirectoryInformation:
  444. -            return "FileBothDirectoryInformation";
  445. -        case FileDirectoryInformation:
  446. -            return "FileDirectoryInformation";
  447. -        case FileFullDirectoryInformation:
  448. -            return "FileFullDirectoryInformation";
  449. -        case FileIdBothDirectoryInformation:
  450. -            return "FileIdBothDirectoryInformation";
  451. -        case FileIdFullDirectoryInformation:
  452. -            return "FileIdFullDirectoryInformation";
  453. -        case FileNamesInformation:
  454. -            return "FileNamesInformation";
  455. -        case FileObjectIdInformation:
  456. -            return "FileObjectIdInformation";
  457. -        case FileQuotaInformation:
  458. -            return "FileQuotaInformation";
  459. -        case FileReparsePointInformation:
  460. -            return "FileReparsePointInformation";
  461. -        case FileAllInformation:
  462. -            return "FileAllInformation";
  463. -        case FileAttributeTagInformation:
  464. -            return "FileAttributeTagInformation";
  465. -        case FileBasicInformation:
  466. -            return "FileBasicInformation";
  467. -        case FileCompressionInformation:
  468. -            return "FileCompressionInformation";
  469. -        case FileEaInformation:
  470. -            return "FileEaInformation";
  471. -        case FileInternalInformation:
  472. -            return "FileInternalInformation";
  473. -        case FileNameInformation:
  474. -            return "FileNameInformation";
  475. -        case FileNetworkOpenInformation:
  476. -            return "FileNetworkOpenInformation";
  477. -        case FilePositionInformation:
  478. -            return "FilePositionInformation";
  479. -        case FileStandardInformation:
  480. -            return "FileStandardInformation";
  481. -        case FileStreamInformation:
  482. -            return "FileStreamInformation";
  483. -        case FileAllocationInformation:
  484. -            return "FileAllocationInformation";
  485. -        case FileDispositionInformation:
  486. -            return "FileDispositionInformation";
  487. -        case FileEndOfFileInformation:
  488. -            return "FileEndOfFileInformation";
  489. -        case FileLinkInformation:
  490. -            return "FileLinkInformation";
  491. -        case FileRenameInformation:
  492. -            return "FileRenameInformation";
  493. -        case FileValidDataLengthInformation:
  494. -            return "FileValidDataLengthInformation";
  495. -        default:
  496. -            return "UNKNOWN_InfoClass";
  497. +    switch(fic) {
  498. +#define FIC_TO_STRLITERAL(e) case e: return #e;
  499. +        FIC_TO_STRLITERAL(FileDirectoryInformation)
  500. +        FIC_TO_STRLITERAL(FileFullDirectoryInformation)
  501. +        FIC_TO_STRLITERAL(FileBothDirectoryInformation)
  502. +        FIC_TO_STRLITERAL(FileBasicInformation)
  503. +        FIC_TO_STRLITERAL(FileStandardInformation)
  504. +        FIC_TO_STRLITERAL(FileInternalInformation)
  505. +        FIC_TO_STRLITERAL(FileEaInformation)
  506. +        FIC_TO_STRLITERAL(FileAccessInformation)
  507. +        FIC_TO_STRLITERAL(FileNameInformation)
  508. +        FIC_TO_STRLITERAL(FileRenameInformation)
  509. +        FIC_TO_STRLITERAL(FileLinkInformation)
  510. +        FIC_TO_STRLITERAL(FileNamesInformation)
  511. +        FIC_TO_STRLITERAL(FileDispositionInformation)
  512. +        FIC_TO_STRLITERAL(FilePositionInformation)
  513. +        FIC_TO_STRLITERAL(FileFullEaInformation)
  514. +        FIC_TO_STRLITERAL(FileModeInformation)
  515. +        FIC_TO_STRLITERAL(FileAlignmentInformation)
  516. +        FIC_TO_STRLITERAL(FileAllInformation)
  517. +        FIC_TO_STRLITERAL(FileAllocationInformation)
  518. +        FIC_TO_STRLITERAL(FileEndOfFileInformation)
  519. +        FIC_TO_STRLITERAL(FileAlternateNameInformation)
  520. +        FIC_TO_STRLITERAL(FileStreamInformation)
  521. +        FIC_TO_STRLITERAL(FilePipeInformation)
  522. +        FIC_TO_STRLITERAL(FilePipeLocalInformation)
  523. +        FIC_TO_STRLITERAL(FilePipeRemoteInformation)
  524. +        FIC_TO_STRLITERAL(FileMailslotQueryInformation)
  525. +        FIC_TO_STRLITERAL(FileMailslotSetInformation)
  526. +        FIC_TO_STRLITERAL(FileCompressionInformation)
  527. +        FIC_TO_STRLITERAL(FileObjectIdInformation)
  528. +        FIC_TO_STRLITERAL(FileCompletionInformation)
  529. +        FIC_TO_STRLITERAL(FileMoveClusterInformation)
  530. +        FIC_TO_STRLITERAL(FileQuotaInformation)
  531. +        FIC_TO_STRLITERAL(FileReparsePointInformation)
  532. +        FIC_TO_STRLITERAL(FileNetworkOpenInformation)
  533. +        FIC_TO_STRLITERAL(FileAttributeTagInformation)
  534. +        FIC_TO_STRLITERAL(FileTrackingInformation)
  535. +        FIC_TO_STRLITERAL(FileIdBothDirectoryInformation)
  536. +        FIC_TO_STRLITERAL(FileIdFullDirectoryInformation)
  537. +        FIC_TO_STRLITERAL(FileValidDataLengthInformation)
  538. +        FIC_TO_STRLITERAL(FileShortNameInformation)
  539. +        FIC_TO_STRLITERAL(FileIoCompletionNotificationInformation)
  540. +        FIC_TO_STRLITERAL(FileIoStatusBlockRangeInformation)
  541. +        FIC_TO_STRLITERAL(FileIoPriorityHintInformation)
  542. +        FIC_TO_STRLITERAL(FileSfioReserveInformation)
  543. +        FIC_TO_STRLITERAL(FileSfioVolumeInformation)
  544. +        FIC_TO_STRLITERAL(FileHardLinkInformation)
  545. +        FIC_TO_STRLITERAL(FileProcessIdsUsingFileInformation)
  546. +        FIC_TO_STRLITERAL(FileNormalizedNameInformation)
  547. +        FIC_TO_STRLITERAL(FileNetworkPhysicalNameInformation)
  548. +        FIC_TO_STRLITERAL(FileIdGlobalTxDirectoryInformation)
  549. +        FIC_TO_STRLITERAL(FileIsRemoteDeviceInformation)
  550. +        FIC_TO_STRLITERAL(FileUnusedInformation)
  551. +        FIC_TO_STRLITERAL(FileNumaNodeInformation)
  552. +        FIC_TO_STRLITERAL(FileStandardLinkInformation)
  553. +        FIC_TO_STRLITERAL(FileRemoteProtocolInformation)
  554. +        FIC_TO_STRLITERAL(FileRenameInformationBypassAccessCheck)
  555. +        FIC_TO_STRLITERAL(FileLinkInformationBypassAccessCheck)
  556. +        FIC_TO_STRLITERAL(FileVolumeNameInformation)
  557. +        FIC_TO_STRLITERAL(FileIdInformation)
  558. +        FIC_TO_STRLITERAL(FileIdExtdDirectoryInformation)
  559. +        FIC_TO_STRLITERAL(FileReplaceCompletionInformation)
  560. +        FIC_TO_STRLITERAL(FileHardLinkFullIdInformation)
  561. +        FIC_TO_STRLITERAL(FileIdExtdBothDirectoryInformation)
  562. +        FIC_TO_STRLITERAL(FileDispositionInformationEx)
  563. +        FIC_TO_STRLITERAL(FileRenameInformationEx)
  564. +        FIC_TO_STRLITERAL(FileRenameInformationExBypassAccessCheck)
  565. +        FIC_TO_STRLITERAL(FileDesiredStorageClassInformation)
  566. +        FIC_TO_STRLITERAL(FileStatInformation)
  567. +        FIC_TO_STRLITERAL(FileMemoryPartitionInformation)
  568. +        FIC_TO_STRLITERAL(FileStatLxInformation)
  569. +        FIC_TO_STRLITERAL(FileCaseSensitiveInformation)
  570. +        FIC_TO_STRLITERAL(FileLinkInformationEx)
  571. +        FIC_TO_STRLITERAL(FileLinkInformationExBypassAccessCheck)
  572. +        FIC_TO_STRLITERAL(FileStorageReserveIdInformation)
  573. +        FIC_TO_STRLITERAL(FileCaseSensitiveInformationForceAccessCheck)
  574.      }
  575. +    return "<unknown FILE_INFORMATION_CLASS>";
  576.  }
  577.  
  578.  const char *print_fs_information_class(int InfoClass)
  579.  {
  580. +#define FSIC_TO_STRLITERAL(e) case e: return #e;
  581.      switch (InfoClass) {
  582. -        case FileFsAttributeInformation:
  583. -            return "FileFsAttributeInformation";
  584. -        case FileFsControlInformation:
  585. -            return "FileFsControlInformation";
  586. -        case FileFsDeviceInformation:
  587. -            return "FileFsDeviceInformation";
  588. -        case FileFsDriverPathInformation:
  589. -            return "FileFsDriverPathInformation";
  590. -        case FileFsFullSizeInformation:
  591. -            return "FileFsFullSizeInformation";
  592. -        case FileFsObjectIdInformation:
  593. -            return "FileFsObjectIdInformation";
  594. -        case FileFsSizeInformation:
  595. -            return "FileFsSizeInformation";
  596. -        case FileFsVolumeInformation:
  597. -            return "FileFsVolumeInformation";
  598. -        default:
  599. -            return "UNKNOWN_FsInfoClass";
  600. +        FSIC_TO_STRLITERAL(FileFsVolumeInformation)
  601. +        FSIC_TO_STRLITERAL(FileFsLabelInformation)
  602. +        FSIC_TO_STRLITERAL(FileFsSizeInformation)
  603. +        FSIC_TO_STRLITERAL(FileFsDeviceInformation)
  604. +        FSIC_TO_STRLITERAL(FileFsAttributeInformation)
  605. +        FSIC_TO_STRLITERAL(FileFsControlInformation)
  606. +        FSIC_TO_STRLITERAL(FileFsFullSizeInformation)
  607. +        FSIC_TO_STRLITERAL(FileFsObjectIdInformation)
  608. +        FSIC_TO_STRLITERAL(FileFsDriverPathInformation)
  609. +        FSIC_TO_STRLITERAL(FileFsVolumeFlagsInformation)
  610. +        FSIC_TO_STRLITERAL(FileFsSectorSizeInformation)
  611. +        FSIC_TO_STRLITERAL(FileFsDataCopyInformation)
  612. +        FSIC_TO_STRLITERAL(FileFsMetadataSizeInformation)
  613. +        FSIC_TO_STRLITERAL(FileFsFullSizeInformationEx)
  614.      }
  615. +    return "<unknown FS_INFORMATION_CLASS>";
  616.  }
  617.  
  618.  void print_caching_level(int on, ULONG flag, PUNICODE_STRING name)
  619. --
  620. 2.45.1
  621.  
  622. From a999a662190dbb7fe14979c7b93ed5a036619758 Mon Sep 17 00:00:00 2001
  623. From: Roland Mainz <roland.mainz@nrubsig.org>
  624. Date: Wed, 30 Oct 2024 15:20:23 +0100
  625. Subject: [PATCH 3/3] cygwin,daemon,include,nfs41_build_features.h,sys: WSL:
  626.  Add |FileStatInformation|+|FileStatLxInformation|
  627.  
  628. Add WSL support by implementing the |FileStatInformation|
  629. and |FileStatLxInformation| queryinfo classes.
  630.  
  631. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  632. ---
  633. cygwin/README.bintarball.txt |  40 ++++
  634.  daemon/fileinfoutil.c        | 258 ++++++++++++++++++++
  635.  daemon/getattr.c             |  25 ++
  636.  daemon/nfs41_const.h         |  14 ++
  637.  daemon/upcall.h              |   6 +-
  638.  daemon/util.h                |  12 +
  639.  include/from_kernel.h        | 442 ++++++++++++++++++++---------------
  640.  nfs41_build_features.h       |   5 +
  641.  sys/nfs41sys_fileinfo.c      |   8 +
  642.  9 files changed, 617 insertions(+), 193 deletions(-)
  643.  
  644. diff --git a/cygwin/README.bintarball.txt b/cygwin/README.bintarball.txt
  645. index 2613d29..1d24dec 100644
  646. --- a/cygwin/README.bintarball.txt
  647. +++ b/cygwin/README.bintarball.txt
  648. @@ -49,6 +49,11 @@ NFSv4.1 filesystem driver for Windows 10/11&Windows Server 2019
  649.      - Cygwin bash+ksh93 support UNC paths, e.g.
  650.        cd //derfwnb4966@2049/nfs4/bigdisk/mysqldb4/
  651.  
  652. +- WSL support
  653. +    - Mount Windows NFSv4.1 shares via driver letter or UNC path
  654. +      in WSL via mount -t drvfs
  655. +    - Supports NFS owner/group to WSL uid/gid mapping
  656. +
  657.  - IPv6 support
  658.      - IPv6 address within '[', ']'
  659.        (will be converted to *.ipv6-literal.net)
  660. @@ -311,6 +316,41 @@ BUG: Note that "ms-nfs41-client-globalmountall-service" currently
  661.  does not wait until nfsd*.exe is available for accepting mounts.
  662.  
  663.  
  664. +# WSL usage:
  665. +Example 1: Mount Windows NFSv4.1 share via Windows driver letter
  666. +# Mount NFSv4.1 share in Windows to driver letter 'N':
  667. +---- snip ----
  668. +$ /sbin/nfs_mount -o rw 'N' nfs://10.49.202.230//bigdisk
  669. +Successfully mounted '10.49.202.230@2049' to drive 'N:'
  670. +---- snip ----
  671. +
  672. +# Within WSL mount driver letter 'N' to /mnt/n
  673. +---- snip ----
  674. +$ sudo bash
  675. +$ mkdir /mnt/n
  676. +$ mount -t drvfs N: /mnt/n
  677. +---- snip ----
  678. +
  679. +Example 2: Mount Windows NFSv4.1 share via UNC path:
  680. +# Mount NFSv4.1 share in Windows
  681. +---- snip ----
  682. +$ /sbin/nfs_mount -o rw nfs://10.49.202.230//bigdisk
  683. +Successfully mounted '10.49.202.230@2049' to drive '\0.49.202.230@2049\nfs4\bigdisk'
  684. +---- snip ----
  685. +
  686. +# Within WSL mount UNC path returned by /sbin/nfs_mount
  687. +---- snip ----
  688. +$ sudo bash
  689. +$ mkdir /mnt/bigdisk
  690. +$ mount -t drvfs '\0.49.202.230@2049\nfs4\bigdisk' /mnt/bigdisk
  691. +---- snip ----
  692. +
  693. +* Known issues with WSL:
  694. +- Softlinks do not work yet
  695. +- Creating a hard link returns "Invalid Argument", maybe drvfs
  696. +  limitation
  697. +- Not all POSIX file types (e.g. block devices) etc. are supported
  698. +
  699.  #
  700.  # 9. Notes:
  701.  #
  702. diff --git a/daemon/fileinfoutil.c b/daemon/fileinfoutil.c
  703. index 24d547b..29f9b4d 100644
  704. --- a/daemon/fileinfoutil.c
  705. +++ b/daemon/fileinfoutil.c
  706. @@ -26,7 +26,9 @@
  707.  #include <stdio.h>
  708.  #include <stdlib.h>
  709.  
  710. +#include "nfs41_build_features.h"
  711.  #include "daemon_debug.h"
  712. +#include "nfs41_daemon.h"
  713.  #include "util.h"
  714.  #include "nfs41_ops.h"
  715.  
  716. @@ -184,6 +186,262 @@ void nfs_to_network_openinfo(
  717.      net_out->FileAttributes = nfs_file_info_to_attributes(info);
  718.  }
  719.  
  720. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  721. +void nfs_to_stat_info(
  722. +    IN const char *name,
  723. +    IN const nfs41_file_info *info,
  724. +    OUT PFILE_STAT_INFORMATION stat_out)
  725. +{
  726. +    EASSERT(info->attrmask.count > 0);
  727. +
  728. +    stat_out->FileId.QuadPart = info->fileid;
  729. +
  730. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  731. +        nfs_time_to_file_time(&info->time_create, &stat_out->CreationTime);
  732. +    }
  733. +    else {
  734. +        DPRINTF(1, ("nfs_to_stat_info(name='%s'): "
  735. +            "time_create not set\n", name));
  736. +        stat_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  737. +    }
  738. +
  739. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  740. +        nfs_time_to_file_time(&info->time_access, &stat_out->LastAccessTime);
  741. +    }
  742. +    else {
  743. +        DPRINTF(1, ("nfs_to_stat_info(name='%s'): "
  744. +            "time_access not set\n", name));
  745. +        stat_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  746. +    }
  747. +
  748. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  749. +        nfs_time_to_file_time(&info->time_modify, &stat_out->LastWriteTime);
  750. +    }
  751. +    else {
  752. +        DPRINTF(1, ("nfs_to_stat_info(name='%s'): "
  753. +            "time_modify not set\n", name));
  754. +        stat_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  755. +    }
  756. +
  757. +    /* XXX: was using 'change' attr, but that wasn't giving a time */
  758. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  759. +        nfs_time_to_file_time(&info->time_modify, &stat_out->ChangeTime);
  760. +    }
  761. +    else {
  762. +        DPRINTF(1, ("nfs_to_stat_info(name='%s'): "
  763. +            "time_modify2 not set\n", name));
  764. +        stat_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  765. +    }
  766. +
  767. +    stat_out->AllocationSize.QuadPart =
  768. +        stat_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  769. +
  770. +    stat_out->FileAttributes = nfs_file_info_to_attributes(info);
  771. +
  772. +    stat_out->ReparseTag = (info->type == NF4LNK)?
  773. +        IO_REPARSE_TAG_SYMLINK : 0;
  774. +
  775. +    stat_out->NumberOfLinks = info->numlinks;
  776. +    stat_out->EffectiveAccess =
  777. +        GENERIC_EXECUTE|GENERIC_WRITE|GENERIC_READ; /* FIXME */
  778. +}
  779. +
  780. +void nfs_to_stat_lx_info(
  781. +    IN void *daemon_context,
  782. +    IN const char *name,
  783. +    IN const nfs41_file_info *info,
  784. +    OUT PFILE_STAT_LX_INFORMATION stat_lx_out)
  785. +{
  786. +    nfs41_daemon_globals *nfs41_dg =
  787. +        (nfs41_daemon_globals *)daemon_context;
  788. +
  789. +    EASSERT(info->attrmask.count > 0);
  790. +
  791. +    stat_lx_out->FileId.QuadPart = info->fileid;
  792. +
  793. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_CREATE) {
  794. +        nfs_time_to_file_time(&info->time_create,
  795. +            &stat_lx_out->CreationTime);
  796. +    }
  797. +    else {
  798. +        DPRINTF(1, ("nfs_to_stat_lx_info(name='%s'): "
  799. +            "time_create not set\n", name));
  800. +        stat_lx_out->CreationTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  801. +    }
  802. +
  803. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_ACCESS) {
  804. +        nfs_time_to_file_time(&info->time_access,
  805. +            &stat_lx_out->LastAccessTime);
  806. +    }
  807. +    else {
  808. +        DPRINTF(1, ("nfs_to_stat_lx_info(name='%s'): "
  809. +            "time_access not set\n", name));
  810. +        stat_lx_out->LastAccessTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  811. +    }
  812. +
  813. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  814. +        nfs_time_to_file_time(&info->time_modify,
  815. +            &stat_lx_out->LastWriteTime);
  816. +    }
  817. +    else {
  818. +        DPRINTF(1, ("nfs_to_stat_lx_info(name='%s'): "
  819. +            "time_modify not set\n", name));
  820. +        stat_lx_out->LastWriteTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  821. +    }
  822. +
  823. +    /* XXX: was using 'change' attr, but that wasn't giving a time */
  824. +    if (info->attrmask.arr[1] & FATTR4_WORD1_TIME_MODIFY) {
  825. +        nfs_time_to_file_time(&info->time_modify, &stat_lx_out->ChangeTime);
  826. +    }
  827. +    else {
  828. +        DPRINTF(1, ("nfs_to_stat_lx_info(name='%s'): "
  829. +            "time_modify2 not set\n", name));
  830. +        stat_lx_out->ChangeTime.QuadPart = FILE_INFO_TIME_NOT_SET;
  831. +    }
  832. +
  833. +    stat_lx_out->AllocationSize.QuadPart =
  834. +        stat_lx_out->EndOfFile.QuadPart = (LONGLONG)info->size;
  835. +
  836. +    stat_lx_out->FileAttributes = nfs_file_info_to_attributes(info);
  837. +
  838. +    stat_lx_out->ReparseTag = (info->type == NF4LNK)?
  839. +        IO_REPARSE_TAG_SYMLINK : 0;
  840. +
  841. +    stat_lx_out->NumberOfLinks = info->numlinks;
  842. +    stat_lx_out->EffectiveAccess =
  843. +        GENERIC_EXECUTE|GENERIC_WRITE|GENERIC_READ; /* FIXME */
  844. +
  845. +    stat_lx_out->LxFlags = 0UL;
  846. +
  847. +    if (!info->case_insensitive) {
  848. +        stat_lx_out->LxFlags |= LX_FILE_CASE_SENSITIVE_DIR;
  849. +    }
  850. +
  851. +    stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_MODE;
  852. +
  853. +    stat_lx_out->LxMode = 0UL;
  854. +    switch(info->type) {
  855. +        case NF4REG:
  856. +            stat_lx_out->LxMode |= LX_MODE_S_IFREG;
  857. +            break;
  858. +        case NF4DIR:
  859. +            stat_lx_out->LxMode |= LX_MODE_S_IFDIR;
  860. +            break;
  861. +        case NF4BLK:
  862. +            /* Map block dev to WSL char dev */
  863. +            stat_lx_out->LxMode |= LX_MODE_S_IFCHR;
  864. +            break;
  865. +        case NF4CHR:
  866. +            stat_lx_out->LxMode |= LX_MODE_S_IFCHR;
  867. +            break;
  868. +        case NF4LNK:
  869. +            /*
  870. +             * gisburn: Is this really correct to do nothing here,
  871. +             * or is |stat_lx_out->ReparseTag| enough ?
  872. +             */
  873. +            if (info->symlink_dir)
  874. +                stat_lx_out->LxMode |= LX_MODE_S_IFDIR;
  875. +            break;
  876. +        case NF4SOCK:
  877. +            /* Map socket dev to WSL char dev */
  878. +            stat_lx_out->LxMode |= LX_MODE_S_IFCHR;
  879. +            break;
  880. +        case NF4FIFO:
  881. +            stat_lx_out->LxMode |= LX_MODE_S_IFIFO;
  882. +            break;
  883. +        default:
  884. +            DPRINTF(0,
  885. +                ("nfs_to_stat_lx_info: "
  886. +                "unhandled file type %d, defaulting to NF4REG\n",
  887. +                info->type));
  888. +            stat_lx_out->LxMode |= LX_MODE_S_IFREG;
  889. +            break;
  890. +    }
  891. +
  892. +    EASSERT((info->attrmask.count > 0) &&
  893. +        (info->attrmask.arr[1] & FATTR4_WORD1_MODE));
  894. +    if (info->mode & MODE4_RUSR)
  895. +        stat_lx_out->LxMode |= LX_MODE_S_IREAD;
  896. +    if (info->mode & MODE4_WUSR)
  897. +        stat_lx_out->LxMode |= LX_MODE_S_IWRITE;
  898. +    if (info->mode & MODE4_XUSR)
  899. +        stat_lx_out->LxMode |= LX_MODE_S_IEXEC;
  900. +
  901. +    char owner[NFS4_FATTR4_OWNER_LIMIT+1];
  902. +    char owner_group[NFS4_FATTR4_OWNER_LIMIT+1];
  903. +    uid_t map_uid = ~0UL;
  904. +    gid_t map_gid = ~0UL;
  905. +    char *at_ch; /* pointer to '@' */
  906. +
  907. +    EASSERT((info->attrmask.arr[1] & FATTR4_WORD1_OWNER) != 0);
  908. +    EASSERT((info->attrmask.arr[1] & FATTR4_WORD1_OWNER_GROUP) != 0);
  909. +
  910. +    /* Make copies as we will modify  them */
  911. +    (void)strcpy(owner, info->owner);
  912. +    (void)strcpy(owner_group, info->owner_group);
  913. +
  914. +    /*
  915. +     * Map owner to local uid
  916. +     *
  917. +     * |owner| can be numeric string ("1616"), plain username
  918. +     * ("gisburn") or username@domain ("gisburn@sun.com")
  919. +     */
  920. +    /* stomp over '@' */
  921. +    at_ch = strchr(owner, '@');
  922. +    if (at_ch)
  923. +        *at_ch = '\0';
  924. +
  925. +    if (!nfs41_idmap_name_to_uid(
  926. +        nfs41_dg->idmapper,
  927. +        owner,
  928. +        &map_uid)) {
  929. +        stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_UID;
  930. +        stat_lx_out->LxUid = map_uid;
  931. +    }
  932. +    else {
  933. +        /*
  934. +         * No mapping --> Use |NFS NFS_USER_NOBODY_UID| and set
  935. +         * |LX_FILE_METADATA_HAS_UID|, because we have an user
  936. +         * name, but just no name2uid mapping
  937. +         */
  938. +        stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_UID;
  939. +        stat_lx_out->LxUid = NFS_USER_NOBODY_UID;
  940. +    }
  941. +
  942. +    /*
  943. +     * Map owner_group to local gid
  944. +     *
  945. +     * |owner_group| can be numeric string ("1616"), plain username
  946. +     * ("gisgrp") or username@domain ("gisgrp@sun.com")
  947. +     */
  948. +    /* stomp over '@' */
  949. +    at_ch = strchr(owner_group, '@');
  950. +    if (at_ch)
  951. +        *at_ch = '\0';
  952. +
  953. +    if (!nfs41_idmap_group_to_gid(
  954. +        nfs41_dg->idmapper,
  955. +        owner_group,
  956. +        &map_gid)) {
  957. +        stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_GID;
  958. +        stat_lx_out->LxGid = map_gid;
  959. +    }
  960. +    else {
  961. +        /*
  962. +         * No mapping --> Use |NFS NFS_GROUP_NOGROUP_GID| and set
  963. +         * |LX_FILE_METADATA_HAS_GID|, because we have a group
  964. +         * name, but just no name2gid mapping
  965. +         */
  966. +        stat_lx_out->LxFlags |= LX_FILE_METADATA_HAS_GID;
  967. +        stat_lx_out->LxUid = NFS_GROUP_NOGROUP_GID;
  968. +    }
  969. +
  970. +    /* FIXME: |LX_FILE_METADATA_HAS_DEVICE_ID| not implemented yet */
  971. +    stat_lx_out->LxDeviceIdMajor = 0UL;
  972. +    stat_lx_out->LxDeviceIdMinor = 0UL;
  973. +}
  974. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  975. +
  976.  /* copy |nfs41_file_info| */
  977.  void nfs41_file_info_cpy(
  978.      OUT nfs41_file_info *dest,
  979. diff --git a/daemon/getattr.c b/daemon/getattr.c
  980. index 3d0dabf..642f84e 100644
  981. --- a/daemon/getattr.c
  982. +++ b/daemon/getattr.c
  983. @@ -187,6 +187,15 @@ static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
  984.      case FileNetworkOpenInformation:
  985.          nfs_to_network_openinfo(state->file.name.name, &info, &args->network_info);
  986.          break;
  987. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  988. +    case FileStatInformation:
  989. +        nfs_to_stat_info(state->file.name.name, &info, &args->stat_info);
  990. +        break;
  991. +    case FileStatLxInformation:
  992. +        nfs_to_stat_lx_info(daemon_context,
  993. +            state->file.name.name, &info, &args->stat_lx_info);
  994. +        break;
  995. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  996.      default:
  997.          eprintf("unhandled file query class %d\n", args->query_class);
  998.          status = ERROR_INVALID_PARAMETER;
  999. @@ -238,6 +247,22 @@ static int marshall_getattr(unsigned char *buffer, uint32_t *length, nfs41_upcal
  1000.          status = safe_write(&buffer, length, &args->network_info, info_len);
  1001.          if (status) goto out;
  1002.          break;
  1003. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  1004. +    case FileStatInformation:
  1005. +        info_len = sizeof(args->stat_info);
  1006. +        status = safe_write(&buffer, length, &info_len, sizeof(info_len));
  1007. +        if (status) goto out;
  1008. +        status = safe_write(&buffer, length, &args->stat_info, info_len);
  1009. +        if (status) goto out;
  1010. +        break;
  1011. +    case FileStatLxInformation:
  1012. +        info_len = sizeof(args->stat_lx_info);
  1013. +        status = safe_write(&buffer, length, &info_len, sizeof(info_len));
  1014. +        if (status) goto out;
  1015. +        status = safe_write(&buffer, length, &args->stat_lx_info, info_len);
  1016. +        if (status) goto out;
  1017. +        break;
  1018. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  1019.      default:
  1020.          eprintf("unknown file query class %d\n", args->query_class);
  1021.          status = 103;
  1022. diff --git a/daemon/nfs41_const.h b/daemon/nfs41_const.h
  1023. index 8a0c259..0738241 100644
  1024. --- a/daemon/nfs41_const.h
  1025. +++ b/daemon/nfs41_const.h
  1026. @@ -443,4 +443,18 @@ enum nfs_ftype4 {
  1027.  #define NFS_USER_NOBODY_UID     65534
  1028.  #define NFS_GROUP_NOGROUP_GID   65534
  1029.  
  1030. +/* Mode bits */
  1031. +#define MODE4_SUID 0x800    /* set user id on execution     */
  1032. +#define MODE4_SGID 0x400    /* set group id on execution    */
  1033. +#define MODE4_SVTX 0x200    /* save text even after use     */
  1034. +#define MODE4_RUSR 0x100    /* read permission: owner       */
  1035. +#define MODE4_WUSR 0x080    /* write permission: owner      */
  1036. +#define MODE4_XUSR 0x040    /* execute permission: owner    */
  1037. +#define MODE4_RGRP 0x020    /* read permission: group       */
  1038. +#define MODE4_WGRP 0x010    /* write permission: group      */
  1039. +#define MODE4_XGRP 0x008    /* execute permission: group    */
  1040. +#define MODE4_ROTH 0x004    /* read permission: other       */
  1041. +#define MODE4_WOTH 0x002    /* write permission: other      */
  1042. +#define MODE4_XOTH 0x001    /* execute permission: other    */
  1043. +
  1044.  #endif /* !__NFS41_NFS_CONST_H__ */
  1045. diff --git a/daemon/upcall.h b/daemon/upcall.h
  1046. index a01898a..deeac9e 100644
  1047. --- a/daemon/upcall.h
  1048. +++ b/daemon/upcall.h
  1049. @@ -23,8 +23,8 @@
  1050.  #ifndef __NFS41_DAEMON_UPCALL_H__
  1051.  #define __NFS41_DAEMON_UPCALL_H__
  1052.  
  1053. -#include "nfs41_ops.h"
  1054.  #include "nfs41_build_features.h"
  1055. +#include "nfs41_ops.h"
  1056.  #include "from_kernel.h"
  1057.  
  1058.  #define NFSD_VERSION_MISMATCH 116
  1059. @@ -100,6 +100,10 @@ typedef struct __getattr_upcall_args {
  1060.      FILE_ATTRIBUTE_TAG_INFO tag_info;
  1061.      FILE_INTERNAL_INFORMATION intr_info;
  1062.      FILE_NETWORK_OPEN_INFORMATION network_info;
  1063. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  1064. +    FILE_STAT_INFORMATION stat_info;
  1065. +    FILE_STAT_LX_INFORMATION stat_lx_info;
  1066. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  1067.      int query_class;
  1068.      int buf_len;
  1069.      int query_reply_len;
  1070. diff --git a/daemon/util.h b/daemon/util.h
  1071. index 2b13d06..37d50a7 100644
  1072. --- a/daemon/util.h
  1073. +++ b/daemon/util.h
  1074. @@ -26,6 +26,7 @@
  1075.  #include <stdlib.h>
  1076.  #include <stdbool.h>
  1077.  
  1078. +#include "nfs41_build_features.h"
  1079.  #include "nfs41_types.h"
  1080.  #include "from_kernel.h"
  1081.  
  1082. @@ -184,6 +185,17 @@ void nfs_to_network_openinfo(
  1083.      IN const char *name,
  1084.      IN const nfs41_file_info *info,
  1085.      OUT PFILE_NETWORK_OPEN_INFORMATION std_out);
  1086. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  1087. +void nfs_to_stat_info(
  1088. +    IN const char *name,
  1089. +    IN const nfs41_file_info *info,
  1090. +    OUT PFILE_STAT_INFORMATION stat_out);
  1091. +void nfs_to_stat_lx_info(
  1092. +    IN void *daemon_context,
  1093. +    IN const char *name,
  1094. +    IN const nfs41_file_info *info,
  1095. +    OUT PFILE_STAT_LX_INFORMATION stat_lx_out);
  1096. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  1097.  void nfs41_file_info_cpy(
  1098.      OUT nfs41_file_info *dest,
  1099.      IN const nfs41_file_info *src);
  1100. diff --git a/include/from_kernel.h b/include/from_kernel.h
  1101. index b395112..b4ff4cc 100644
  1102. --- a/include/from_kernel.h
  1103. +++ b/include/from_kernel.h
  1104. @@ -1,44 +1,44 @@
  1105. -/* NFSv4.1 client for Windows
  1106. - * Copyright (C) 2012 The Regents of the University of Michigan
  1107. - *
  1108. - * Olga Kornievskaia <aglo@umich.edu>
  1109. - * Casey Bodley <cbodley@umich.edu>
  1110. - *
  1111. - * This library is free software; you can redistribute it and/or modify it
  1112. - * under the terms of the GNU Lesser General Public License as published by
  1113. - * the Free Software Foundation; either version 2.1 of the License, or (at
  1114. - * your option) any later version.
  1115. - *
  1116. - * This library is distributed in the hope that it will be useful, but
  1117. - * without any warranty; without even the implied warranty of merchantability
  1118. - * or fitness for a particular purpose.  See the GNU Lesser General Public
  1119. - * License for more details.
  1120. - *
  1121. - * You should have received a copy of the GNU Lesser General Public License
  1122. - * along with this library; if not, write to the Free Software Foundation,
  1123. - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  1124. - */
  1125. -
  1126. -#ifndef _NFS41_DAEMON_
  1127. -#define _NFS41_DAEMON_
  1128. -
  1129. -#define FILE_DIRECTORY_FILE                     0x00000001
  1130. -#define FILE_WRITE_THROUGH                      0x00000002
  1131. -#define FILE_SEQUENTIAL_ONLY                    0x00000004
  1132. -#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008
  1133. -
  1134. -#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
  1135. -#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
  1136. -#define FILE_NON_DIRECTORY_FILE                 0x00000040
  1137. -#define FILE_CREATE_TREE_CONNECTION             0x00000080
  1138. -
  1139. -#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
  1140. -#define FILE_NO_EA_KNOWLEDGE                    0x00000200
  1141. -#define FILE_OPEN_REMOTE_INSTANCE               0x00000400
  1142. -#define FILE_RANDOM_ACCESS                      0x00000800
  1143. -
  1144. -#define FILE_DELETE_ON_CLOSE                    0x00001000
  1145. -#define FILE_OPEN_BY_FILE_ID                    0x00002000
  1146. +/* NFSv4.1 client for Windows
  1147. + * Copyright (C) 2012 The Regents of the University of Michigan
  1148. + *
  1149. + * Olga Kornievskaia <aglo@umich.edu>
  1150. + * Casey Bodley <cbodley@umich.edu>
  1151. + *
  1152. + * This library is free software; you can redistribute it and/or modify it
  1153. + * under the terms of the GNU Lesser General Public License as published by
  1154. + * the Free Software Foundation; either version 2.1 of the License, or (at
  1155. + * your option) any later version.
  1156. + *
  1157. + * This library is distributed in the hope that it will be useful, but
  1158. + * without any warranty; without even the implied warranty of merchantability
  1159. + * or fitness for a particular purpose.  See the GNU Lesser General Public
  1160. + * License for more details.
  1161. + *
  1162. + * You should have received a copy of the GNU Lesser General Public License
  1163. + * along with this library; if not, write to the Free Software Foundation,
  1164. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  1165. + */
  1166. +
  1167. +#ifndef _NFS41_DAEMON_
  1168. +#define _NFS41_DAEMON_
  1169. +
  1170. +#define FILE_DIRECTORY_FILE                     0x00000001
  1171. +#define FILE_WRITE_THROUGH                      0x00000002
  1172. +#define FILE_SEQUENTIAL_ONLY                    0x00000004
  1173. +#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008
  1174. +
  1175. +#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
  1176. +#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
  1177. +#define FILE_NON_DIRECTORY_FILE                 0x00000040
  1178. +#define FILE_CREATE_TREE_CONNECTION             0x00000080
  1179. +
  1180. +#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
  1181. +#define FILE_NO_EA_KNOWLEDGE                    0x00000200
  1182. +#define FILE_OPEN_REMOTE_INSTANCE               0x00000400
  1183. +#define FILE_RANDOM_ACCESS                      0x00000800
  1184. +
  1185. +#define FILE_DELETE_ON_CLOSE                    0x00001000
  1186. +#define FILE_OPEN_BY_FILE_ID                    0x00002000
  1187.  #define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000
  1188.  #define FILE_NO_COMPRESSION                     0x00008000
  1189.  
  1190. @@ -49,17 +49,17 @@
  1191.  #define FILE_RESERVE_OPFILTER                   0x00100000
  1192.  #define FILE_OPEN_REPARSE_POINT                 0x00200000
  1193.  #define FILE_OPEN_NO_RECALL                     0x00400000
  1194. -#define FILE_OPEN_FOR_FREE_SPACE_QUERY          0x00800000
  1195. -
  1196. -#define FILE_COPY_STRUCTURED_STORAGE            0x00000041
  1197. -#define FILE_STRUCTURED_STORAGE                 0x00000441
  1198. -
  1199. -#define FILE_SUPERSEDE                  0x00000000
  1200. -#define FILE_OPEN                       0x00000001
  1201. -#define FILE_CREATE                     0x00000002
  1202. -#define FILE_OPEN_IF                    0x00000003
  1203. -#define FILE_OVERWRITE                  0x00000004
  1204. -#define FILE_OVERWRITE_IF               0x00000005
  1205. +#define FILE_OPEN_FOR_FREE_SPACE_QUERY          0x00800000
  1206. +
  1207. +#define FILE_COPY_STRUCTURED_STORAGE            0x00000041
  1208. +#define FILE_STRUCTURED_STORAGE                 0x00000441
  1209. +
  1210. +#define FILE_SUPERSEDE                  0x00000000
  1211. +#define FILE_OPEN                       0x00000001
  1212. +#define FILE_CREATE                     0x00000002
  1213. +#define FILE_OPEN_IF                    0x00000003
  1214. +#define FILE_OVERWRITE                  0x00000004
  1215. +#define FILE_OVERWRITE_IF               0x00000005
  1216.  #define FILE_MAXIMUM_DISPOSITION        0x00000005
  1217.  
  1218.  typedef enum _FILE_INFORMATION_CLASS {
  1219. @@ -142,109 +142,167 @@ typedef enum _FILE_INFORMATION_CLASS {
  1220.      FileMaximumInformation
  1221.  } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
  1222.  
  1223. -
  1224. -/* kernel structures for QueryDirectory results */
  1225. -typedef struct _FILE_NAMES_INFORMATION {
  1226. -    ULONG NextEntryOffset;
  1227. -    ULONG FileIndex;
  1228. -    ULONG FileNameLength;
  1229. -    WCHAR FileName[1];
  1230. -} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
  1231. -
  1232. -typedef struct _FILE_DIRECTORY_INFO {
  1233. -    ULONG NextEntryOffset;
  1234. -    ULONG FileIndex;
  1235. -    LARGE_INTEGER CreationTime;
  1236. -    LARGE_INTEGER LastAccessTime;
  1237. -    LARGE_INTEGER LastWriteTime;
  1238. -    LARGE_INTEGER ChangeTime;
  1239. -    LARGE_INTEGER EndOfFile;
  1240. -    LARGE_INTEGER AllocationSize;
  1241. -    ULONG FileAttributes;
  1242. -    ULONG FileNameLength;
  1243. -    WCHAR FileName[1];
  1244. -} FILE_DIRECTORY_INFO, *PFILE_DIRECTORY_INFO;
  1245. -
  1246. -typedef struct _FILE_BOTH_DIR_INFORMATION {
  1247. -    ULONG NextEntryOffset;
  1248. -    ULONG FileIndex;
  1249. -    LARGE_INTEGER CreationTime;
  1250. -    LARGE_INTEGER LastAccessTime;
  1251. -    LARGE_INTEGER LastWriteTime;
  1252. -    LARGE_INTEGER ChangeTime;
  1253. -    LARGE_INTEGER EndOfFile;
  1254. -    LARGE_INTEGER AllocationSize;
  1255. -    ULONG FileAttributes;
  1256. -    ULONG FileNameLength;
  1257. -    ULONG EaSize;
  1258. -    CCHAR ShortNameLength;
  1259. -    WCHAR ShortName[12];
  1260. -    WCHAR FileName[1];
  1261. -} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
  1262. -
  1263. -#ifdef FIXME_OLD_DDK
  1264. -typedef struct _FILE_FULL_DIR_INFO {
  1265. -    ULONG NextEntryOffset;
  1266. -    ULONG FileIndex;
  1267. -    LARGE_INTEGER CreationTime;
  1268. -    LARGE_INTEGER LastAccessTime;
  1269. -    LARGE_INTEGER LastWriteTime;
  1270. -    LARGE_INTEGER ChangeTime;
  1271. -    LARGE_INTEGER EndOfFile;
  1272. -    LARGE_INTEGER AllocationSize;
  1273. -    ULONG FileAttributes;
  1274. -    ULONG FileNameLength;
  1275. -    ULONG EaSize;
  1276. -    WCHAR FileName[1];
  1277. -} FILE_FULL_DIR_INFO, *PFILE_FULL_DIR_INFO;
  1278. -#endif /* FIXME_OLD_DDK */
  1279. -
  1280. -typedef struct _FILE_ID_FULL_DIR_INFO {
  1281. -    ULONG NextEntryOffset;
  1282. -    ULONG FileIndex;
  1283. -    LARGE_INTEGER CreationTime;
  1284. -    LARGE_INTEGER LastAccessTime;
  1285. -    LARGE_INTEGER LastWriteTime;
  1286. -    LARGE_INTEGER ChangeTime;
  1287. -    LARGE_INTEGER EndOfFile;
  1288. -    LARGE_INTEGER AllocationSize;
  1289. -    ULONG FileAttributes;
  1290. -    ULONG FileNameLength;
  1291. -    ULONG EaSize;
  1292. -    LARGE_INTEGER FileId;
  1293. -    WCHAR FileName[1];
  1294. -} FILE_ID_FULL_DIR_INFO, *PFILE_ID_FULL_DIR_INFO;
  1295. -
  1296. -typedef struct _FILE_LINK_INFORMATION {
  1297. -    BOOLEAN ReplaceIfExists;
  1298. -    HANDLE RootDirectory;
  1299. -    ULONG FileNameLength;
  1300. -    WCHAR FileName[1];
  1301. -} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
  1302. -
  1303. -typedef struct _FILE_FULL_EA_INFORMATION {
  1304. -    ULONG NextEntryOffset;
  1305. -    UCHAR Flags;
  1306. -    UCHAR EaNameLength;
  1307. -    USHORT EaValueLength;
  1308. -    CHAR EaName[1];
  1309. -} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
  1310. -
  1311. -typedef struct _FILE_GET_EA_INFORMATION {
  1312. -    ULONG NextEntryOffset;
  1313. -    UCHAR EaNameLength;
  1314. -    CHAR  EaName[1];
  1315. -} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;
  1316. -
  1317. -typedef struct _FILE_NETWORK_OPEN_INFORMATION {
  1318. -    LARGE_INTEGER CreationTime;
  1319. -    LARGE_INTEGER LastAccessTime;
  1320. -    LARGE_INTEGER LastWriteTime;
  1321. -    LARGE_INTEGER ChangeTime;
  1322. -    LARGE_INTEGER AllocationSize;
  1323. -    LARGE_INTEGER EndOfFile;
  1324. -    ULONG FileAttributes;
  1325. -} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
  1326. +
  1327. +/* kernel structures for QueryDirectory results */
  1328. +typedef struct _FILE_NAMES_INFORMATION {
  1329. +    ULONG NextEntryOffset;
  1330. +    ULONG FileIndex;
  1331. +    ULONG FileNameLength;
  1332. +    WCHAR FileName[1];
  1333. +} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
  1334. +
  1335. +typedef struct _FILE_DIRECTORY_INFO {
  1336. +    ULONG NextEntryOffset;
  1337. +    ULONG FileIndex;
  1338. +    LARGE_INTEGER CreationTime;
  1339. +    LARGE_INTEGER LastAccessTime;
  1340. +    LARGE_INTEGER LastWriteTime;
  1341. +    LARGE_INTEGER ChangeTime;
  1342. +    LARGE_INTEGER EndOfFile;
  1343. +    LARGE_INTEGER AllocationSize;
  1344. +    ULONG FileAttributes;
  1345. +    ULONG FileNameLength;
  1346. +    WCHAR FileName[1];
  1347. +} FILE_DIRECTORY_INFO, *PFILE_DIRECTORY_INFO;
  1348. +
  1349. +typedef struct _FILE_BOTH_DIR_INFORMATION {
  1350. +    ULONG NextEntryOffset;
  1351. +    ULONG FileIndex;
  1352. +    LARGE_INTEGER CreationTime;
  1353. +    LARGE_INTEGER LastAccessTime;
  1354. +    LARGE_INTEGER LastWriteTime;
  1355. +    LARGE_INTEGER ChangeTime;
  1356. +    LARGE_INTEGER EndOfFile;
  1357. +    LARGE_INTEGER AllocationSize;
  1358. +    ULONG FileAttributes;
  1359. +    ULONG FileNameLength;
  1360. +    ULONG EaSize;
  1361. +    CCHAR ShortNameLength;
  1362. +    WCHAR ShortName[12];
  1363. +    WCHAR FileName[1];
  1364. +} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
  1365. +
  1366. +#ifdef FIXME_OLD_DDK
  1367. +typedef struct _FILE_FULL_DIR_INFO {
  1368. +    ULONG NextEntryOffset;
  1369. +    ULONG FileIndex;
  1370. +    LARGE_INTEGER CreationTime;
  1371. +    LARGE_INTEGER LastAccessTime;
  1372. +    LARGE_INTEGER LastWriteTime;
  1373. +    LARGE_INTEGER ChangeTime;
  1374. +    LARGE_INTEGER EndOfFile;
  1375. +    LARGE_INTEGER AllocationSize;
  1376. +    ULONG FileAttributes;
  1377. +    ULONG FileNameLength;
  1378. +    ULONG EaSize;
  1379. +    WCHAR FileName[1];
  1380. +} FILE_FULL_DIR_INFO, *PFILE_FULL_DIR_INFO;
  1381. +#endif /* FIXME_OLD_DDK */
  1382. +
  1383. +typedef struct _FILE_ID_FULL_DIR_INFO {
  1384. +    ULONG NextEntryOffset;
  1385. +    ULONG FileIndex;
  1386. +    LARGE_INTEGER CreationTime;
  1387. +    LARGE_INTEGER LastAccessTime;
  1388. +    LARGE_INTEGER LastWriteTime;
  1389. +    LARGE_INTEGER ChangeTime;
  1390. +    LARGE_INTEGER EndOfFile;
  1391. +    LARGE_INTEGER AllocationSize;
  1392. +    ULONG FileAttributes;
  1393. +    ULONG FileNameLength;
  1394. +    ULONG EaSize;
  1395. +    LARGE_INTEGER FileId;
  1396. +    WCHAR FileName[1];
  1397. +} FILE_ID_FULL_DIR_INFO, *PFILE_ID_FULL_DIR_INFO;
  1398. +
  1399. +typedef struct _FILE_LINK_INFORMATION {
  1400. +    BOOLEAN ReplaceIfExists;
  1401. +    HANDLE RootDirectory;
  1402. +    ULONG FileNameLength;
  1403. +    WCHAR FileName[1];
  1404. +} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
  1405. +
  1406. +typedef struct _FILE_FULL_EA_INFORMATION {
  1407. +    ULONG NextEntryOffset;
  1408. +    UCHAR Flags;
  1409. +    UCHAR EaNameLength;
  1410. +    USHORT EaValueLength;
  1411. +    CHAR EaName[1];
  1412. +} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
  1413. +
  1414. +typedef struct _FILE_GET_EA_INFORMATION {
  1415. +    ULONG NextEntryOffset;
  1416. +    UCHAR EaNameLength;
  1417. +    CHAR  EaName[1];
  1418. +} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;
  1419. +
  1420. +typedef struct _FILE_NETWORK_OPEN_INFORMATION {
  1421. +    LARGE_INTEGER CreationTime;
  1422. +    LARGE_INTEGER LastAccessTime;
  1423. +    LARGE_INTEGER LastWriteTime;
  1424. +    LARGE_INTEGER ChangeTime;
  1425. +    LARGE_INTEGER AllocationSize;
  1426. +    LARGE_INTEGER EndOfFile;
  1427. +    ULONG FileAttributes;
  1428. +} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
  1429. +
  1430. +typedef struct _FILE_STAT_INFORMATION {
  1431. +    LARGE_INTEGER FileId;
  1432. +    LARGE_INTEGER CreationTime;
  1433. +    LARGE_INTEGER LastAccessTime;
  1434. +    LARGE_INTEGER LastWriteTime;
  1435. +    LARGE_INTEGER ChangeTime;
  1436. +    LARGE_INTEGER AllocationSize;
  1437. +    LARGE_INTEGER EndOfFile;
  1438. +    ULONG FileAttributes;
  1439. +    ULONG ReparseTag;
  1440. +    ULONG NumberOfLinks;
  1441. +    ACCESS_MASK EffectiveAccess;
  1442. +} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;
  1443. +
  1444. +typedef struct _FILE_STAT_LX_INFORMATION {
  1445. +    LARGE_INTEGER FileId;
  1446. +    LARGE_INTEGER CreationTime;
  1447. +    LARGE_INTEGER LastAccessTime;
  1448. +    LARGE_INTEGER LastWriteTime;
  1449. +    LARGE_INTEGER ChangeTime;
  1450. +    LARGE_INTEGER AllocationSize;
  1451. +    LARGE_INTEGER EndOfFile;
  1452. +    ULONG FileAttributes;
  1453. +    ULONG ReparseTag;
  1454. +    ULONG NumberOfLinks;
  1455. +    ACCESS_MASK EffectiveAccess;
  1456. +    ULONG LxFlags;
  1457. +    ULONG LxUid;
  1458. +    ULONG LxGid;
  1459. +    ULONG LxMode;
  1460. +    ULONG LxDeviceIdMajor;
  1461. +    ULONG LxDeviceIdMinor;
  1462. +} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;
  1463. +
  1464. +/* Flags for |LxFlags| field */
  1465. +#define LX_FILE_METADATA_HAS_UID        0x1
  1466. +#define LX_FILE_METADATA_HAS_GID        0x2
  1467. +#define LX_FILE_METADATA_HAS_MODE       0x4
  1468. +#define LX_FILE_METADATA_HAS_DEVICE_ID  0x8
  1469. +#define LX_FILE_CASE_SENSITIVE_DIR      0x10
  1470. +
  1471. +/*
  1472. + * Bits for |LxMode| field
  1473. + * Notes:
  1474. + * - |_S_I*| bits are not portable across platforms and protocols
  1475. + * (e.g. Win32, Cygwin, Linux, NFSv4 etc.), and we always need
  1476. + * to translate them.
  1477. + * - NFSv4 has |MODE4_*| flags in "daemon/nfs41_const.h"
  1478. + */
  1479. +#define LX_MODE_S_IFMT      0xF000 /* file type mask */
  1480. +#define LX_MODE_S_IFREG     0x8000 /* regular */
  1481. +#define LX_MODE_S_IFDIR     0x4000 /* directory */
  1482. +#define LX_MODE_S_IFCHR     0x2000 /* character special */
  1483. +#define LX_MODE_S_IFIFO     0x1000 /* pipe */
  1484. +#define LX_MODE_S_IREAD     0x0100 /* read permission, owner */
  1485. +#define LX_MODE_S_IWRITE    0x0080 /* write permission, owner */
  1486. +#define LX_MODE_S_IEXEC     0x0040 /* execute/search permission, owner */
  1487.  
  1488.  /* wdm.h */
  1489.  typedef enum _FSINFOCLASS {
  1490. @@ -265,13 +323,13 @@ typedef enum _FSINFOCLASS {
  1491.      FileFsMaximumInformation
  1492.  } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
  1493.  
  1494. -/* ntifs.h */
  1495. -#define FILE_CASE_SENSITIVE_SEARCH          0x00000001
  1496. -#define FILE_CASE_PRESERVED_NAMES           0x00000002
  1497. -#define FILE_UNICODE_ON_DISK                0x00000004
  1498. -#define FILE_PERSISTENT_ACLS                0x00000008
  1499. -#define FILE_FILE_COMPRESSION               0x00000010
  1500. -#define FILE_VOLUME_QUOTAS                  0x00000020
  1501. +/* ntifs.h */
  1502. +#define FILE_CASE_SENSITIVE_SEARCH          0x00000001
  1503. +#define FILE_CASE_PRESERVED_NAMES           0x00000002
  1504. +#define FILE_UNICODE_ON_DISK                0x00000004
  1505. +#define FILE_PERSISTENT_ACLS                0x00000008
  1506. +#define FILE_FILE_COMPRESSION               0x00000010
  1507. +#define FILE_VOLUME_QUOTAS                  0x00000020
  1508.  #define FILE_SUPPORTS_SPARSE_FILES          0x00000040
  1509.  #define FILE_SUPPORTS_REPARSE_POINTS        0x00000080
  1510.  #define FILE_SUPPORTS_REMOTE_STORAGE        0x00000100
  1511. @@ -280,11 +338,11 @@ typedef enum _FSINFOCLASS {
  1512.  #define FILE_VOLUME_IS_COMPRESSED           0x00008000
  1513.  #define FILE_SUPPORTS_OBJECT_IDS            0x00010000
  1514.  #define FILE_SUPPORTS_ENCRYPTION            0x00020000
  1515. -#define FILE_NAMED_STREAMS                  0x00040000
  1516. -#define FILE_READ_ONLY_VOLUME               0x00080000
  1517. -#define FILE_SEQUENTIAL_WRITE_ONCE          0x00100000
  1518. -#define FILE_SUPPORTS_TRANSACTIONS          0x00200000
  1519. -#define FILE_SUPPORTS_HARD_LINKS            0x00400000
  1520. +#define FILE_NAMED_STREAMS                  0x00040000
  1521. +#define FILE_READ_ONLY_VOLUME               0x00080000
  1522. +#define FILE_SEQUENTIAL_WRITE_ONCE          0x00100000
  1523. +#define FILE_SUPPORTS_TRANSACTIONS          0x00200000
  1524. +#define FILE_SUPPORTS_HARD_LINKS            0x00400000
  1525.  #define FILE_SUPPORTS_EXTENDED_ATTRIBUTES   0x00800000
  1526.  #define FILE_SUPPORTS_OPEN_BY_FILE_ID       0x01000000
  1527.  #define FILE_SUPPORTS_USN_JOURNAL           0x02000000
  1528. @@ -296,28 +354,28 @@ typedef enum _FSINFOCLASS {
  1529.  
  1530.  typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
  1531.      ULONG FileSystemAttributes;
  1532. -    LONG MaximumComponentNameLength;
  1533. -    ULONG FileSystemNameLength;
  1534. -    WCHAR FileSystemName[1];
  1535. -} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
  1536. -
  1537. -/* ntddk.h */
  1538. -typedef struct _FILE_FS_SIZE_INFORMATION {
  1539. -    LARGE_INTEGER TotalAllocationUnits;
  1540. -    LARGE_INTEGER AvailableAllocationUnits;
  1541. -    ULONG SectorsPerAllocationUnit;
  1542. -    ULONG BytesPerSector;
  1543. -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
  1544. -
  1545. -typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
  1546. -    LARGE_INTEGER TotalAllocationUnits;
  1547. -    LARGE_INTEGER CallerAvailableAllocationUnits;
  1548. -    LARGE_INTEGER ActualAvailableAllocationUnits;
  1549. -    ULONG SectorsPerAllocationUnit;
  1550. -    ULONG BytesPerSector;
  1551. -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
  1552. -
  1553. -typedef struct _FILE_INTERNAL_INFORMATION {
  1554. -    LARGE_INTEGER IndexNumber;
  1555. -} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
  1556. -#endif
  1557. +    LONG MaximumComponentNameLength;
  1558. +    ULONG FileSystemNameLength;
  1559. +    WCHAR FileSystemName[1];
  1560. +} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
  1561. +
  1562. +/* ntddk.h */
  1563. +typedef struct _FILE_FS_SIZE_INFORMATION {
  1564. +    LARGE_INTEGER TotalAllocationUnits;
  1565. +    LARGE_INTEGER AvailableAllocationUnits;
  1566. +    ULONG SectorsPerAllocationUnit;
  1567. +    ULONG BytesPerSector;
  1568. +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
  1569. +
  1570. +typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
  1571. +    LARGE_INTEGER TotalAllocationUnits;
  1572. +    LARGE_INTEGER CallerAvailableAllocationUnits;
  1573. +    LARGE_INTEGER ActualAvailableAllocationUnits;
  1574. +    ULONG SectorsPerAllocationUnit;
  1575. +    ULONG BytesPerSector;
  1576. +} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
  1577. +
  1578. +typedef struct _FILE_INTERNAL_INFORMATION {
  1579. +    LARGE_INTEGER IndexNumber;
  1580. +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
  1581. +#endif
  1582. diff --git a/nfs41_build_features.h b/nfs41_build_features.h
  1583. index 02f2840..dfb144f 100644
  1584. --- a/nfs41_build_features.h
  1585. +++ b/nfs41_build_features.h
  1586. @@ -160,4 +160,9 @@
  1587.   */
  1588.  #define NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES 1
  1589.  
  1590. +/*
  1591. + * NFS41_DRIVER_WSL_SUPPORT - Enable WSL support
  1592. + */
  1593. +#define NFS41_DRIVER_WSL_SUPPORT 1
  1594. +
  1595.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
  1596. diff --git a/sys/nfs41sys_fileinfo.c b/sys/nfs41sys_fileinfo.c
  1597. index 0f7ca82..5a21916 100644
  1598. --- a/sys/nfs41sys_fileinfo.c
  1599. +++ b/sys/nfs41sys_fileinfo.c
  1600. @@ -306,6 +306,10 @@ NTSTATUS nfs41_QueryFileInformation(
  1601.      case FileInternalInformation:
  1602.      case FileAttributeTagInformation:
  1603.      case FileNetworkOpenInformation:
  1604. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  1605. +    case FileStatInformation:
  1606. +    case FileStatLxInformation:
  1607. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  1608.          break;
  1609.      default:
  1610.          print_error("nfs41_QueryFileInformation: unhandled class %d\n", InfoClass);
  1611. @@ -399,6 +403,10 @@ NTSTATUS nfs41_QueryFileInformation(
  1612.          case FileNetworkOpenInformation:
  1613.          case FileInternalInformation:
  1614.          case FileAttributeTagInformation:
  1615. +#ifdef NFS41_DRIVER_WSL_SUPPORT
  1616. +        case FileStatInformation:
  1617. +        case FileStatLxInformation:
  1618. +#endif /* NFS41_DRIVER_WSL_SUPPORT */
  1619.              break;
  1620.          default:
  1621.              print_error("Unhandled/unsupported InfoClass(%d)\n", (int)InfoClass);
  1622. --
  1623. 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