Compare commits

..

149 Commits

Author SHA1 Message Date
e3c19afb72 update Changelog for 2020.1 B1 2020-02-07 13:40:49 -08:00
799025e8c2 build: version.properties: fix version 2020-02-07 13:33:31 -08:00
896c00a08c Merge branch 'pvt-reject-irp' 2020-02-07 13:29:19 -08:00
8497855d80 sys: FSP_DEVICE_REJECT_EARLY_IRP macro 2020-02-07 13:22:09 -08:00
52663ec676 dll: FspFileSystemResolveReparsePoints
Fix junction handling.
2020-02-04 15:37:17 -08:00
0901fb6477 inc,sys,tst: FSP_FSCTL_VOLUME_PARAMS::RejectIrpPriorToTransact0 2020-02-03 16:43:15 -08:00
bf6d56ceac inc,sys,tst: FSP_FSCTL_VOLUME_PARAMS::RejectIrpPriorToTransact0 2020-02-03 16:38:55 -08:00
51350d5a42 inc,sys,tst: FSP_FSCTL_VOLUME_PARAMS::RejectIrpPriorToTransact 2020-02-03 14:59:23 -08:00
9e32fed598 tools: build-choco.bat 2020-01-28 19:47:14 -08:00
8301642e6b build: bump version to 1.7 2020-01-28 17:44:13 -08:00
0002655782 build: update version: 2020 2020-01-27 14:26:45 -08:00
e0e8d74d01 update changelog 2020-01-27 14:25:12 -08:00
e608920679 Merge pull request #272 from pfrejo/hotfix-1.5
Fixed data corruption when overwriting a file on a Fuse v3 filesystem
2020-01-27 14:14:35 -08:00
dbfbcb547d Fixed data corruption when overwriting a file on a Fuse v3 filesystem
When a file of size "s" is overwritten, forcing "O_APPEND" flag
makes the server file offset to be placed "s" bytes in advance.
This caused subsequent write operations to be paded by "s" zeroes,
thus corrupting the file.
2020-01-23 21:31:56 +01:00
b3dfea8303 tools: fix-source-copyright: fix botched script 2020-01-22 14:35:24 -08:00
3ab0e5a3d3 doc: add kernel mode file systems document 2020-01-16 17:04:23 -08:00
d687ef3a67 update Changelog (PR #270) 2020-01-15 13:39:59 -08:00
6df5ff980f Merge branch 'hammerg-track_dir_check' 2020-01-15 13:27:19 -08:00
14ac0f8db9 dll: FspFileSystemOpCreate_FileOpenTargetDirectory 2020-01-15 13:26:29 -08:00
ac306c2ce1 dll: open as directory when file's parent directory should be opened. 2020-01-05 09:09:05 +02:00
aedf01a384 update source copyright for 2020 2020-01-02 17:50:40 -08:00
0ce8b1c254 build: bump version to 2020.1 B1 2020-01-02 17:46:13 -08:00
4e0690e65f update Changelog for v1.5 2019-12-31 16:56:59 -08:00
e7b81e4bac build: bump version to 2019.3 GOLD 2019-12-31 16:55:35 -08:00
9dc774d306 tst: winfsp-tests: ResilientRemoveDirectoryW 2019-12-16 23:07:04 -08:00
26fe1a741b sys: FspPropagateTopFlags: propagate union of flags from top level IRP 2019-12-13 16:42:49 -08:00
efdb6d1c86 build: bump version to 2019.3 B5 2019-12-09 14:36:08 -08:00
b18df6bba8 sys: release rename lock when doing oplock breaks 2019-12-08 14:27:02 -08:00
39aad2b4fa ku: posix: improve kernel mode support 2019-11-18 22:22:32 -08:00
ab1e024965 tools: build.bat: fix winfsp-tests zip file build 2019-11-16 16:05:40 -08:00
5a67c47d0f update changelog 2019-11-16 14:54:10 -08:00
39c189aff7 sys: fsext: FspFsextProviderTransact 2019-11-16 14:02:44 -08:00
3d9fc467ef tools: build.bat: winfsp-tests zip file 2019-11-16 07:26:07 +00:00
23b5c67913 shared: minimal.h: eliminate warning on VS2015 builds 2019-11-07 16:08:41 -08:00
4b5478e50c sys: dirctl: support directory marker as FUSE style next offset 2019-11-05 22:14:16 -08:00
c7fc728ad0 build: bump version 2019-11-04 19:26:45 -08:00
254174b8e9 sys: avoid using FspFsextProvider unnecessarily 2019-11-04 16:30:30 -08:00
5110b3c5a1 sys: dirctl: support directory marker as FUSE style next offset 2019-10-30 16:40:48 -07:00
847eab3da4 tst: memfs-fuse3: #if0 ioctl 2019-10-21 20:21:36 -07:00
5131ed5c01 Merge branch 'bdutro-o_append-fix' 2019-10-21 20:14:02 -07:00
b513128cfe In Windows, Go clears any write-related flags when O_APPEND is
specified. This causes WinFSP to think that any O_APPEND requests are
actually read-only. This adds an additional check for the
FILE_APPEND_DATA flag so that we can ensure the request is sent with at
least O_WRONLY and O_APPEND set.
2019-10-21 18:04:26 -05:00
3fe69f2208 installer: add fsext development files 2019-10-18 16:23:27 -07:00
29fd9bf779 sys: fsext: allow multiple providers (up to 4) 2019-10-18 16:00:31 -07:00
3c391ca711 build: bump version to 2019.3 B3 2019-10-16 12:18:24 -07:00
82a8545d8f tst: memfs-fuse3: fix narrow conversion on x86 builds 2019-10-09 14:42:39 -07:00
79be3e445a tst: memfs-fuse3: accurately compute current time 2019-10-09 11:39:41 -07:00
b04266e0fe tools: run-tests: add memfs-fuse3 testing 2019-10-08 04:35:28 +01:00
25adfaec00 update Changelog 2019-10-08 04:30:30 +01:00
ce20747534 tst: memfs-fuse3: testing 2019-10-07 18:32:25 -07:00
d3d75bf977 tst: add memfs-fuse3 file system 2019-10-07 14:24:18 -07:00
6f1f1cda71 update Changelog 2019-10-07 22:17:07 +01:00
21dfeca124 update Changelog 2019-10-07 22:15:29 +01:00
6f585ce63e Merge pull request #251 from johntyner/feature/remove-fuse-prefix
Remove "FUSE-" prefix from file system name when using FUSE API
2019-10-07 14:05:18 -07:00
8f90305726 add support for setting file system name without 'FUSE-' prefix 2019-10-07 07:05:01 -07:00
490d0577bb Revert "Remove 'FUSE-' prefix from file system name when using fuse interface"
This reverts commit 7d2ff3afeb.
2019-10-07 06:47:02 -07:00
c9d3cb74c7 add John Tyner to contributors 2019-09-25 16:20:50 -07:00
7d2ff3afeb Remove 'FUSE-' prefix from file system name when using fuse interface 2019-09-24 20:04:29 -07:00
c415c87195 dll: FspMountSet, FspMountRemove 2019-09-24 15:34:01 -07:00
d161ca59a7 update Changelog 2019-09-12 05:36:19 +01:00
bc03af3b2a doc: update FAQ, Known File Systems 2019-09-12 04:54:40 +01:00
ed1543665c Merge pull request #248 from JohnOberschelp/master
Airfs cleanup after persistence review
2019-09-10 22:32:58 -07:00
a99fa512d4 Fixed issues noted at the PR review 2019-09-10 16:00:34 -07:00
a6800dd73d Fixed issues noted at the PR review 2019-09-10 15:59:48 -07:00
aa9354773b Fixed issues noted at the PR review 2019-09-10 15:58:35 -07:00
05b37c744b sys,dll: only user mode sends MountManager IOCTL's
(except for cleanup in FspMountdevFini)
2019-09-08 17:45:00 -07:00
1d15c9546b Merge branch 'pvt-sqlfix2' 2019-09-08 11:05:17 -07:00
51b33f02aa Merge pull request #241 from JohnOberschelp/master
Add persistence to Airfs
2019-09-07 17:40:42 -07:00
97ffa741b2 tst: volpath-test: fix silly mistake 2019-09-07 11:56:34 -07:00
073645db3b tst: fix tests broken by new mountmgr func 2019-09-07 11:39:06 -07:00
fd9ac1c9e0 appveyor: WDK 1903 hackfix 2019-09-06 20:56:37 -07:00
62b08c3d1e appveyor: WDK 1903 hackfix 2019-09-07 04:54:39 +01:00
9436fd8402 sys: implement SectorSize queries
- IRP_MJ_QUERY_VOLUME_INFORMATION/FileFsSectorSizeInformation
- IOCTL_STORAGE_QUERY_PROPERTY/StorageAccessAlignmentProperty
2019-09-06 20:52:15 -07:00
de75454d50 sys: FspFsvolDeviceControl: disable mountdev handling on fsvol devices 2019-09-06 15:43:20 -07:00
430d7a5650 sys: FspMountdevMake: use non-repeatable (i.e. non UUIDv5) GUID when non-persistent mountdev 2019-09-06 14:34:33 -07:00
4655926d03 sys, dll: mount manager support 2019-09-06 14:24:00 -07:00
565caebe4c sys,dll: FspFileSystemSetMountPoint: mount manager support 2019-09-05 19:58:14 -07:00
a47f853beb sys: mountdev: mount manager support 2019-09-05 09:54:36 -07:00
89ec3e6733 ku: UUID v5 generation 2019-09-04 13:45:53 -07:00
dbdfaeee1f tst: winfsp-tests: GetVolumePathName testing 2019-08-23 16:00:35 +01:00
2c64d59001 Add common.h & persistence.cpp for Airfs to Product.wxs 2019-08-09 15:58:12 -07:00
af8c74378e appveyor: hack to make WDK 1903 work on VS2015 2019-08-07 22:53:21 -07:00
19c320350f Add persistence.cpp and common.h 2019-08-03 17:55:29 -07:00
d60b1de430 Add persistence.cpp and common.h 2019-08-03 17:54:26 -07:00
6a7b6c77c6 Create common.h 2019-08-03 12:22:57 -07:00
16b1b2b349 Create persistence.cpp
Create persistence.cpp to supply functionality needed for volume persistence within a memory-mapped file:
    memory management
    sorted sets
    offsets that don’t use a pointer
2019-08-03 12:19:56 -07:00
f181593f49 Add persistence to Airfs
Adds persistence to Airfs; stores the volume in a file.
The interface has changed slightly. Pass...
-N VolumeName ( for example C:\Users\foo\Desktop\test.air )
-n MapName    ( for example Local\Airfs )
... in place of the no longer used...
-n MaxFileNodes
2019-08-03 11:52:47 -07:00
d2f42f4918 update Changelog 2019-07-11 03:17:33 -07:00
a73f1b9559 launcher: path transform language 2019-07-09 13:26:07 -07:00
fb6893968a dll: fuse: add --UserName and --GroupName 2019-07-08 15:12:26 -07:00
c97f2cb660 dotnet: add MountEx and fine-grained timeouts 2019-07-07 12:12:04 -07:00
3a12d928e5 dll: fuse: avoid calling fgetattr on directories 2019-07-01 00:00:37 -07:00
8fa337ae54 sys: fix issues found by static analyzer 2019-06-28 16:19:58 -07:00
7f084787e3 sys: fix issues found by static analyzer 2019-06-28 15:21:36 -07:00
369c0256f3 build: version.properties: update company name 2019-06-25 17:11:01 -07:00
f25983853b tools: build.bat: update cert subject 2019-06-25 17:09:34 -07:00
757e23ded6 ku: kernel-mode testing and fixes 2019-06-24 16:14:03 -07:00
ebb9b8b799 sys: FspVolumeTransact: remove erroneous ASSERT 2019-06-23 11:07:01 -07:00
804bcc3354 sys: FspVolumeTransactFsext:
- only allow ControlCodes with 0xC00 bits set in Function
2019-06-22 15:40:48 -07:00
f5fde4c0bb sys: FspVolumeTransactFsext 2019-06-22 15:18:16 -07:00
dcf7e4c5a6 sys: fsext: FsextProvider testing 2019-06-22 14:30:23 -07:00
adc759447e sys: FspVolumeCreate: fix missing return 2019-06-21 16:37:07 -07:00
f0d7e5b322 Merge pull request #237 from dworkin/feature/async-dotnet
Async I/O for dotnet
2019-06-21 14:48:30 -07:00
bfd8dca62d Delay unmounting until all Slowio tasks are done.
Preventing a crash when unmounting a filesystem with pending Slowio.
2019-06-20 15:49:02 +02:00
79b2f38d87 update README 2019-06-18 21:52:19 -07:00
4ae03629f7 sys: FspFsextProvider: load provider driver 2019-06-18 20:28:59 -07:00
f4496786e5 src: ku: posix.c
- src/ku directory contains shared kernel/user mode code
2019-06-18 16:49:20 -07:00
b637a72ec8 sys: FspFsextProvider 2019-06-18 16:11:38 -07:00
2cd1bddafb sys: FspFsextProvider 2019-06-14 21:22:01 -07:00
6b83748d89 sys: fsext: WIP 2019-06-14 20:53:09 -07:00
ed31a187ac opt/fsext: kernel mode winfsp extension 2019-06-14 18:34:19 -07:00
781deff06f sys: default TransactTimeout changes 2019-06-11 17:53:34 -07:00
3902874ac9 dll: FspFileSystemStartDispatcher
Change default number of threads when ThreadCount==0 is passed.
New min DEFAULT number of threads is 4 and new max DEFAULT number of threads is 16.
The absolute minimum number of threads that any file system dispatcher has remains 2.
2019-06-11 11:51:20 -07:00
8ad77fe62f shared: minimal.h: fix memmove issue in VS 2019 2019-06-06 15:10:25 -07:00
f78b3464ce sys: meta: fix rare memory leak 2019-06-05 20:43:12 -07:00
02fd6906c2 Revert making SeekableReadDirectory virtual.
This would be an API-breaking change that is actually pointless.
Override ReadDirectory instead, as intended.
2019-06-05 09:24:27 +02:00
ce436fc29a Attempt to add a slowio test for memfs-dotnet. 2019-06-04 17:10:33 +02:00
879fa2464f Add asynchronous I/O testing to memfs-dotnet.
Make SeekableReadDirectory virtual, so that it can be overridden.
2019-06-04 15:58:54 +02:00
af7e5432a7 Let the Status argument be a signed integer.
The constants are defined as negative numbers, which would have required
a cast to unsigned for each call.
2019-05-15 14:09:08 +02:00
1d619e0874 Use pointers instead of references.
To avoid copying structs needlessly.
2019-05-14 11:38:55 +02:00
290896b010 Add asyncronous support for dotnet. 2019-05-13 09:47:59 +02:00
c01402443d wslinux support: ATOMIC_CREATE_ECP_CONTEXT 2019-04-27 15:30:57 -07:00
195f3bf92d build: VS2015 - VS2019 round-tripping: LatestTargetPlatformVersion 2019-04-26 09:44:30 -07:00
ae86aeb633 README: WinFsp now builds with VS2015 - VS2019 2019-04-25 17:43:14 -07:00
369da895d3 build: VS2015 - VS2019 round-tripping 2019-04-25 16:43:53 -07:00
17adae481c sys: FspFileNodeOplockCheckAsyncEx: fix stupid mistake in DEBUGTEST code 2019-04-18 23:47:27 -07:00
db34b8c913 update changelog 2019-04-18 20:45:56 -07:00
f6212be687 README: minor fix 2019-04-18 20:38:35 -07:00
7af36d8f78 Merge branch 'master' of https://github.com/billziss-gh/winfsp 2019-04-18 17:46:51 -07:00
f6e49a11c8 .gitignore: add .vs rule 2019-04-18 17:45:11 -07:00
01ca9cef35 README: add info on VS2015 + latest WDK problem 2019-04-18 17:34:02 -07:00
7cb29a4db3 sys: remove unused variables 2019-04-18 17:22:58 -07:00
5523320348 build: fix stampinf cmdline for latest WDK 2019-04-18 17:21:06 -07:00
969651f5f6 sys: improve support for FileStatLxInformation 2019-04-18 15:57:22 -07:00
a08fdccb17 sys: FspSendQueryEaIrp: fix EA related BSOD 2019-04-17 16:04:44 -07:00
859d4250c3 tst: winfsp-tests: wsl: fix WOW64 failure 2019-04-17 15:04:53 -07:00
c6b7b7586e sys: ea: buffers from user mode fs can have zero length 2019-04-17 14:40:06 -07:00
6406246ce2 tools: deploy: fix driver path 2019-04-17 14:39:16 -07:00
9d8ff57be7 Merge branch 'master' into pvt-wsl 2019-04-17 11:28:06 -07:00
2b0d204ff1 sys: FileStatInformation is missing on old WDK's 2019-04-16 21:28:09 -07:00
851d0758d9 sys: define FSP_FILE_STAT*_INFORMATION that are missing on some WDK's 2019-04-16 15:55:13 -07:00
4f444b412e dll: fuse: create_file_mask, create_dir_mask options 2019-04-16 15:16:54 -07:00
e9578b48ce update Changelog 2019-04-16 12:15:32 -07:00
3c3163c41b dll; fuse: rename dot_hidden option to dothidden 2019-04-16 12:11:43 -07:00
8beb534340 dll: fuse: dot_hidden option adds hidden file attribute on dot files 2019-04-15 16:30:00 -07:00
9dcc04f882 tools: update deploy/debug scripts 2019-04-15 15:34:35 -07:00
ce83619728 sys: FileStatLxInformation and friends 2019-04-15 15:04:31 -07:00
04b3675f12 update .gitignore files 2019-04-03 22:39:25 -07:00
6a23f28249 build: bump version number 2019-04-03 22:39:03 -07:00
351b4f5294 sys: fileinfo: fix unnecessary STATUS_BUFFER_TOO_SMALL 2019-04-03 09:52:00 -07:00
218 changed files with 7969 additions and 1796 deletions

View File

@ -1,5 +1,151 @@
= Changelog = Changelog
v1.7B1 (2020.1 B1)::
Changes since v1.6:
* [FIX] Workaround an incompatibility with Avast Antivirus. (GitHub issue #221.)
* [FIX] Fix junction (mount point reparse point) handling. (GitHub issue #269.)
v1.6 (2020)::
Changes since v1.5:
* [FIX] Do no pass `O_APPEND` flag to FUSE file systems, which would result in data corruption under some circumstances. (See PR #272. Thanks @pfrejo.)
* [FIX] Fix how rename target directories are opened (use `FILE_DIRECTORY_FILE`). (See PR #270. Thanks @hammerg.)
v1.5 (2019.3)::
Changes since v1.4:
* [GEN] WinFsp file systems can now be used by WSLinux. File systems must enable this support by setting the `FSP_FSCTL_VOLUME_PARAMS::WslFeatures` bit. Use the command `sudo mount -t drvfs x: /mnt/x` to mount.
* [GEN] Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* [GEN] Mount Manager support has been added and it works for current and new file systems:
** If the file system mountpoint is in the syntax `\\.\X:` then the Mount Manager is used.
** If the file system mountpoint is in the syntax `X:` then `DefineDosDeviceW` is used (i.e. same as today).
** If the file system mountpoint is in the syntax `X:\DIR` then a reparse point is used and the file system is mounted as a directory (i.e. same as today).
** Caveats:
*** It requires Administrator access. This is because opening the `\\.\MountPointManager` device requires Administrator access.
*** It currently works with drives (`\\.\X:`) but not directories (`\\.\X:\DIR`).
*** Mount Manager drives created by WinFsp are transient. WinFsp takes various steps to ensure that this is the case.
*** Mount Manager drives are global and are visible across Terminal Services sessions (they go into the `\GLOBAL??` portion of the NT namespace).
* [FSD] Support for kernel-mode file systems on top of WinFsp has been added. See `FspFsextProvider`. This is in preparation for WinFuse - FUSE for Windows and WSLinux.
* [FSD] FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* [FSD] Support for `FileFsSectorSizeInformation` and `IOCTL_STORAGE_QUERY_PROPERTY / StorageAccessAlignmentProperty` has been added.
* [DLL] The `FspFileSystemStartDispatcher` default number of threads (`ThreadCount==0`) has been changed. See commit 3902874ac93fe40685d9761f46a96358ba24f24c for more.
* [FUSE] FUSE has new `-o UserName=DOMAIN+USERNAME` and `-o GroupName=DOMAIN+GROUPNAME` options. These function like the `-o uid=UID` and `-o gid=GID` options, but accept Windows user and groups names.
* [FUSE] FUSE has new `-o dothidden` option that is used to add the Windows hidden file attribute to files that start with a dot.
* [FUSE] FUSE has new `-o create_file_umask=nnn` and `-o create_dir_umask=nnn` options that allow for more control than the `-o create_umask=nnn` option.
* [FUSE] FUSE has new `--ExactFileSystemName=FSNAME` option that removes the "FUSE-" prefix from the file system name. (Use with caution: see discussion in PR #251.) (Thanks @johntyner.)
* [.NET] The .NET API now supports asynchronous handling of `Read`, `Write` and `ReadDirectory`. (Thanks @dworkin.)
* [.NET] The .NET API now supports fine-grained timeouts (`VolumeInfoTimeout`, `DirInfoTimeout`, etc).
* [.NET] The .NET API has new method `FileSystemHost.MountEx` that adds a `ThreadCount` parameter.
* [LAUNCH] The Launcher can now rewrite path arguments passed to file systems during launching using "Path Transformation Language". See commit a73f1b95592617ac7484e16c2e642573a4d65644 for more.
* [MEMFS] A new memfs FUSE3 file system written in C++ has been added. See `tst/memfs-fuse3`.
* [AIRFS] John Oberschelp has done some fantastic work adding persistence to the airfs file system. (Thanks @JohnOberschelp.)
* [FIX] Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* [FIX] A fix for how FUSE handles the return value from `opendir`. (GitHub issue billziss-gh/sshfs-win#54)
* [FIX] A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* [FIX] A fix on the C++ layer. (Thanks @colatkinson.)
* Other fixes and improvements.
v1.5B4 (2019.3 B4)::
Changes since v1.4:
* [GEN] WinFsp file systems can now be used by WSLinux. File systems must enable this support by setting the `FSP_FSCTL_VOLUME_PARAMS::WslFeatures` bit. Use the command `sudo mount -t drvfs x: /mnt/x` to mount.
* [GEN] Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* [GEN] Mount Manager support has been added and it works for current and new file systems:
** If the file system mountpoint is in the syntax `\\.\X:` then the Mount Manager is used.
** If the file system mountpoint is in the syntax `X:` then `DefineDosDeviceW` is used (i.e. same as today).
** If the file system mountpoint is in the syntax `X:\DIR` then a reparse point is used and the file system is mounted as a directory (i.e. same as today).
** Caveats:
*** It requires Administrator access. This is because opening the `\\.\MountPointManager` device requires Administrator access.
*** It currently works with drives (`\\.\X:`) but not directories (`\\.\X:\DIR`).
*** Mount Manager drives created by WinFsp are transient. WinFsp takes various steps to ensure that this is the case.
*** Mount Manager drives are global and are visible across Terminal Services sessions (they go into the `\GLOBAL??` portion of the NT namespace).
* [FSD] Support for kernel-mode file systems on top of WinFsp has been added. See `FspFsextProvider`. This is in preparation for WinFuse - FUSE for Windows and WSLinux.
* [FSD] FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* [FSD] Support for `FileFsSectorSizeInformation` and `IOCTL_STORAGE_QUERY_PROPERTY / StorageAccessAlignmentProperty` has been added.
* [DLL] The `FspFileSystemStartDispatcher` default number of threads (`ThreadCount==0`) has been changed. See commit 3902874ac93fe40685d9761f46a96358ba24f24c for more.
* [FUSE] FUSE has new `-o UserName=DOMAIN+USERNAME` and `-o GroupName=DOMAIN+GROUPNAME` options. These function like the `-o uid=UID` and `-o gid=GID` options, but accept Windows user and groups names.
* [FUSE] FUSE has new `-o dothidden` option that is used to add the Windows hidden file attribute to files that start with a dot.
* [FUSE] FUSE has new `-o create_file_umask=nnn` and `-o create_dir_umask=nnn` options that allow for more control than the `-o create_umask=nnn` option.
* [FUSE] FUSE has new `--ExactFileSystemName=FSNAME` option that removes the "FUSE-" prefix from the file system name. (Use with caution: see discussion in PR #251.) (Thanks @johntyner.)
* [.NET] The .NET API now supports asynchronous handling of `Read`, `Write` and `ReadDirectory`. (Thanks @dworkin.)
* [.NET] The .NET API now supports fine-grained timeouts (`VolumeInfoTimeout`, `DirInfoTimeout`, etc).
* [.NET] The .NET API has new method `FileSystemHost.MountEx` that adds a `ThreadCount` parameter.
* [LAUNCH] The Launcher can now rewrite path arguments passed to file systems during launching using "Path Transformation Language". See commit a73f1b95592617ac7484e16c2e642573a4d65644 for more.
* [MEMFS] A new memfs FUSE3 file system written in C++ has been added. See `tst/memfs-fuse3`.
* [AIRFS] John Oberschelp has done some fantastic work adding persistence to the airfs file system. (Thanks @JohnOberschelp.)
* [FIX] Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* [FIX] A fix for how FUSE handles the return value from `opendir`. (GitHub issue billziss-gh/sshfs-win#54)
* [FIX] A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* [FIX] A fix on the C++ layer. (Thanks @colatkinson.)
* Other fixes and improvements.
v1.5B3 (2019.3 B3)::
Changes since v1.4:
* [GEN] WinFsp file systems can now be used by WSLinux. Use the command `sudo mount -t drvfs x: /mnt/x` to mount.
* [GEN] Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* [GEN] Mount Manager support has been added and it works for current and new file systems:
** If the file system mountpoint is in the syntax `\\.\X:` then the Mount Manager is used.
** If the file system mountpoint is in the syntax `X:` then `DefineDosDeviceW` is used (i.e. same as today).
** If the file system mountpoint is in the syntax `X:\DIR` then a reparse point is used and the file system is mounted as a directory (i.e. same as today).
** Caveats:
*** It requires Administrator access. This is because opening the `\\.\MountPointManager` device requires Administrator access.
*** It currently works with drives (`\\.\X:`) but not directories (`\\.\X:\DIR`).
*** Mount Manager drives created by WinFsp are transient. WinFsp takes various steps to ensure that this is the case.
*** Mount Manager drives are global and are visible across Terminal Services sessions (they go into the `\GLOBAL??` portion of the NT namespace).
* [FSD] Support for kernel-mode file systems on top of WinFsp has been added. See `FspFsextProvider`. This is in preparation for WinFuse - FUSE for Windows and WSLinux.
* [FSD] FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* [FSD] Support for `FileFsSectorSizeInformation` and `IOCTL_STORAGE_QUERY_PROPERTY / StorageAccessAlignmentProperty` has been added.
* [DLL] The `FspFileSystemStartDispatcher` default number of threads (`ThreadCount==0`) has been changed. See commit 3902874ac93fe40685d9761f46a96358ba24f24c for more.
* [FUSE] FUSE has new `-o UserName=DOMAIN+USERNAME` and `-o GroupName=DOMAIN+GROUPNAME` options. These function like the `-o uid=UID` and `-o gid=GID` options, but accept Windows user and groups names.
* [FUSE] FUSE has new `-o dothidden` option that is used to add the Windows hidden file attribute to files that start with a dot.
* [FUSE] FUSE has new `-o create_file_umask=nnn` and `-o create_dir_umask=nnn` options that allow for more control than the `-o create_umask=nnn` option.
* [FUSE] FUSE has new `--ExactFileSystemName=FSNAME` option that removes the "FUSE-" prefix from the file system name. (Use with caution: see discussion in PR #251.) (Thanks @johntyner.)
* [.NET] The .NET API now supports asynchronous handling of `Read`, `Write` and `ReadDirectory`. (Thanks @dworkin.)
* [.NET] The .NET API now supports fine-grained timeouts (`VolumeInfoTimeout`, `DirInfoTimeout`, etc).
* [.NET] The .NET API has new method `FileSystemHost.MountEx` that adds a `ThreadCount` parameter.
* [LAUNCH] The Launcher can now rewrite path arguments passed to file systems during launching using "Path Transformation Language". See commit a73f1b95592617ac7484e16c2e642573a4d65644 for more.
* [MEMFS] A new memfs FUSE3 file system written in C++ has been added. See `tst/memfs-fuse3`.
* [AIRFS] John Oberschelp has done some fantastic work adding persistence to the airfs file system. (Thanks @JohnOberschelp.)
* [FIX] Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* [FIX] A fix for how FUSE handles the return value from `opendir`. (GitHub issue billziss-gh/sshfs-win#54)
* [FIX] A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* [FIX] A fix on the C++ layer. (Thanks @colatkinson.)
* Other fixes and improvements.
v1.5B2 (2019.3 B2)::
Changes since v1.4:
* [GEN] WinFsp file systems can now be used by WSLinux. Use the command `sudo mount -t drvfs x: /mnt/x` to mount.
* [GEN] Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* [FSD] Support for kernel-mode file systems on top of WinFsp has been added. See `FspFsextProvider`. This is in preparation for WinFuse - FUSE for Windows and WSLinux.
* [FSD] FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* [DLL] The `FspFileSystemStartDispatcher` default number of threads (`ThreadCount==0`) has been changed. See commit 3902874ac93fe40685d9761f46a96358ba24f24c for more.
* [FUSE] FUSE has new `-o UserName=DOMAIN\USERNAME` and `-o GroupName=DOMAIN\GROUPNAME` options. These function like the `-o uid=UID` and `-o gid=GID` options, but accept Windows user and groups names.
* [FUSE] FUSE has new `-o dothidden` option that is used to add the Windows hidden file attribute to files that start with a dot.
* [FUSE] FUSE has new `-o create_file_umask=nnn` and `-o create_dir_umask=nnn` options that allow for more control than the `-o create_umask=nnn` option.
* [.NET] The .NET API now supports asynchronous handling of `Read`, `Write` and `ReadDirectory`. (Thanks @dworkin.)
* [.NET] The .NET API now supports fine-grained timeouts (`VolumeInfoTimeout`, `DirInfoTimeout`, etc).
* [.NET] The .NET API has new method `FileSystemHost.MountEx` that adds a `ThreadCount` parameter.
* [LAUNCH] The Launcher can now rewrite path arguments passed to file systems during launching using "Path Transformation Language". See commit a73f1b95592617ac7484e16c2e642573a4d65644 for more.
* [FIX] Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* [FIX] A fix for how FUSE handles the return value from `opendir`. (GitHub issue billziss-gh/sshfs-win#54)
* [FIX] A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* [FIX] A fix on the C++ layer. (Thanks @colatkinson.)
* Other fixes and improvements.
v1.5B1 (2019.3 B1):: v1.5B1 (2019.3 B1)::
@ -11,6 +157,7 @@ Changes since v1.4:
* A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.) * A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* A fix on the C++ layer. (Thanks @colatkinson.) * A fix on the C++ layer. (Thanks @colatkinson.)
v1.4.19049 (2019.2):: v1.4.19049 (2019.2)::
Changes since v1.3: Changes since v1.3:

View File

@ -56,11 +56,15 @@ CONTRIBUTOR LIST
|=== |===
|Ben Rubson |ben.rubson at gmail.com |Ben Rubson |ben.rubson at gmail.com
|Bill Zissimopoulos |billziss at navimatics.com |Bill Zissimopoulos |billziss at navimatics.com
|Brett Dutro |brett.dutro at gmail.com
|Colin Atkinson (Atakama, https://atakama.com) |colin at atakama.com |Colin Atkinson (Atakama, https://atakama.com) |colin at atakama.com
|Felix Croes |felix at dworkin.nl |Felix Croes |felix at dworkin.nl
|Francois Karam (KS2, http://www.ks2.fr) |francois.karam at ks2.fr |Francois Karam (KS2, http://www.ks2.fr) |francois.karam at ks2.fr
|Fritz Elfert |fritz-github at fritz-elfert.de |Fritz Elfert |fritz-github at fritz-elfert.de
|Gal Hammer (Red Hat, https://www.redhat.com) |ghammer at redhat.com
|John Oberschelp |john at oberschelp.net |John Oberschelp |john at oberschelp.net
|John Tyner |jtyner at gmail.com
|Pedro Frejo (Arpa System, https://arpasystem.com) |pedro.frejo at arpasystem.com
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com |Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|Santiago Ganis |sganis at gmail.com |Santiago Ganis |sganis at gmail.com
|Tobias Urlaub |saibotu at outlook.de |Tobias Urlaub |saibotu at outlook.de

View File

@ -96,6 +96,7 @@ The project source code is organized as follows:
* :file_folder: [src/dll/fuse3](src/dll/fuse3): Source code to the FUSE3 compatibility layer. * :file_folder: [src/dll/fuse3](src/dll/fuse3): Source code to the FUSE3 compatibility layer.
* :file_folder: [src/dotnet](src/dotnet): Source code to the .NET layer. * :file_folder: [src/dotnet](src/dotnet): Source code to the .NET layer.
* :file_folder: [src/fsptool](src/fsptool): Source code to fsptool command line utility. * :file_folder: [src/fsptool](src/fsptool): Source code to fsptool command line utility.
* :file_folder: [src/ku](src/ku): Source code that can be used from kernel or user mode.
* :file_folder: [src/launcher](src/launcher): Source code to the launcher service and the launchctl utility. * :file_folder: [src/launcher](src/launcher): Source code to the launcher service and the launchctl utility.
* :file_folder: [src/sys](src/sys): Source code to the WinFsp FSD. * :file_folder: [src/sys](src/sys): Source code to the WinFsp FSD.
* :file_folder: [opt/cygfuse](opt/cygfuse): Source code to the FUSE for Cygwin package. * :file_folder: [opt/cygfuse](opt/cygfuse): Source code to the FUSE for Cygwin package.
@ -107,8 +108,12 @@ The project source code is organized as follows:
In order to build WinFsp you will need the following: In order to build WinFsp you will need the following:
* Visual Studio 2015 * Visual Studio 2015 - 2019
* Windows Driver Kit (WDK) 10 * Windows Driver Kit (WDK) 10
- **NOTE**: When using the latest WDK (Windows 10.0.18362.1) with Visual Studio 2015 you may get an error about a missing task `ValidateNTTargetVersion`. The fix is to edit the file `\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets` and modify the `UsingTask` line for `ValidateNTTargetVersion` as follows:
```
<UsingTask TaskName="ValidateNTTargetVersion" AssemblyFile="$(WDKContentRoot)build\bin\Microsoft.DriverKit.Build.Tasks.16.0.dll"/>
```
* [Wix toolset](http://wixtoolset.org) * [Wix toolset](http://wixtoolset.org)
To fully build WinFsp (including the installer) you must use `tools\build.bat`. By default it builds a Release build, but you can choose either the Debug or Release configuration by using the syntax: To fully build WinFsp (including the installer) you must use `tools\build.bat`. By default it builds a Release build, but you can choose either the Debug or Release configuration by using the syntax:

View File

@ -15,6 +15,13 @@ init:
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) #- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
install: install:
- ps: |
# Hack to make WDK 1903 work on VS2015.
# See https://github.com/appveyor-tests/WDK-10.0.14393.0/blob/31cf12217fe0c92b218c70d7027dfe145be4f4cb/appveyor.yml#L7
[xml]$targets = get-content "C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets"
$usingTask = $targets.ChildNodes[1].UsingTask | ? {$_.TaskName -eq "ValidateNTTargetVersion"}
$usingTask.AssemblyFile = '$(WDKContentRoot)build\bin\Microsoft.DriverKit.Build.Tasks.16.0.dll'
$targets.Save("C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets")
- git submodule update --init --recursive - git submodule update --init --recursive
- appveyor AddMessage "Change boot configuration and reboot" -Category Information - appveyor AddMessage "Change boot configuration and reboot" -Category Information
- bcdedit /set testsigning on - bcdedit /set testsigning on

View File

@ -4,3 +4,6 @@ build
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.csproj.user *.csproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -1,7 +1,7 @@
/** /**
* @file CustomActions.cpp * @file CustomActions.cpp
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -14,18 +15,18 @@
<ProjectGuid>{95C223E6-B5F1-4FD0-9376-41CDBC824445}</ProjectGuid> <ProjectGuid>{95C223E6-B5F1-4FD0-9376-41CDBC824445}</ProjectGuid>
<RootNamespace>CustomActions</RootNamespace> <RootNamespace>CustomActions</RootNamespace>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -68,7 +69,6 @@
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile> <ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
@ -92,7 +92,6 @@
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile> <ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>

View File

@ -369,6 +369,23 @@
<File Name="uninstall.sh" KeyPath="yes" /> <File Name="uninstall.sh" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="OPTDIR.fsext" Name="fsext" FileSource="..\..\..\opt\fsext">
<Directory Id="OPTDIR.fsext.inc" Name="inc">
<Directory Id="OPTDIR.fsext.inc.winfsp" Name="winfsp">
<Component Id="C.fsext.h">
<File Name="fsext.h" KeyPath="yes" />
</Component>
</Directory>
</Directory>
<Directory Id="OPTDIR.fsext.lib" Name="lib">
<Component Id="C.fsext.winfsp_x64.lib">
<File Id="FILE.fsext.winfsp_x64.lib" Name="winfsp-x64.lib" KeyPath="yes" />
</Component>
<Component Id="C.fsext.winfsp_x86.lib">
<File Id="FILE.fsext.winfsp_x86.lib" Name="winfsp-x86.lib" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</DirectoryRef> </DirectoryRef>
<DirectoryRef Id="SMPDIR" FileSource="..\..\..\tst"> <DirectoryRef Id="SMPDIR" FileSource="..\..\..\tst">
<Directory Id="SMPDIR.memfs" Name="memfs"> <Directory Id="SMPDIR.memfs" Name="memfs">
@ -382,6 +399,29 @@
<File Name="memfs-main.c" KeyPath="yes" /> <File Name="memfs-main.c" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="SMPDIR.memfs_fuse3" Name="memfs-fuse3">
<Component Id="C.memfs_fuse3.cpp">
<File Name="memfs-fuse3.cpp" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.compat.h">
<File Id="F.memfs_fuse3.compat.h" Name="compat.h" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.sln">
<File Name="memfs-fuse3.sln" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.vcxproj">
<File Name="memfs-fuse3.vcxproj" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.vcxproj.filters">
<File Name="memfs-fuse3.vcxproj.filters" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.Makefile">
<File Id="F.memfs_fuse3.Makefile" Name="Makefile" KeyPath="yes" />
</Component>
<Component Id="C.memfs_fuse3.README.md">
<File Id="F.memfsx_fuse3.README.md" Name="README.md" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="SMPDIR.memfs_dotnet" Name="memfs-dotnet"> <Directory Id="SMPDIR.memfs_dotnet" Name="memfs-dotnet">
<Component Id="C.memfs_dotnet.Program.cs"> <Component Id="C.memfs_dotnet.Program.cs">
<File Id="FILE.memfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" /> <File Id="FILE.memfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
@ -391,6 +431,12 @@
<Component Id="C.airfs.cpp"> <Component Id="C.airfs.cpp">
<File Name="airfs.cpp" KeyPath="yes" /> <File Name="airfs.cpp" KeyPath="yes" />
</Component> </Component>
<Component Id="C.persistence.cpp">
<File Name="persistence.cpp" KeyPath="yes" />
</Component>
<Component Id="C.common.h">
<File Name="common.h" KeyPath="yes" />
</Component>
<Component Id="C.airfs.sln"> <Component Id="C.airfs.sln">
<File Name="airfs.sln" KeyPath="yes" /> <File Name="airfs.sln" KeyPath="yes" />
</Component> </Component>
@ -580,13 +626,27 @@
<ComponentRef Id="C.fuse.install.sh" /> <ComponentRef Id="C.fuse.install.sh" />
<ComponentRef Id="C.fuse.uninstall.sh" /> <ComponentRef Id="C.fuse.uninstall.sh" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.opt.fsext">
<ComponentRef Id="C.fsext.h" />
<ComponentRef Id="C.fsext.winfsp_x64.lib" />
<ComponentRef Id="C.fsext.winfsp_x86.lib" />
</ComponentGroup>
<ComponentGroup Id="C.WinFsp.smp"> <ComponentGroup Id="C.WinFsp.smp">
<ComponentRef Id="C.memfs_x64.exe" /> <ComponentRef Id="C.memfs_x64.exe" />
<ComponentRef Id="C.memfs_x86.exe" /> <ComponentRef Id="C.memfs_x86.exe" />
<ComponentRef Id="C.memfs.h" /> <ComponentRef Id="C.memfs.h" />
<ComponentRef Id="C.memfs.cpp" /> <ComponentRef Id="C.memfs.cpp" />
<ComponentRef Id="C.memfs_main.c" /> <ComponentRef Id="C.memfs_main.c" />
<ComponentRef Id="C.memfs_fuse3.cpp" />
<ComponentRef Id="C.memfs_fuse3.compat.h" />
<ComponentRef Id="C.memfs_fuse3.sln" />
<ComponentRef Id="C.memfs_fuse3.vcxproj" />
<ComponentRef Id="C.memfs_fuse3.vcxproj.filters" />
<ComponentRef Id="C.memfs_fuse3.Makefile" />
<ComponentRef Id="C.memfs_fuse3.README.md" />
<ComponentRef Id="C.airfs.cpp" /> <ComponentRef Id="C.airfs.cpp" />
<ComponentRef Id="C.persistence.cpp" />
<ComponentRef Id="C.common.h" />
<ComponentRef Id="C.airfs.sln" /> <ComponentRef Id="C.airfs.sln" />
<ComponentRef Id="C.airfs.vcxproj" /> <ComponentRef Id="C.airfs.vcxproj" />
<ComponentRef Id="C.airfs.vcxproj.filters" /> <ComponentRef Id="C.airfs.vcxproj.filters" />
@ -694,6 +754,16 @@
<ComponentGroupRef Id="C.WinFsp.smp.net" /> <ComponentGroupRef Id="C.WinFsp.smp.net" />
<ComponentGroupRef Id="C.WinFsp.sym" /> <ComponentGroupRef Id="C.WinFsp.sym" />
</Feature> </Feature>
<Feature
Id="F.KernelDeveloper"
Level="1000"
Title="Kernel Developer"
Description="Additional files needed for in-kernel development."
AllowAdvertise="no"
InstallDefault="local"
Absent="allow">
<ComponentGroupRef Id="C.WinFsp.opt.fsext" />
</Feature>
<Feature <Feature
Id="F.Cygfuse" Id="F.Cygfuse"
Level="1000" Level="1000"
@ -750,4 +820,4 @@
</ScheduleReboot> </ScheduleReboot>
</InstallExecuteSequence> </InstallExecuteSequence>
</Product> </Product>
</Wix> </Wix>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}</ProjectGuid> <ProjectGuid>{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fsbench</RootNamespace> <RootNamespace>fsbench</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -122,7 +122,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -142,7 +141,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -162,7 +160,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{10757011-749D-4954-873B-AE38D8145472}</ProjectGuid> <ProjectGuid>{10757011-749D-4954-873B-AE38D8145472}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fscrash</RootNamespace> <RootNamespace>fscrash</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -122,7 +122,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -142,7 +141,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -162,7 +160,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,33 +23,33 @@
<ProjectGuid>{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}</ProjectGuid> <ProjectGuid>{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>memfs</RootNamespace> <RootNamespace>memfs</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<ProjectName>memfs</ProjectName> <ProjectName>memfs</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -100,14 +101,13 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>MEMFS_STANDALONE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -117,14 +117,13 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>MEMFS_STANDALONE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -136,14 +135,13 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>MEMFS_STANDALONE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -157,14 +155,13 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>MEMFS_STANDALONE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{262DF8CC-E7A8-4460-A22C-683CBA322C32}</ProjectGuid> <ProjectGuid>{262DF8CC-E7A8-4460-A22C-683CBA322C32}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>winfsptests</RootNamespace> <RootNamespace>winfsptests</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -123,7 +123,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -142,7 +141,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -163,7 +161,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -194,6 +191,7 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\launcher-ptrans-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\lock-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\lock-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\memfs-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\memfs-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" />
@ -206,8 +204,11 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\uuid5-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\volpath-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\wsl-test.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\ext\tlib\testsuite.h" /> <ClInclude Include="..\..\..\ext\tlib\testsuite.h" />

View File

@ -97,6 +97,18 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\ea-test.c"> <ClCompile Include="..\..\..\tst\winfsp-tests\ea-test.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\wsl-test.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\launcher-ptrans-test.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\volpath-test.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\uuid5-test.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\ext\tlib\testsuite.h"> <ClInclude Include="..\..\..\ext\tlib\testsuite.h">

View File

@ -23,32 +23,32 @@
<ProjectGuid>{1E997BEC-1642-4A5C-B252-852DA094E11E}</ProjectGuid> <ProjectGuid>{1E997BEC-1642-4A5C-B252-852DA094E11E}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fsptool</RootNamespace> <RootNamespace>fsptool</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -108,7 +108,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -127,7 +126,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -149,7 +147,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -171,7 +168,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>

View File

@ -23,32 +23,32 @@
<ProjectGuid>{264A5D09-126F-4760-A3F1-4B3B95C925AA}</ProjectGuid> <ProjectGuid>{264A5D09-126F-4760-A3F1-4B3B95C925AA}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>launchctl</RootNamespace> <RootNamespace>launchctl</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -110,7 +110,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -131,7 +130,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -155,7 +153,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -179,7 +176,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>

View File

@ -23,32 +23,32 @@
<ProjectGuid>{6CDF9411-B852-4EAC-822D-8F930675F17B}</ProjectGuid> <ProjectGuid>{6CDF9411-B852-4EAC-822D-8F930675F17B}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>launcher</RootNamespace> <RootNamespace>launcher</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -110,7 +110,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -132,7 +131,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -157,7 +155,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -182,7 +179,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -190,6 +186,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\src\launcher\launcher.c" /> <ClCompile Include="..\..\..\src\launcher\launcher.c" />
<ClCompile Include="..\..\..\src\launcher\ptrans.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\winfsp_dll.vcxproj"> <ProjectReference Include="..\winfsp_dll.vcxproj">

View File

@ -16,6 +16,9 @@
<ClCompile Include="..\..\..\src\launcher\launcher.c"> <ClCompile Include="..\..\..\src\launcher\launcher.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\launcher\ptrans.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\shared\minimal.h"> <ClInclude Include="..\..\..\src\shared\minimal.h">

View File

@ -13,12 +13,12 @@
<MyProductName>WinFsp</MyProductName> <MyProductName>WinFsp</MyProductName>
<MyDescription>Windows File System Proxy</MyDescription> <MyDescription>Windows File System Proxy</MyDescription>
<MyCompanyName>Navimatics Corporation</MyCompanyName> <MyCompanyName>Navimatics LLC</MyCompanyName>
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright> <MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
<MyCanonicalVersion>1.5</MyCanonicalVersion> <MyCanonicalVersion>1.7</MyCanonicalVersion>
<MyProductVersion>2019.3 B1</MyProductVersion> <MyProductVersion>2020.1 B1</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
@ -37,4 +37,17 @@
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions> <PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(DefaultPlatformToolset)'=='v140'">
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(DefaultPlatformToolset)'!='v140'">
<Link>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
</Project> </Project>

View File

@ -35,6 +35,7 @@
<ClInclude Include="..\..\src\dll\fuse3\library.h" /> <ClInclude Include="..\..\src\dll\fuse3\library.h" />
<ClInclude Include="..\..\src\dll\fuse\library.h" /> <ClInclude Include="..\..\src\dll\fuse\library.h" />
<ClInclude Include="..\..\src\dll\library.h" /> <ClInclude Include="..\..\src\dll\library.h" />
<ClInclude Include="..\..\src\ku\library.h" />
<ClInclude Include="..\..\src\shared\minimal.h" /> <ClInclude Include="..\..\src\shared\minimal.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -50,8 +51,8 @@
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_main.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" />
<ClCompile Include="..\..\src\dll\launch.c" /> <ClCompile Include="..\..\src\dll\launch.c" />
<ClCompile Include="..\..\src\dll\mount.c" />
<ClCompile Include="..\..\src\dll\np.c" /> <ClCompile Include="..\..\src\dll\np.c" />
<ClCompile Include="..\..\src\dll\posix.c" />
<ClCompile Include="..\..\src\dll\security.c" /> <ClCompile Include="..\..\src\dll\security.c" />
<ClCompile Include="..\..\src\dll\debug.c" /> <ClCompile Include="..\..\src\dll\debug.c" />
<ClCompile Include="..\..\src\dll\fsctl.c" /> <ClCompile Include="..\..\src\dll\fsctl.c" />
@ -63,6 +64,7 @@
<ClCompile Include="..\..\src\dll\service.c" /> <ClCompile Include="..\..\src\dll\service.c" />
<ClCompile Include="..\..\src\dll\util.c" /> <ClCompile Include="..\..\src\dll\util.c" />
<ClCompile Include="..\..\src\dll\wksid.c" /> <ClCompile Include="..\..\src\dll\wksid.c" />
<ClCompile Include="..\..\src\ku\posix.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in"> <CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
@ -126,33 +128,33 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<ProjectGuid>{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}</ProjectGuid> <ProjectGuid>{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>winfspdll</RootNamespace> <RootNamespace>winfspdll</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<ProjectName>winfsp.dll</ProjectName> <ProjectName>winfsp.dll</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -216,7 +218,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -244,7 +245,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -273,7 +273,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
@ -304,7 +303,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>

View File

@ -27,6 +27,9 @@
<Filter Include="Source\fuse3"> <Filter Include="Source\fuse3">
<UniqueIdentifier>{96091a7b-3923-4a74-9491-3ee230c688f9}</UniqueIdentifier> <UniqueIdentifier>{96091a7b-3923-4a74-9491-3ee230c688f9}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source\ku">
<UniqueIdentifier>{613cce77-2428-4f9a-9187-f37e009253c1}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">
@ -77,6 +80,9 @@
<ClInclude Include="..\..\src\dll\fuse3\library.h"> <ClInclude Include="..\..\src\dll\fuse3\library.h">
<Filter>Source\fuse3</Filter> <Filter>Source\fuse3</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ku\library.h">
<Filter>Source\ku</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\dll\library.c"> <ClCompile Include="..\..\src\dll\library.c">
@ -124,9 +130,6 @@
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c"> <ClCompile Include="..\..\src\dll\fuse\fuse_main.c">
<Filter>Source\fuse</Filter> <Filter>Source\fuse</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\posix.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\fuse\fuse_intf.c"> <ClCompile Include="..\..\src\dll\fuse\fuse_intf.c">
<Filter>Source\fuse</Filter> <Filter>Source\fuse</Filter>
</ClCompile> </ClCompile>
@ -154,6 +157,12 @@
<ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c"> <ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c">
<Filter>Source\fuse3</Filter> <Filter>Source\fuse3</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ku\posix.c">
<Filter>Source\ku</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\mount.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\src\dll\library.def"> <None Include="..\..\src\dll\library.def">

View File

@ -101,11 +101,11 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>cng.lib;wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -114,11 +114,11 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>cng.lib;wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -127,11 +127,11 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>cng.lib;wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -140,11 +140,11 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>cng.lib;wdmsec.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -155,6 +155,8 @@
<FilesToPackage Include="$(TargetPath)" /> <FilesToPackage Include="$(TargetPath)" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\ku\posix.c" />
<ClCompile Include="..\..\src\ku\uuid5.c" />
<ClCompile Include="..\..\src\sys\cleanup.c" /> <ClCompile Include="..\..\src\sys\cleanup.c" />
<ClCompile Include="..\..\src\sys\close.c" /> <ClCompile Include="..\..\src\sys\close.c" />
<ClCompile Include="..\..\src\sys\create.c" /> <ClCompile Include="..\..\src\sys\create.c" />
@ -169,10 +171,12 @@
<ClCompile Include="..\..\src\sys\fileinfo.c" /> <ClCompile Include="..\..\src\sys\fileinfo.c" />
<ClCompile Include="..\..\src\sys\flush.c" /> <ClCompile Include="..\..\src\sys\flush.c" />
<ClCompile Include="..\..\src\sys\fsctl.c" /> <ClCompile Include="..\..\src\sys\fsctl.c" />
<ClCompile Include="..\..\src\sys\fsext.c" />
<ClCompile Include="..\..\src\sys\iop.c" /> <ClCompile Include="..\..\src\sys\iop.c" />
<ClCompile Include="..\..\src\sys\ioq.c" /> <ClCompile Include="..\..\src\sys\ioq.c" />
<ClCompile Include="..\..\src\sys\lockctl.c" /> <ClCompile Include="..\..\src\sys\lockctl.c" />
<ClCompile Include="..\..\src\sys\meta.c" /> <ClCompile Include="..\..\src\sys\meta.c" />
<ClCompile Include="..\..\src\sys\mountdev.c" />
<ClCompile Include="..\..\src\sys\mup.c" /> <ClCompile Include="..\..\src\sys\mup.c" />
<ClCompile Include="..\..\src\sys\name.c" /> <ClCompile Include="..\..\src\sys\name.c" />
<ClCompile Include="..\..\src\sys\psbuffer.c" /> <ClCompile Include="..\..\src\sys\psbuffer.c" />
@ -188,6 +192,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h" /> <ClInclude Include="..\..\inc\winfsp\fsctl.h" />
<ClInclude Include="..\..\opt\fsext\inc\winfsp\fsext.h" />
<ClInclude Include="..\..\src\ku\library.h" />
<ClInclude Include="..\..\src\sys\driver.h" /> <ClInclude Include="..\..\src\sys\driver.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -212,7 +218,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -225,7 +231,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -238,7 +244,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -251,7 +257,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing driver-$(PlatformTarget).inf</Message> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing driver-$(PlatformTarget).inf</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>

View File

@ -12,6 +12,9 @@
<Filter Include="Include\winfsp"> <Filter Include="Include\winfsp">
<UniqueIdentifier>{904f0df1-2fb8-4f84-aa46-fa929488c39a}</UniqueIdentifier> <UniqueIdentifier>{904f0df1-2fb8-4f84-aa46-fa929488c39a}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source\ku">
<UniqueIdentifier>{235076b8-290c-4dec-b005-71d9b8e8cba7}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\sys\driver.c"> <ClCompile Include="..\..\src\sys\driver.c">
@ -104,6 +107,18 @@
<ClCompile Include="..\..\src\sys\mup.c"> <ClCompile Include="..\..\src\sys\mup.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\sys\fsext.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ku\posix.c">
<Filter>Source\ku</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ku\uuid5.c">
<Filter>Source\ku</Filter>
</ClCompile>
<ClCompile Include="..\..\src\sys\mountdev.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h"> <ClInclude Include="..\..\src\sys\driver.h">
@ -112,6 +127,12 @@
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">
<Filter>Include\winfsp</Filter> <Filter>Include\winfsp</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\opt\fsext\inc\winfsp\fsext.h">
<Filter>Include\winfsp</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ku\library.h">
<Filter>Source\ku</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\src\sys\version.rc"> <ResourceCompile Include="..\..\src\sys\version.rc">

View File

@ -18,10 +18,6 @@ Disconnecting (unmapping) a network drive does not work.::
Case-sensitive file systems do not work properly when mounted as a directory.:: Case-sensitive file systems do not work properly when mounted as a directory.::
This is fixed as of WinFsp 2018.2 B3. This is fixed as of WinFsp 2018.2 B3.
+
Windows and WinFsp support case-sensitive file systems. These file systems work properly when mounted as a drive. Unfortunately when a file system is mounted as a directory over NTFS, Windows expects it to be case-insensitive and will UPPERCASE many of the file names sent to the file system.
+
This is an unfortunate but well understood Windows limitation. Case-sensitive file systems should only be mounted as drives.
Why is the DLL not installed in the Windows system directories?:: Why is the DLL not installed in the Windows system directories?::
@ -68,5 +64,10 @@ With this in mind here are the reasons for the current WinFsp-FUSE behavior:
WinFsp-FUSE does not have the ability to support multiple file systems from within the same process. Why?:: WinFsp-FUSE does not have the ability to support multiple file systems from within the same process. Why?::
This is supported as of WinFsp 2018.2 B2. This is supported as of WinFsp 2018.2 B2.
I have problems getting permissions to work properly in a WinFsp-FUSE file system. Can you help?::
The WinFsp-FUSE layer includes a built-in command line option that can help: `-o uid=-1`. This instructs the WinFsp-FUSE layer to present all file system files as if they are owned by the user that launched the file system.
+ +
The core WinFsp layer always supported multiple file systems in the same process either simultaneously or one after another. However this was not the case with WinFsp-FUSE (i.e. the FUSE layer of WinFsp) prior to version 2018.2 B2. This limitation has been rectified as of WinFsp 2018.2 B2. Alternatives include `-o uid=-1,gid=-1`, which presents files as owned by the user *and* group that launched the file system and `-o uid=-1,gid=11`, which presents files as owned by the user that launched the file system and the group "Authenticated Users". (The `fsptool` utility in the `bin` subdirectory of the WinFsp installation directory can be used to convert Windows accounts/SID's to UID's and vice versa.)

View File

@ -12,6 +12,7 @@ The documentation available here discusses various aspects of WinFsp.
- The [[API Reference|WinFsp-API-winfsp.h]] describes the native WinFsp API. This external [[link|http://www.secfs.net/winfsp/apiref/]] may be easier to browse for some people. - The [[API Reference|WinFsp-API-winfsp.h]] describes the native WinFsp API. This external [[link|http://www.secfs.net/winfsp/apiref/]] may be easier to browse for some people.
- There is also a FUSE compatibility layer for native Windows and Cygwin. See fuse.h in the source repository. - There is also a FUSE compatibility layer for native Windows and Cygwin. See fuse.h in the source repository.
- This [[document|Native-API-vs-FUSE]] discusses the need for both a native API and FUSE and gives some pointers on which one to choose. - This [[document|Native-API-vs-FUSE]] discusses the need for both a native API and FUSE and gives some pointers on which one to choose.
- Since release 2019.3 WinFsp supports development of file systems in kernel mode. This [[document|WinFsp-Kernel-Mode-File-Systems]] discusses how to write such file systems.
## Design ## Design

View File

@ -5,6 +5,7 @@ This document contains a list of known file systems and file system libraries th
== File Systems == File Systems
- https://github.com/vgough/encfs[EncFS] - an Encrypted Filesystem for FUSE - https://github.com/vgough/encfs[EncFS] - an Encrypted Filesystem for FUSE
- https://github.com/lowleveldesign/fsmemfs[fsmemfs] - Memory File System written in F#
- https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files - https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files
- https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive - https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows - https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
@ -13,6 +14,7 @@ This document contains a list of known file systems and file system libraries th
- https://github.com/billziss-gh/redditfs[redditfs] - ls -l /r/programming - https://github.com/billziss-gh/redditfs[redditfs] - ls -l /r/programming
- https://github.com/netheril96/securefs[securefs] - Filesystem in userspace (FUSE) with transparent authenticated encryption - https://github.com/netheril96/securefs[securefs] - Filesystem in userspace (FUSE) with transparent authenticated encryption
- https://github.com/billziss-gh/sshfs-win[sshfs-win] - SSHFS for Windows - https://github.com/billziss-gh/sshfs-win[sshfs-win] - SSHFS for Windows
- https://github.com/UtrechtUniversity/YodaDrive[YodaDrive] - Mount a Yoda drive as a local drive
== File System Libraries == File System Libraries
@ -20,3 +22,4 @@ This document contains a list of known file systems and file system libraries th
- https://github.com/DuroSoft/fuse-bindings[Nodejs: fuse-bindings] - Fully maintained FUSE bindings for Node that aims to cover the entire FUSE api - https://github.com/DuroSoft/fuse-bindings[Nodejs: fuse-bindings] - Fully maintained FUSE bindings for Node that aims to cover the entire FUSE api
- https://github.com/SerCeMan/jnr-fuse[Java: jnr-fuse] - FUSE implementation in Java using Java Native Runtime (JNR) - https://github.com/SerCeMan/jnr-fuse[Java: jnr-fuse] - FUSE implementation in Java using Java Native Runtime (JNR)
- https://github.com/billziss-gh/fusepy[Python: fusepy] - Simple ctypes bindings for FUSE - https://github.com/billziss-gh/fusepy[Python: fusepy] - Simple ctypes bindings for FUSE
- https://github.com/Scille/winfspy[Python: winfspy] - WinFSP binding for Python

View File

@ -0,0 +1,117 @@
= Developing File Systems in Kernel Mode
Since release 2019.3 WinFsp supports development of file systems in kernel mode. Such file systems are implemented as kernel drivers that use WinFsp as the primary FSD (File System Driver) as well as the software library that they interface with to retrieve and service file system requests. This document discusses how to write such file systems.
== Motivation
The primary goal of WinFsp is to enable the easy creation of *user mode* file systems using an easy to use API. There are however legitimate reasons for wanting to develop a file system as a *kernel mode* driver, but the difficulty of doing so often deters people because Windows kernel file system development is notoriously difficult and has many pitfalls.
Some of the reasons that a kernel mode file system may be preferrable to a user mode one:
* A kernel driver may be able to achieve better performance than user mode processes.
* A kernel driver may be able to access advanced OS features that are not easily available to user mode processes.
* A kernel driver may be able to present an alternative interface than the one presented by WinFsp to user mode processes.
Since release 2019.3 WinFsp supports development of file systems as kernel mode drivers. The primary motivation for this work was to support the https://github.com/billziss-gh/winfuse[WinFuse] project, which exposes the FUSE protocol from the Windows kernel in a way that allows FUSE file systems to interface with it, either directly or via https://github.com/libfuse/libfuse[libfuse]. The support was added in such a way that it is generic enough to be used by other kernel mode file systems.
== Overview
A WinFsp "volume" (file system) is typically created using the `FspFsctlCreateVolume` API. This is simply a wrapper around a `CreateFileW` call on one of the WinFsp control devices, either `WinFsp.Disk` or `WinFsp.Net`. The `CreateFileW` call returns a `HANDLE` to the newly created volume, which acts either as a "disk" or a "network" file system, depending on which control device was used to create it.
User mode file systems interact with the WinFsp FSD via `DeviceIoControl/FSP_FSCTL_TRANSACT` messages on the volume `HANDLE`. (This is usually done indirectly via the WinFsp DLL, which hides this detail behind an easy to use API.)
Since release 2019.3 (v1.5) WinFsp supports the following:
* Registration and on-demand loading of a third party driver when a volume that is destined to be handled by the third party driver is created.
* Forwarding of custom `DeviceIoControl` messages to a third party driver. This allows the third party driver to handle custom `FSCTL` requests directed to a WinFsp volume `HANDLE`.
* Kernel-mode API's (called DDI's) that allow a third party driver to register itself with the FSD and interact with its I/O queues.
Such drivers are called within the WinFsp sources and header/library files by the name of "Fsext Providers" (File System Extension Providers). In the text below we will usually refer to them as simply "Providers".
A Provider is a kernel mode driver that uses the FSD as a frontend file system driver to interface with Windows and implement all the complex details that this entails. The Provider fetches I/O requests from the WinFsp I/O queues and may filter them, transform them into a different protocol (as is the case with WinFuse) or use them to fully implement a file system in kernel mode.
== Provider Development
The WinFsp installer includes a "Kernel Developer" feature. When installed this feature adds header and library files in the `opt\fsext` installation subdirectory.
The primary header file used for Provider development is `<winfsp/fsext.h>` and can be found in `opt\fsext\inc`. Additionally the file `<winfsp/fsctl.h>` found in the `inc` installation subdirectory must be in the compiler's include path.
Providers must also be linked with one of the import libraries that can be found in `opt\fsext\lib`. Use the `winfsp-x64.lib` import library when linking the 64-bit version of a Provider and the `winfsp-x86.lib` import library when linking the 32-bit version of a Provider.
=== Provider DDI's
The `<winfsp/fsext.h>` header file includes definitions for the following important DDI's:
* `FspFsextProviderRegister`: This DDI is used by a Provider to register itself with the FSD. Typically the Provider prepares an `FSP_FSEXT_PROVIDER` structure and calls `FspFsextProviderRegister` in its `DriverEntry` routine. The structure's fields are as follows:
** `Version`: Set to `sizeof(FSP_FSEXT_PROVIDER)`.
** `DeviceTransactCode`: The `DeviceIoControl` code that should be forwarded to the Provider.
*** The code must be defined as follows: `CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0xC00 + ProviderSpecific, METHOD_BUFFERED, FILE_ANY_ACCESS)`.
*** Please note that this scheme allows for up to 1024 codes. If you want to define a new Provider code I will appreciate it if you email me at `<billziss at navimatics.com>` so that we can keep track of Provider codes, avoid conflicts and see when we need to extend this scheme.
** `DeviceExtensionSize`: The size of private data that the Provider wants for itself in the `DeviceExtension` of the FSD volume's device object.
** `DeviceInit`: Called when a new volume is created. The `DeviceObject` parameter is the volume's device object. The `VolumeParams` are the initial parameters passed to `FspFsctlCreateVolume` and can be modified by the Provider.
** `DeviceFini`: Called when a volume is going away. This usually happens when the volume `HANDLE` is closed.
** `DeviceExpirationRoutine`: Called once a second as part of the FSD's expiration timer. The FSD uses this timer to expire caches, long-pending IRP's, etc. A Provider can use this call for a similar purpose. The `ExpirationTime` parameter contains the current interrupt time as determined by the FSD.
** `DeviceTransact`: Called whenever the FSD receives a `DeviceIoControl` request with the `DeviceTransactCode`. The `Irp` parameter contains the relevant `IRP_MJ_FILE_SYSTEM_CONTROL`.
** `DeviceExtensionOffset`: Set to `0` on input. On successful return from `FspFsextProviderRegister` it will contain the offset to use for accessing the Provider's private data in the `DeviceExtension` of the FSD volume's device object. Given a `DeviceObject`, the data can be accessed as `(PVOID)((PUINT8)DeviceObject->DeviceExtension + Provider.DeviceExtensionOffset)`.
* `FspFsextProviderTransact`: This DDI is used by a Provider to interact with the FSD I/O queues. The `DeviceObject` is the FSD volume's device object. The `FileObject` is the `FILE_OBJECT` that corresponds to the volume `HANDLE` (created by `FspFsctlCreateVolume`). The `Response` is the response to send and can be `NULL`. The `Request` is a pointer that receives a pointer to a new request from the WinFsp I/O queue and can be `NULL`; if the received pointer is not `NULL` it must be freed with `ExFreePool`.
=== Provider I/O
When the FSD receives a file system IRP it is often able to handle and complete it without help from an external user mode or kernel mode file system. However in most cases the IRP has to be seen and acted upon by an external file system. For this reason the FSD preprocesses the IRP and places it in an I/O queue in the form of a "request". At a later time the external file system retrieves the request, processes it and sends back a "response". The FSD uses the response to locate the original IRP, perform any necessary postprocessing and finally complete the IRP.
Providers typically use the `FspFsextProviderTransact` DDI to receive requests and send back responses. Requests are of type `FSP_FSCTL_TRANSACT_REQ` and responses are of type `FSP_FSCTL_TRANSACT_RSP`. Requests have a `Kind` field which describes what kind of file system operation is being requested. The following request kinds are currently defined in `<winfsp/fsctl.h>`:
```
FspFsctlTransactCreateKind,
FspFsctlTransactOverwriteKind,
FspFsctlTransactCleanupKind,
FspFsctlTransactCloseKind,
FspFsctlTransactReadKind,
FspFsctlTransactWriteKind,
FspFsctlTransactQueryInformationKind,
FspFsctlTransactSetInformationKind,
FspFsctlTransactQueryEaKind,
FspFsctlTransactSetEaKind,
FspFsctlTransactFlushBuffersKind,
FspFsctlTransactQueryVolumeInformationKind,
FspFsctlTransactSetVolumeInformationKind,
FspFsctlTransactQueryDirectoryKind,
FspFsctlTransactFileSystemControlKind,
FspFsctlTransactDeviceControlKind,
FspFsctlTransactShutdownKind,
FspFsctlTransactLockControlKind,
FspFsctlTransactQuerySecurityKind,
FspFsctlTransactSetSecurityKind,
FspFsctlTransactQueryStreamInformationKind,
```
When request processing is complete the Provider must prepare a response and send it to the FSD using `FspFsextProviderTransact` as mentioned above. It is particularly important that the Provider initializes the `Kind` and `Hint` fields by copying the values from the corresponding request.
This document does not describe in detail how each request kind is supposed to be handled. For the full details refer to the implementation for the WinFsp DLL in the WinFsp sources: `src/dll/fsop.c`. Although this implementation is for user mode file systems, similar logic and techniques should be used for Providers.
== Provider Registration
Providers are loaded on demand and must be properly registered:
* A provider must be registered as a kernel driver. This can be achieved by using the command `sc create PROVIDER type=kernel binPath=X:\PATH\TO\PROVIDER.SYS` or by using the Service Control Manager API's (`OpenServiceW`, `CreateServiceW`, etc.). You do not need an INF file or to use the Setup API in order to register a Provider driver.
* A provider must be registered under the registry key `HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\WinFsp\Fsext`. Create a string value with name the textual representation of the Provider's transact code (see `DeviceTransactCode`) in `"%08lx"` format and value the Provider's driver name.
For example the WinFuse Provider registers its driver under the name `WinFuse` and adds a registry value of `00093118` -> `WinFuse`.
== Provider Lifetime
Providers are loaded on demand by the FSD during volume creation. This process works as follows:
* During volume creation (e.g. by using `FspFsctlCreateVolume`) a non-zero `FsextControlCode` must be specified in `VolumeParams`.
* If the FSD sees the `FsextControlCode` as non-zero it attempts to find a corresponding Provider driver.
** It first checks an internal mapping of codes to Provider drivers. If the code is found, the FSD proceeds to the `DeviceInit` step below.
** If the code is not found in the internal mapping, the FSD checks the registry under the registry key `HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\WinFsp\Fsext`. If the code is not found the volume creation fails.
** If the code is found the FSD loads the Provider driver using `ZwLoadDriver`. The Provider is supposed to register itself with the FSD during `DriverEntry` by calling `FspFsextProviderRegister`.
** Finally the internal mapping of codes to Providers is rechecked. Assuming that everything worked as intended, the corresponding Provider driver is now loaded and we can proceed to the `DeviceInit` step.
* The FSD proceeds to call the `DeviceInit` callback of the Provider. The Provider can use this call to initialize itself in relation to the new volume device object.
* Assuming that the volume device object is created successfully, the FSD will do the following:
** Forward any `FsextControlCode==DeviceTransactCode` requests that it gets in its `IRP_MJ_FILE_SYSTEM_CONTROL` to the Provider via `DeviceTransact`.
** Call the Provider's `DeviceExpirationRoutine` once a second as part of the FSD's expiration process.
* Eventually the volume device object will be torn down (e.g. because the corresponding `HANDLE` is closed). In this case the FSD will call the Provider's `DeviceFini` callback.
Finally note that once loaded a Provider driver cannot be unloaded (without a reboot).

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/callstack.c * @file tlib/callstack.c
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#include <tlib/callstack.h> #include <tlib/callstack.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/callstack.h * @file tlib/callstack.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#ifndef TLIB_CALLSTACK_H_INCLUDED #ifndef TLIB_CALLSTACK_H_INCLUDED

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injected/allfunc.h * @file tlib/injected/allfunc.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED #ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injected/curlfunc.c * @file tlib/injected/curlfunc.c
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#include <tlib/injected/curlfunc.h> #include <tlib/injected/curlfunc.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injected/curlfunc.h * @file tlib/injected/curlfunc.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED #ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injected/stdfunc.c * @file tlib/injected/stdfunc.c
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#include <tlib/injected/stdfunc.h> #include <tlib/injected/stdfunc.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injected/stdfunc.h * @file tlib/injected/stdfunc.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED #ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injection.c * @file tlib/injection.c
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#include <tlib/injection.h> #include <tlib/injection.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/injection.h * @file tlib/injection.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
/* NOTE: This header may usefully be included multiple times. /* NOTE: This header may usefully be included multiple times.

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/testsuite.c * @file tlib/testsuite.c
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#include <tlib/testsuite.h> #include <tlib/testsuite.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/testsuite.h * @file tlib/testsuite.h
* *
* @copyright 2014-2019 Bill Zissimopoulos * @copyright 2014-2020 Bill Zissimopoulos
*/ */
#ifndef TLIB_TESTSUITE_H_INCLUDED #ifndef TLIB_TESTSUITE_H_INCLUDED

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -2,7 +2,7 @@
* @file fuse/winfsp_fuse.h * @file fuse/winfsp_fuse.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -2,7 +2,7 @@
* @file fuse3/fuse_opt.h * @file fuse3/fuse_opt.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -2,7 +2,7 @@
* @file fuse3/winfsp_fuse.h * @file fuse3/winfsp_fuse.h
* WinFsp FUSE3 compatible API. * WinFsp FUSE3 compatible API.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file winfsp/fsctl.h * @file winfsp/fsctl.h
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -54,6 +54,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
#define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT)) #define FSP_FSCTL_DECLSPEC_ALIGN __declspec(align(FSP_FSCTL_DEFAULT_ALIGNMENT))
/* fsctl device codes */ /* fsctl device codes */
#define FSP_FSCTL_MOUNTDEV \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSP_FSCTL_VOLUME_NAME \ #define FSP_FSCTL_VOLUME_NAME \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSP_FSCTL_VOLUME_LIST \ #define FSP_FSCTL_VOLUME_LIST \
@ -65,6 +67,10 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
#define FSP_FSCTL_STOP \ #define FSP_FSCTL_STOP \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS)
/* fsctl internal device codes (usable only in-kernel) */
#define FSP_FSCTL_TRANSACT_INTERNAL \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'I', METHOD_NEITHER, FILE_ANY_ACCESS)
#define FSP_FSCTL_VOLUME_PARAMS_PREFIX "\\VolumeParams=" #define FSP_FSCTL_VOLUME_PARAMS_PREFIX "\\VolumeParams="
#define FSP_FSCTL_VOLUME_NAME_SIZE (64 * sizeof(WCHAR)) #define FSP_FSCTL_VOLUME_NAME_SIZE (64 * sizeof(WCHAR))
@ -83,14 +89,14 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR),
#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) #define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024)
#define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX #define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((T) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((UINT_PTR)((T) & 0xffffffff)))
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff))
#define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */ #define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */
/* marshalling */ /* marshalling */
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4200) /* zero-sized array in struct/union */ #pragma warning(disable:4200 4201) /* zero-sized array in struct/union; nameless struct/union */
enum enum
{ {
FspFsctlTransactReservedKind = 0, FspFsctlTransactReservedKind = 0,
@ -121,7 +127,7 @@ enum
{ {
FspFsctlTransactTimeoutMinimum = 1000, FspFsctlTransactTimeoutMinimum = 1000,
FspFsctlTransactTimeoutMaximum = 10000, FspFsctlTransactTimeoutMaximum = 10000,
FspFsctlTransactTimeoutDefault = 1000, FspFsctlTransactTimeoutDefault = 1000, /* DEPRECATED: default is unspecified */
FspFsctlIrpTimeoutMinimum = 60000, FspFsctlIrpTimeoutMinimum = 60000,
FspFsctlIrpTimeoutMaximum = 600000, FspFsctlIrpTimeoutMaximum = 600000,
FspFsctlIrpTimeoutDefault = 300000, FspFsctlIrpTimeoutDefault = 300000,
@ -139,7 +145,7 @@ enum
UINT64 VolumeCreationTime;\ UINT64 VolumeCreationTime;\
UINT32 VolumeSerialNumber;\ UINT32 VolumeSerialNumber;\
/* I/O timeouts, capacity, etc. */\ /* I/O timeouts, capacity, etc. */\
UINT32 TransactTimeout; /* FSP_FSCTL_TRANSACT timeout (millis; 1 sec - 10 sec) */\ UINT32 TransactTimeout; /* DEPRECATED: (millis; 1 sec - 10 sec) */\
UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\ UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\
UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\ UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\
UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\ UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\
@ -168,7 +174,10 @@ enum
/* additional kernel-mode flags */\ /* additional kernel-mode flags */\
UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\ UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\ UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
UINT32 KmReservedFlags:6;\ UINT32 WslFeatures:1; /* support features required for WSLinux */\
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\
UINT32 RejectIrpPriorToTransact0:1; /* reject IRP's prior to FspFsctlTransact with 0 buffers */\
UINT32 KmReservedFlags:3;\
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ #define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
@ -184,7 +193,8 @@ enum
UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\ UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\
UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\ UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\
UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\ UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\
UINT32 Reserved32[2];\ UINT32 FsextControlCode;\
UINT32 Reserved32[1];\
UINT64 Reserved64[2]; UINT64 Reserved64[2];
typedef struct typedef struct
{ {
@ -234,8 +244,12 @@ typedef struct
{ {
UINT16 Size; UINT16 Size;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
UINT8 Padding[24]; union
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */ {
UINT64 NextOffset;
UINT8 Padding[24];
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */
} DUMMYUNIONNAME;
WCHAR FileNameBuf[]; WCHAR FileNameBuf[];
} FSP_FSCTL_DIR_INFO; } FSP_FSCTL_DIR_INFO;
FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO), FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO),
@ -277,7 +291,7 @@ typedef struct
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */ FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes or reparse point buffer */
UINT32 UserMode:1; /* request originated in user mode */ UINT32 UserMode:1; /* request originated in user mode */
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */ UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
@ -286,6 +300,7 @@ typedef struct
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */ UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
UINT32 AcceptsSecurityDescriptor:1; UINT32 AcceptsSecurityDescriptor:1;
UINT32 EaIsReparsePoint:1; /* Ea buffer is reparse point */
UINT32 ReservedFlags:24; UINT32 ReservedFlags:24;
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */ UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
} Create; } Create;
@ -586,11 +601,13 @@ static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse(
return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse : 0; return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse : 0;
} }
#if !defined(WINFSP_SYS_INTERNAL) #if !defined(_KERNEL_MODE)
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,
PHANDLE PVolumeHandle); PHANDLE PVolumeHandle);
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
BOOLEAN Persistent, GUID *UniqueId);
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID ResponseBuf, SIZE_T ResponseBufSize, PVOID ResponseBuf, SIZE_T ResponseBufSize,
PVOID RequestBuf, SIZE_T *PRequestBufSize, PVOID RequestBuf, SIZE_T *PRequestBufSize,
@ -599,6 +616,20 @@ FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath, FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize); PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath); FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
typedef struct
{
/* in */
HANDLE VolumeHandle; /* volume handle returned by FspFsctlCreateVolume */
PWSTR VolumeName; /* volume name returned by FspFsctlCreateVolume */
PSECURITY_DESCRIPTOR Security; /* optional: security descriptor for directories */
UINT64 Reserved; /* reserved for future use */
/* in/out */
PWSTR MountPoint; /* FspMountSet sets drive in buffer when passed "*:" */
HANDLE MountHandle; /* FspMountSet sets, FspMountRemove uses */
} FSP_MOUNT_DESC;
FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc);
FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,7 +5,7 @@
* In order to use the WinFsp Launch API a program must include &lt;winfsp/launch.h&gt; * In order to use the WinFsp Launch API a program must include &lt;winfsp/launch.h&gt;
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library. * and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -5,7 +5,7 @@
* In order to use the WinFsp API the user mode file system must include &lt;winfsp/winfsp.h&gt; * In order to use the WinFsp API the user mode file system must include &lt;winfsp/winfsp.h&gt;
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library. * and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -912,7 +912,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
/** /**
* Create new file or directory. * Create new file or directory.
* *
* This function works like Create, except that it also accepts EA (extended attributes). * This function works like Create, except that it also accepts an extra buffer that
* may contain extended attributes or a reparse point.
* *
* NOTE: If both Create and CreateEx are defined, CreateEx takes precedence. * NOTE: If both Create and CreateEx are defined, CreateEx takes precedence.
* *
@ -941,10 +942,12 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* Windows GetSecurityDescriptorLength API. Will be NULL for named streams. * Windows GetSecurityDescriptorLength API. Will be NULL for named streams.
* @param AllocationSize * @param AllocationSize
* Allocation size for the newly created file. * Allocation size for the newly created file.
* @param Ea * @param ExtraBuffer
* Extended attributes buffer. * Extended attributes or reparse point buffer.
* @param EaLength * @param ExtraLength
* Extended attributes buffer length. * Extended attributes or reparse point buffer length.
* @param ExtraBufferIsReparsePoint
* FALSE: extra buffer is extended attributes; TRUE: extra buffer is reparse point.
* @param PFileContext [out] * @param PFileContext [out]
* Pointer that will receive the file context on successful return from this call. * Pointer that will receive the file context on successful return from this call.
* @param FileInfo [out] * @param FileInfo [out]
@ -956,7 +959,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
/** /**
* Overwrite a file. * Overwrite a file.

View File

@ -2,7 +2,7 @@
* @file winfsp/winfsp.hpp * @file winfsp/winfsp.hpp
* WinFsp C++ Layer. * WinFsp C++ Layer.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file fuse/cygfuse.c * @file fuse/cygfuse.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file fuse3/cygfuse.c * @file fuse3/cygfuse.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -0,0 +1,96 @@
/**
* @file winfsp/fsext.h
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef WINFSP_FSEXT_H_INCLUDED
#define WINFSP_FSEXT_H_INCLUDED
#if !defined(_KERNEL_MODE)
#error This file can only be included when compiling for kernel mode.
#endif
#include <winfsp/fsctl.h>
#if defined(WINFSP_SYS_INTERNAL)
#define FSP_DDI __declspec(dllexport)
#else
#define FSP_DDI __declspec(dllimport)
#endif
#if !defined(FSP_DDI_DEF)
#define FSP_DDI_DEF(RetType, Name, ...) FSP_DDI RetType NTAPI Name ( __VA_ARGS__ );
#endif
typedef struct
{
UINT32 Version;
/* in */
UINT32 DeviceTransactCode;
UINT32 DeviceExtensionSize;
NTSTATUS (*DeviceInit)(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_PARAMS *VolumeParams);
VOID (*DeviceFini)(PDEVICE_OBJECT DeviceObject);
VOID (*DeviceExpirationRoutine)(PDEVICE_OBJECT DeviceObject, UINT64 ExpirationTime);
NTSTATUS (*DeviceTransact)(PDEVICE_OBJECT DeviceObject, PIRP Irp);
/* out */
UINT32 DeviceExtensionOffset;
} FSP_FSEXT_PROVIDER;
FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister,
FSP_FSEXT_PROVIDER *Provider)
FSP_DDI_DEF(NTSTATUS, FspFsextProviderTransact,
PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FSP_FSCTL_TRANSACT_RSP *Response, FSP_FSCTL_TRANSACT_REQ **PRequest)
FSP_DDI_DEF(NTSTATUS, FspPosixMapUidToSid,
UINT32 Uid,
PSID *PSid)
FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid,
PSID Sid,
PUINT32 PUid)
FSP_DDI_DEF(VOID, FspDeleteSid,
PSID Sid,
NTSTATUS (*CreateFunc)())
FSP_DDI_DEF(NTSTATUS, FspPosixMapPermissionsToSecurityDescriptor,
UINT32 Uid,
UINT32 Gid,
UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
FSP_DDI_DEF(NTSTATUS, FspPosixMapSecurityDescriptorToPermissions,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid,
PUINT32 PGid,
PUINT32 PMode)
FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx,
PWSTR WindowsPath,
char **PPosixPath,
BOOLEAN Translate)
FSP_DDI_DEF(NTSTATUS, FspPosixMapPosixToWindowsPathEx,
const char *PosixPath,
PWSTR *PWindowsPath,
BOOLEAN Translate)
FSP_DDI_DEF(VOID, FspPosixDeletePath,
void *Path)
FSP_DDI_DEF(VOID, FspPosixEncodeWindowsPath,
PWSTR WindowsPath,
ULONG Size)
FSP_DDI_DEF(VOID, FspPosixDecodeWindowsPath,
PWSTR WindowsPath,
ULONG Size)
#endif

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,6 @@
// tools\impdef.bat lib\winfsp.impdef lib\winfsp-x64.lib
// tools\impdef.bat lib\winfsp.impdef lib\winfsp-x86.lib
#define FSP_DDI_DEF(RetType, Name, ...) __declspec(dllexport) RetType NTAPI Name ( __VA_ARGS__ ) {}
#include <ntifs.h>
#include <winfsp/fsext.h>

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/debug.c * @file dll/debug.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/dirbuf.c * @file dll/dirbuf.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/eventlog.c * @file dll/eventlog.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fs.c * @file dll/fs.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -24,41 +24,19 @@
enum enum
{ {
FspFileSystemDispatcherThreadCountMin = 2, FspFileSystemDispatcherThreadCountMin = 2,
FspFileSystemDispatcherDefaultThreadCountMin = 4,
FspFileSystemDispatcherDefaultThreadCountMax = 16,
}; };
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface; static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT; static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT;
static DWORD FspFileSystemTlsKey = TLS_OUT_OF_INDEXES; static DWORD FspFileSystemTlsKey = TLS_OUT_OF_INDEXES;
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
static NTSTATUS (NTAPI *FspNtMakeTemporaryObject)(
HANDLE Handle);
static NTSTATUS (NTAPI *FspNtClose)(
HANDLE Handle);
static BOOL WINAPI FspFileSystemInitialize( static BOOL WINAPI FspFileSystemInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
HANDLE Handle;
FspFileSystemTlsKey = TlsAlloc(); FspFileSystemTlsKey = TlsAlloc();
Handle = GetModuleHandleW(L"ntdll.dll");
if (0 != Handle)
{
FspNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
FspNtMakeTemporaryObject = (PVOID)GetProcAddress(Handle, "NtMakeTemporaryObject");
FspNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
if (0 == FspNtOpenSymbolicLinkObject || 0 == FspNtMakeTemporaryObject || 0 == FspNtClose)
{
FspNtOpenSymbolicLinkObject = 0;
FspNtMakeTemporaryObject = 0;
FspNtClose = 0;
}
}
return TRUE; return TRUE;
} }
@ -91,7 +69,9 @@ FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath,
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
else else
{ {
if (FspPathIsDrive(MountPoint)) if (FspPathIsMountmgrMountPoint(MountPoint))
Result = STATUS_SUCCESS; /* cannot check with the mount manager, assume success */
else if (FspPathIsDrive(MountPoint))
Result = QueryDosDeviceW(MountPoint, TargetPath, MAX_PATH) ? Result = QueryDosDeviceW(MountPoint, TargetPath, MAX_PATH) ?
STATUS_OBJECT_NAME_COLLISION : STATUS_SUCCESS; STATUS_OBJECT_NAME_COLLISION : STATUS_SUCCESS;
else else
@ -194,205 +174,6 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
MemFree(FileSystem); MemFree(FileSystem);
} }
static NTSTATUS FspFileSystemLauncherDefineDosDevice(
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
{
if (2 != lstrlenW(MountPoint) ||
FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= lstrlenW(VolumeName))
return STATUS_INVALID_PARAMETER;
WCHAR Argv0[4];
PWSTR Argv[2];
NTSTATUS Result;
ULONG ErrorCode;
Argv0[0] = Sign;
Argv0[1] = MountPoint[0];
Argv0[2] = MountPoint[1];
Argv0[3] = L'\0';
Argv[0] = Argv0;
Argv[1] = VolumeName;
Result = FspLaunchCallLauncherPipe(FspLaunchCmdDefineDosDevice, 2, Argv, 0, 0, 0, &ErrorCode);
return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode);
}
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
PHANDLE PMountHandle)
{
NTSTATUS Result;
BOOLEAN IsLocalSystem, IsServiceContext;
*PMountHandle = 0;
Result = FspServiceContextCheck(0, &IsLocalSystem);
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
if (IsServiceContext)
{
/*
* If the current process is in the service context but not LocalSystem,
* ask the launcher to DefineDosDevice for us. This is because the launcher
* runs in the LocalSystem context and can create global drives.
*
* In this case the launcher will also add DELETE access to the drive symlink
* for us, so that we can make it temporary below.
*/
Result = FspFileSystemLauncherDefineDosDevice(L'+', MountPoint, VolumeName);
if (!NT_SUCCESS(Result))
return Result;
}
else
{
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
return FspNtStatusFromWin32(GetLastError());
}
if (0 != FspNtOpenSymbolicLinkObject)
{
WCHAR SymlinkBuf[6];
UNICODE_STRING Symlink;
OBJECT_ATTRIBUTES Obja;
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
SymlinkBuf[4] = MountPoint[0];
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
Symlink.Buffer = SymlinkBuf;
memset(&Obja, 0, sizeof Obja);
Obja.Length = sizeof Obja;
Obja.ObjectName = &Symlink;
Obja.Attributes = OBJ_CASE_INSENSITIVE;
Result = FspNtOpenSymbolicLinkObject(PMountHandle, DELETE, &Obja);
if (NT_SUCCESS(Result))
{
Result = FspNtMakeTemporaryObject(*PMountHandle);
if (!NT_SUCCESS(Result))
{
FspNtClose(*PMountHandle);
*PMountHandle = 0;
}
}
}
/* HACK:
*
* Handles do not use the low 2 bits (unless they are console handles).
* Abuse this fact to remember that we are running in the service context.
*/
*PMountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)*PMountHandle | IsServiceContext);
return STATUS_SUCCESS;
}
static NTSTATUS FspFileSystemSetMountPoint_Directory(PWSTR MountPoint, PWSTR VolumeName,
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
{
NTSTATUS Result;
SECURITY_ATTRIBUTES SecurityAttributes;
HANDLE MountHandle = INVALID_HANDLE_VALUE;
DWORD Backslashes, Bytes;
USHORT VolumeNameLength, BackslashLength, ReparseDataLength;
PREPARSE_DATA_BUFFER ReparseData = 0;
PWSTR P, PathBuffer;
*PMountHandle = 0;
/*
* Windows does not allow mount points (junctions) to point to network file systems.
*
* Count how many backslashes our VolumeName has. If it is 3 or more this is a network
* file system. Preemptively return STATUS_NETWORK_ACCESS_DENIED.
*/
for (P = VolumeName, Backslashes = 0; *P; P++)
if (L'\\' == *P)
if (3 == ++Backslashes)
{
Result = STATUS_NETWORK_ACCESS_DENIED;
goto exit;
}
memset(&SecurityAttributes, 0, sizeof SecurityAttributes);
SecurityAttributes.nLength = sizeof SecurityAttributes;
SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor;
MountHandle = CreateFileW(MountPoint,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
&SecurityAttributes,
CREATE_NEW,
FILE_ATTRIBUTE_DIRECTORY |
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE,
0);
if (INVALID_HANDLE_VALUE == MountHandle)
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
VolumeNameLength = (USHORT)lstrlenW(VolumeName);
BackslashLength = 0 == VolumeNameLength || L'\\' != VolumeName[VolumeNameLength - 1];
VolumeNameLength *= sizeof(WCHAR);
BackslashLength *= sizeof(WCHAR);
ReparseDataLength = (USHORT)(
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) -
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)) +
2 * (VolumeNameLength + BackslashLength + sizeof(WCHAR));
ReparseData = MemAlloc(REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataLength);
if (0 == ReparseData)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
ReparseData->ReparseDataLength = ReparseDataLength;
ReparseData->Reserved = 0;
ReparseData->MountPointReparseBuffer.SubstituteNameOffset = 0;
ReparseData->MountPointReparseBuffer.SubstituteNameLength =
VolumeNameLength + BackslashLength;
ReparseData->MountPointReparseBuffer.PrintNameOffset =
ReparseData->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
ReparseData->MountPointReparseBuffer.PrintNameLength =
VolumeNameLength + BackslashLength;
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer;
memcpy(PathBuffer, VolumeName, VolumeNameLength);
if (BackslashLength)
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer +
(ReparseData->MountPointReparseBuffer.PrintNameOffset) / sizeof(WCHAR);
memcpy(PathBuffer, VolumeName, VolumeNameLength);
if (BackslashLength)
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
if (!DeviceIoControl(MountHandle, FSCTL_SET_REPARSE_POINT,
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
0, 0,
&Bytes, 0))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
*PMountHandle = MountHandle;
Result = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(Result) && INVALID_HANDLE_VALUE != MountHandle)
CloseHandle(MountHandle);
MemFree(ReparseData);
return Result;
}
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint) FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint)
{ {
return FspFileSystemSetMountPointEx(FileSystem, MountPoint, 0); return FspFileSystemSetMountPointEx(FileSystem, MountPoint, 0);
@ -404,105 +185,55 @@ FSP_API NTSTATUS FspFileSystemSetMountPointEx(FSP_FILE_SYSTEM *FileSystem, PWSTR
if (0 != FileSystem->MountPoint) if (0 != FileSystem->MountPoint)
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
FSP_MOUNT_DESC Desc;
int Size;
NTSTATUS Result; NTSTATUS Result;
HANDLE MountHandle = 0;
memset(&Desc, 0, sizeof Desc);
Desc.VolumeHandle = FileSystem->VolumeHandle;
Desc.VolumeName = FileSystem->VolumeName;
Desc.Security = SecurityDescriptor;
if (0 == MountPoint) if (0 == MountPoint)
MountPoint = L"*:";
Size = (lstrlenW(MountPoint) + 1) * sizeof(WCHAR);
Desc.MountPoint = MemAlloc(Size);
if (0 == Desc.MountPoint)
{ {
DWORD Drives; Result = STATUS_INSUFFICIENT_RESOURCES;
WCHAR Drive; goto exit;
MountPoint = MemAlloc(3 * sizeof(WCHAR));
if (0 == MountPoint)
return STATUS_INSUFFICIENT_RESOURCES;
MountPoint[1] = L':';
MountPoint[2] = L'\0';
Drives = GetLogicalDrives();
if (0 != Drives)
{
for (Drive = 'Z'; 'D' <= Drive; Drive--)
if (0 == (Drives & (1 << (Drive - 'A'))))
{
MountPoint[0] = Drive;
Result = FspFileSystemSetMountPoint_Drive(MountPoint, FileSystem->VolumeName,
&MountHandle);
if (NT_SUCCESS(Result))
goto exit;
}
Result = STATUS_NO_SUCH_DEVICE;
}
else
Result = FspNtStatusFromWin32(GetLastError());
} }
else memcpy(Desc.MountPoint, MountPoint, Size);
{
PWSTR P;
ULONG L;
L = (ULONG)((lstrlenW(MountPoint) + 1) * sizeof(WCHAR)); Result = FspMountSet(&Desc);
P = MemAlloc(L);
if (0 == P)
return STATUS_INSUFFICIENT_RESOURCES;
memcpy(P, MountPoint, L);
MountPoint = P;
if (FspPathIsDrive(MountPoint))
Result = FspFileSystemSetMountPoint_Drive(MountPoint, FileSystem->VolumeName,
&MountHandle);
else
Result = FspFileSystemSetMountPoint_Directory(MountPoint, FileSystem->VolumeName,
SecurityDescriptor, &MountHandle);
}
exit: exit:
if (NT_SUCCESS(Result)) if (NT_SUCCESS(Result))
{ {
FileSystem->MountPoint = MountPoint; FileSystem->MountPoint = Desc.MountPoint;
FileSystem->MountHandle = MountHandle; FileSystem->MountHandle = Desc.MountHandle;
} }
else else
MemFree(MountPoint); MemFree(Desc.MountPoint);
return Result; return Result;
} }
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
{
BOOLEAN IsServiceContext = 0 != ((DWORD)(UINT_PTR)MountHandle & 1);
MountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)MountHandle & ~1);
if (IsServiceContext)
/*
* If the current process is in the service context but not LocalSystem,
* ask the launcher to DefineDosDevice for us. This is because the launcher
* runs in the LocalSystem context and can remove global drives.
*/
FspFileSystemLauncherDefineDosDevice(L'-', MountPoint, VolumeName);
else
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
MountPoint, VolumeName);
if (0 != MountHandle)
FspNtClose(MountHandle);
}
static VOID FspFileSystemRemoveMountPoint_Directory(HANDLE MountHandle)
{
/* directory is marked DELETE_ON_CLOSE */
CloseHandle(MountHandle);
}
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem) FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
{ {
if (0 == FileSystem->MountPoint) if (0 == FileSystem->MountPoint)
return; return;
if (FspPathIsDrive(FileSystem->MountPoint)) FSP_MOUNT_DESC Desc;
FspFileSystemRemoveMountPoint_Drive(FileSystem->MountPoint, FileSystem->VolumeName,
FileSystem->MountHandle); memset(&Desc, 0, sizeof Desc);
else Desc.VolumeHandle = FileSystem->VolumeHandle;
FspFileSystemRemoveMountPoint_Directory(FileSystem->MountHandle); Desc.VolumeName = FileSystem->VolumeName;
Desc.MountPoint = FileSystem->MountPoint;
Desc.MountHandle = FileSystem->MountHandle;
FspMountRemove(&Desc);
MemFree(FileSystem->MountPoint); MemFree(FileSystem->MountPoint);
FileSystem->MountPoint = 0; FileSystem->MountPoint = 0;
@ -542,6 +273,11 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
OperationContext.Response = Response; OperationContext.Response = Response;
TlsSetValue(FspFileSystemTlsKey, &OperationContext); TlsSetValue(FspFileSystemTlsKey, &OperationContext);
Result = FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, 0, 0, FALSE);
/* send a Transact0 to inform the FSD that the dispatcher is ready */
if (!NT_SUCCESS(Result))
goto exit;
memset(Response, 0, sizeof *Response); memset(Response, 0, sizeof *Response);
for (;;) for (;;)
{ {
@ -636,6 +372,11 @@ FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG
for (ThreadCount = 0; 0 != ProcessMask; ProcessMask >>= 1) for (ThreadCount = 0; 0 != ProcessMask; ProcessMask >>= 1)
ThreadCount += ProcessMask & 1; ThreadCount += ProcessMask & 1;
if (ThreadCount < FspFileSystemDispatcherDefaultThreadCountMin)
ThreadCount = FspFileSystemDispatcherDefaultThreadCountMin;
else if (ThreadCount > FspFileSystemDispatcherDefaultThreadCountMax)
ThreadCount = FspFileSystemDispatcherDefaultThreadCountMax;
} }
if (ThreadCount < FspFileSystemDispatcherThreadCountMin) if (ThreadCount < FspFileSystemDispatcherThreadCountMin)

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fsctl.c * @file dll/fsctl.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -107,6 +107,20 @@ exit:
return Result; return Result;
} }
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
BOOLEAN Persistent, GUID *UniqueId)
{
DWORD Bytes;
if (!DeviceIoControl(VolumeHandle,
FSP_FSCTL_MOUNTDEV,
&Persistent, sizeof Persistent, UniqueId, sizeof *UniqueId,
&Bytes, 0))
return FspNtStatusFromWin32(GetLastError());
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID ResponseBuf, SIZE_T ResponseBufSize, PVOID ResponseBuf, SIZE_T ResponseBufSize,
PVOID RequestBuf, SIZE_T *PRequestBufSize, PVOID RequestBuf, SIZE_T *PRequestBufSize,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fsop.c * @file dll/fsop.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -443,6 +443,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
@ -590,6 +591,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
@ -724,6 +726,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
@ -757,7 +760,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
NTSTATUS Result; NTSTATUS Result;
WCHAR Root[2] = L"\\"; WCHAR Root[2] = L"\\";
PWSTR Parent, Suffix; PWSTR Parent, Suffix;
UINT32 GrantedAccess; UINT32 CreateOptions, GrantedAccess;
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext; FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
UINT32 Information; UINT32 Information;
@ -772,8 +775,10 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer; OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root); FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root);
CreateOptions =
(Request->Req.Create.CreateOptions | FILE_DIRECTORY_FILE) & ~FILE_NON_DIRECTORY_FILE;
Result = FileSystem->Interface->Open(FileSystem, Result = FileSystem->Interface->Open(FileSystem,
Parent, Request->Req.Create.CreateOptions, GrantedAccess, Parent, CreateOptions, GrantedAccess,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
FspPathCombine((PWSTR)Request->Buffer, Suffix); FspPathCombine((PWSTR)Request->Buffer, Suffix);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -1743,9 +1748,15 @@ reparse_data_exit:
return IO_REPARSE_TAG_SYMLINK != ReparseData->ReparseTag ? return IO_REPARSE_TAG_SYMLINK != ReparseData->ReparseTag ?
STATUS_IO_REPARSE_DATA_INVALID : STATUS_REPARSE_POINT_NOT_RESOLVED; STATUS_IO_REPARSE_DATA_INVALID : STATUS_REPARSE_POINT_NOT_RESOLVED;
if (IO_REPARSE_TAG_MOUNT_POINT == ReparseData->ReparseTag)
RemainderPathSize = lstrlenW(RemainderPath) * sizeof(WCHAR);
*PSize = ReparseDataSize; *PSize = ReparseDataSize;
memcpy(Buffer, ReparseData, ReparseDataSize); memcpy(Buffer, ReparseData, ReparseDataSize);
if (IO_REPARSE_TAG_MOUNT_POINT == ReparseData->ReparseTag)
OutputReparseData->Reserved = RemainderPathSize;
PIoStatus->Status = STATUS_REPARSE; PIoStatus->Status = STATUS_REPARSE;
PIoStatus->Information = ReparseData->ReparseTag; PIoStatus->Information = ReparseData->ReparseTag;
return STATUS_REPARSE; return STATUS_REPARSE;

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse.c * @file dll/fuse/fuse.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -54,6 +54,10 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("umask=%o", umask, 0), FSP_FUSE_CORE_OPT("umask=%o", umask, 0),
FSP_FUSE_CORE_OPT("create_umask=", set_create_umask, 1), FSP_FUSE_CORE_OPT("create_umask=", set_create_umask, 1),
FSP_FUSE_CORE_OPT("create_umask=%o", create_umask, 0), FSP_FUSE_CORE_OPT("create_umask=%o", create_umask, 0),
FSP_FUSE_CORE_OPT("create_file_umask=", set_create_file_umask, 1),
FSP_FUSE_CORE_OPT("create_file_umask=%o", create_file_umask, 0),
FSP_FUSE_CORE_OPT("create_dir_umask=", set_create_dir_umask, 1),
FSP_FUSE_CORE_OPT("create_dir_umask=%o", create_dir_umask, 0),
FSP_FUSE_CORE_OPT("uid=", set_uid, 1), FSP_FUSE_CORE_OPT("uid=", set_uid, 1),
FSP_FUSE_CORE_OPT("uid=%d", uid, 0), FSP_FUSE_CORE_OPT("uid=%d", uid, 0),
FSP_FUSE_CORE_OPT("gid=", set_gid, 1), FSP_FUSE_CORE_OPT("gid=", set_gid, 1),
@ -71,6 +75,9 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("rellinks", rellinks, 1), FSP_FUSE_CORE_OPT("rellinks", rellinks, 1),
FSP_FUSE_CORE_OPT("norellinks", rellinks, 0), FSP_FUSE_CORE_OPT("norellinks", rellinks, 0),
FSP_FUSE_CORE_OPT("dothidden", dothidden, 1),
FSP_FUSE_CORE_OPT("nodothidden", dothidden, 0),
FUSE_OPT_KEY("fstypename=", 'F'), FUSE_OPT_KEY("fstypename=", 'F'),
FUSE_OPT_KEY("volname=", 'v'), FUSE_OPT_KEY("volname=", 'v'),
@ -95,6 +102,17 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FUSE_OPT_KEY("--VolumePrefix=", 'U'), FUSE_OPT_KEY("--VolumePrefix=", 'U'),
FUSE_OPT_KEY("FileSystemName=", 'F'), FUSE_OPT_KEY("FileSystemName=", 'F'),
FUSE_OPT_KEY("--FileSystemName=", 'F'), FUSE_OPT_KEY("--FileSystemName=", 'F'),
FUSE_OPT_KEY("ExactFileSystemName=", 'E'),
FUSE_OPT_KEY("--ExactFileSystemName=", 'E'),
FSP_FUSE_CORE_OPT("UserName=", set_uid, 1),
FUSE_OPT_KEY("UserName=", 'u'),
FSP_FUSE_CORE_OPT("--UserName=", set_uid, 1),
FUSE_OPT_KEY("--UserName=", 'u'),
FSP_FUSE_CORE_OPT("GroupName=", set_gid, 1),
FUSE_OPT_KEY("GroupName=", 'g'),
FSP_FUSE_CORE_OPT("--GroupName=", set_gid, 1),
FUSE_OPT_KEY("--GroupName=", 'g'),
FUSE_OPT_END, FUSE_OPT_END,
}; };
@ -226,6 +244,43 @@ FSP_FUSE_API int fsp_fuse_is_lib_option(struct fsp_fuse_env *env,
return fsp_fuse_opt_match(env, fsp_fuse_core_opts, opt); return fsp_fuse_opt_match(env, fsp_fuse_core_opts, opt);
} }
static int fsp_fuse_username_to_uid(const char *username, int *puid)
{
union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} SidBuf;
char Name[256], Domn[256];
DWORD SidSize, NameSize, DomnSize;
SID_NAME_USE Use;
UINT32 Uid;
NTSTATUS Result;
*puid = 0;
NameSize = lstrlenA(username) + 1;
if (sizeof Name / sizeof Name[0] < NameSize)
return -1;
memcpy(Name, username, NameSize);
for (PSTR P = Name, EndP = P + NameSize; EndP > P; P++)
if ('+' == *P)
*P = '\\';
SidSize = sizeof SidBuf;
DomnSize = sizeof Domn / sizeof Domn[0];
if (!LookupAccountNameA(0, Name, &SidBuf, &SidSize, Domn, &DomnSize, &Use))
return -1;
Result = FspPosixMapSidToUid(&SidBuf, &Uid);
if (!NT_SUCCESS(Result))
return -1;
*puid = Uid;
return 0;
}
static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key, static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
struct fuse_args *outargs) struct fuse_args *outargs)
{ {
@ -241,9 +296,12 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
FSP_FUSE_LIBRARY_NAME " options:\n" FSP_FUSE_LIBRARY_NAME " options:\n"
" -o umask=MASK set file permissions (octal)\n" " -o umask=MASK set file permissions (octal)\n"
" -o create_umask=MASK set newly created file permissions (octal)\n" " -o create_umask=MASK set newly created file permissions (octal)\n"
" -o create_file_umask=MASK for files only\n"
" -o create_dir_umask=MASK for directories only\n"
" -o uid=N set file owner (-1 for mounting user id)\n" " -o uid=N set file owner (-1 for mounting user id)\n"
" -o gid=N set file group (-1 for mounting user group)\n" " -o gid=N set file group (-1 for mounting user group)\n"
" -o rellinks interpret absolute symlinks as volume relative\n" " -o rellinks interpret absolute symlinks as volume relative\n"
" -o dothidden dot files have the Windows hidden file attrib\n"
" -o volname=NAME set volume label\n" " -o volname=NAME set volume label\n"
" -o VolumePrefix=UNC set UNC prefix (/Server/Share)\n" " -o VolumePrefix=UNC set UNC prefix (/Server/Share)\n"
" --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n" " --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n"
@ -311,6 +369,40 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
[sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0'; [sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0';
memcpy(opt_data->VolumeParams.FileSystemName, L"FUSE-", 5 * sizeof(WCHAR)); memcpy(opt_data->VolumeParams.FileSystemName, L"FUSE-", 5 * sizeof(WCHAR));
return 0; return 0;
case 'E':
if ('E' == arg[0])
arg += sizeof "ExactFileSystemName=" - 1;
else if ('E' == arg[2])
arg += sizeof "--ExactFileSystemName=" - 1;
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1,
opt_data->VolumeParams.FileSystemName,
sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR)))
return -1;
opt_data->VolumeParams.FileSystemName
[sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0';
return 0;
case 'u':
if ('U' == arg[0])
arg += sizeof "UserName=" - 1;
else if ('U' == arg[2])
arg += sizeof "--UserName=" - 1;
if (-1 == fsp_fuse_username_to_uid(arg, &opt_data->uid))
{
opt_data->username_to_uid_result = -1;
return -1;
}
return 0;
case 'g':
if ('G' == arg[0])
arg += sizeof "GroupName=" - 1;
else if ('G' == arg[2])
arg += sizeof "--GroupName=" - 1;
if (-1 == fsp_fuse_username_to_uid(arg, &opt_data->gid))
{
opt_data->username_to_uid_result = -1;
return -1;
}
return 0;
case 'v': case 'v':
arg += sizeof "volname=" - 1; arg += sizeof "volname=" - 1;
opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) * opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) *
@ -355,7 +447,14 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE; opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE;
if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1)) if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1))
{
if (-1 == opt_data.username_to_uid_result)
{
ErrorMessage = L": invalid user or group name.";
goto fail;
}
return 0; return 0;
}
if (opt_data.help) if (opt_data.help)
return 0; return 0;
@ -422,9 +521,12 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
f->env = env; f->env = env;
f->set_umask = opt_data.set_umask; f->umask = opt_data.umask; f->set_umask = opt_data.set_umask; f->umask = opt_data.umask;
f->set_create_umask = opt_data.set_create_umask; f->create_umask = opt_data.create_umask; f->set_create_umask = opt_data.set_create_umask; f->create_umask = opt_data.create_umask;
f->set_create_file_umask = opt_data.set_create_file_umask; f->create_file_umask = opt_data.create_file_umask;
f->set_create_dir_umask = opt_data.set_create_dir_umask; f->create_dir_umask = opt_data.create_dir_umask;
f->set_uid = opt_data.set_uid; f->uid = opt_data.uid; f->set_uid = opt_data.set_uid; f->uid = opt_data.uid;
f->set_gid = opt_data.set_gid; f->gid = opt_data.gid; f->set_gid = opt_data.set_gid; f->gid = opt_data.gid;
f->rellinks = opt_data.rellinks; f->rellinks = opt_data.rellinks;
f->dothidden = opt_data.dothidden;
f->ThreadCount = opt_data.ThreadCount; f->ThreadCount = opt_data.ThreadCount;
memcpy(&f->ops, ops, opsize); memcpy(&f->ops, ops, opsize);
f->data = data; f->data = data;

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_compat.c * @file dll/fuse/fuse_compat.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_intf.c * @file dll/fuse/fuse_intf.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -354,6 +354,7 @@ static inline UINT32 fsp_fuse_intf_MapFlagsToFileAttributes(uint32_t flags)
return FileAttributes; return FileAttributes;
} }
#define FUSE_FILE_INFO(IsDirectory, fi) ((IsDirectory) ? 0 : (fi))
#define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\ #define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\
fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo) fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo)
static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
@ -429,6 +430,15 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
} }
if (StatEx) if (StatEx)
FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags); FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags);
if (f->dothidden)
{
const char *basename = PosixPath;
for (const char *p = PosixPath; '\0' != *p; p++)
if ('/' == *p)
basename = p + 1;
if ('.' == basename[0])
FileInfo->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
FileInfo->FileSize = stbuf.st_size; FileInfo->FileSize = stbuf.st_size;
FileInfo->AllocationSize = FileInfo->AllocationSize =
(FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; (FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
@ -743,7 +753,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
@ -757,12 +767,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
int err; int err;
NTSTATUS Result; NTSTATUS Result;
if (0 != Ea) if (0 != ExtraBuffer)
{ {
if (0 == f->ops.listxattr || 0 == f->ops.getxattr || if (!ExtraBufferIsReparsePoint)
0 == f->ops.setxattr || 0 == f->ops.removexattr)
{ {
Result = STATUS_EAS_NOT_SUPPORTED; if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
{
Result = STATUS_EAS_NOT_SUPPORTED;
goto exit;
}
}
else
{
/* !!!: revisit */
Result = STATUS_INVALID_PARAMETER;
goto exit; goto exit;
} }
} }
@ -785,8 +804,22 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
Mode &= ~context->umask; Mode &= ~context->umask;
if (f->set_create_umask) if (CreateOptions & FILE_DIRECTORY_FILE)
Mode = 0777 & ~f->create_umask; {
if (f->set_create_dir_umask)
Mode = 0777 & ~f->create_dir_umask;
else
if (f->set_create_umask)
Mode = 0777 & ~f->create_umask;
}
else
{
if (f->set_create_file_umask)
Mode = 0777 & ~f->create_file_umask;
else
if (f->set_create_umask)
Mode = 0777 & ~f->create_umask;
}
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
if ('C' == f->env->environment) /* Cygwin */ if ('C' == f->env->environment) /* Cygwin */
@ -866,12 +899,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
if (0 != Ea) if (0 != ExtraBuffer)
{ {
Result = FspFileSystemEnumerateEa(FileSystem, if (!ExtraBufferIsReparsePoint)
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, Ea, EaLength); {
if (!NT_SUCCESS(Result)) Result = FspFileSystemEnumerateEa(FileSystem,
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, ExtraBuffer, ExtraLength);
if (!NT_SUCCESS(Result))
goto exit;
}
else
{
/* !!!: revisit: WslFeatures, GetFileInfoFunnel, GetReparsePointEx, SetReparsePoint */
Result = STATUS_INVALID_PARAMETER;
goto exit; goto exit;
}
} }
/* /*
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache. * Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
@ -881,7 +923,8 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
* Ignore fuse_file_info::nonseekable. * Ignore fuse_file_info::nonseekable.
*/ */
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath,
FUSE_FILE_INFO(CreateOptions & FILE_DIRECTORY_FILE, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -983,6 +1026,18 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
} }
else else
{ {
/*
* Some Windows applications (notably Go programs) specify FILE_APPEND_DATA without
* FILE_WRITE_DATA when opening files for appending. This caused the WinFsp-FUSE layer
* to erroneously pass O_RDONLY to the FUSE file system in such cases. We add a test
* for FILE_APPEND_DATA to ensure that either O_WRONLY or O_RDWR is specified.
*/
if (GrantedAccess & FILE_APPEND_DATA)
{
if (fi.flags == 0)
fi.flags = 1; /* need O_WRONLY as a bare minimum in order to append */
}
if (0 != f->ops.open) if (0 != f->ops.open)
{ {
err = f->ops.open(contexthdr->PosixPath, &fi); err = f->ops.open(contexthdr->PosixPath, &fi);
@ -1096,7 +1151,8 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1227,7 +1283,8 @@ static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1307,7 +1364,8 @@ static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1330,7 +1388,8 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1368,7 +1427,8 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
{ {
if (0 == LastAccessTime || 0 == LastWriteTime) if (0 == LastAccessTime || 0 == LastWriteTime)
{ {
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1415,7 +1475,8 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1442,7 +1503,8 @@ static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1589,7 +1651,8 @@ static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetSecurityEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetSecurityEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&FileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize); &FileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize);
} }
@ -1613,8 +1676,9 @@ static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, &Uid, &Gid, &Mode, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
&FileInfo); FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1712,7 +1776,7 @@ int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
NTSTATUS Result0; NTSTATUS Result0;
Result0 = fsp_fuse_intf_GetFileInfoFunnel(dh->FileSystem, 0, 0, stbuf, Result0 = fsp_fuse_intf_GetFileInfoFunnel(dh->FileSystem, name, 0, stbuf,
&Uid, &Gid, &Mode, 0, &DirInfo->FileInfo); &Uid, &Gid, &Mode, 0, &DirInfo->FileInfo);
if (NT_SUCCESS(Result0)) if (NT_SUCCESS(Result0))
DirInfo->Padding[0] = 1; /* HACK: remember that the FileInfo is valid */ DirInfo->Padding[0] = 1; /* HACK: remember that the FileInfo is valid */
@ -1972,7 +2036,9 @@ static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetReparsePointEx(FileSystem, filedesc->PosixPath, &fi, Buffer, PSize); return fsp_fuse_intf_GetReparsePointEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
Buffer, PSize);
} }
static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
@ -2043,7 +2109,8 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfo); &Uid, &Gid, &Mode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -2316,7 +2383,8 @@ static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_loop.c * @file dll/fuse/fuse_loop.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_main.c * @file dll/fuse/fuse_main.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_opt.c * @file dll/fuse/fuse_opt.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -216,11 +216,13 @@ static int fsp_fuse_opt_call_proc(struct fsp_fuse_env *env,
goto exit; goto exit;
} }
result = 0;
exit: exit:
if (0 != fullarg) if (0 != fullarg)
env->memfree(fullarg); env->memfree(fullarg);
return 0; return result;
} }
static int fsp_fuse_opt_process_arg(struct fsp_fuse_env *env, static int fsp_fuse_opt_process_arg(struct fsp_fuse_env *env,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/library.h * @file dll/fuse/library.h
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -50,9 +50,12 @@ struct fuse
struct fsp_fuse_env *env; struct fsp_fuse_env *env;
int set_umask, umask; int set_umask, umask;
int set_create_umask, create_umask; int set_create_umask, create_umask;
int set_create_file_umask, create_file_umask;
int set_create_dir_umask, create_dir_umask;
int set_uid, uid; int set_uid, uid;
int set_gid, gid; int set_gid, gid;
int rellinks; int rellinks;
int dothidden;
unsigned ThreadCount; unsigned ThreadCount;
struct fuse_operations ops; struct fuse_operations ops;
void *data; void *data;
@ -137,10 +140,13 @@ struct fsp_fuse_core_opt_data
HANDLE DebugLogHandle; HANDLE DebugLogHandle;
int set_umask, umask, int set_umask, umask,
set_create_umask, create_umask, set_create_umask, create_umask,
set_uid, uid, set_create_file_umask, create_file_umask,
set_create_dir_umask, create_dir_umask,
set_uid, uid, username_to_uid_result,
set_gid, gid, set_gid, gid,
set_attr_timeout, attr_timeout, set_attr_timeout, attr_timeout,
rellinks; rellinks,
dothidden;
int set_FileInfoTimeout, int set_FileInfoTimeout,
set_DirInfoTimeout, set_DirInfoTimeout,
set_EaTimeout, set_EaTimeout,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse3/fuse2to3.c * @file dll/fuse3/fuse2to3.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse3/fuse3.c * @file dll/fuse3/fuse3.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse3_compat.c * @file dll/fuse/fuse3_compat.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse3/library.h * @file dll/fuse3/library.h
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/launch.c * @file dll/launch.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/library.c * @file dll/library.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/library.h * @file dll/library.h
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -91,6 +91,21 @@ static inline BOOLEAN FspPathIsDrive(PWSTR FileName)
) && ) &&
L':' == FileName[1] && L'\0' == FileName[2]; L':' == FileName[1] && L'\0' == FileName[2];
} }
static inline BOOLEAN FspPathIsMountmgrMountPoint(PWSTR FileName)
{
return
(
L'\\' == FileName[0] &&
L'\\' == FileName[1] &&
(L'?' == FileName[2] || L'.' == FileName[2]) &&
L'\\' == FileName[3]
) &&
(
(L'A' <= FileName[4] && FileName[4] <= L'Z') ||
(L'a' <= FileName[4] && FileName[4] <= L'z')
) &&
L':' == FileName[5];
}
#define FSP_NEXT_EA(Ea, EaEnd) \ #define FSP_NEXT_EA(Ea, EaEnd) \
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd)) (0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))

612
src/dll/mount.c Normal file
View File

@ -0,0 +1,612 @@
/**
* @file dll/mount.c
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dll/library.h>
static INIT_ONCE FspMountInitOnce = INIT_ONCE_STATIC_INIT;
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
static NTSTATUS (NTAPI *FspNtMakeTemporaryObject)(
HANDLE Handle);
static NTSTATUS (NTAPI *FspNtClose)(
HANDLE Handle);
static BOOL WINAPI FspMountInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{
HANDLE Handle;
Handle = GetModuleHandleW(L"ntdll.dll");
if (0 != Handle)
{
FspNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
FspNtMakeTemporaryObject = (PVOID)GetProcAddress(Handle, "NtMakeTemporaryObject");
FspNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
if (0 == FspNtOpenSymbolicLinkObject || 0 == FspNtMakeTemporaryObject || 0 == FspNtClose)
{
FspNtOpenSymbolicLinkObject = 0;
FspNtMakeTemporaryObject = 0;
FspNtClose = 0;
}
}
return TRUE;
}
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
{
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
DWORD Bytes = 0;
NTSTATUS Result;
if (0 == POutputBufferLength)
POutputBufferLength = &Bytes;
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);
if (INVALID_HANDLE_VALUE == MgrHandle)
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
if (!DeviceIoControl(MgrHandle,
IoControlCode,
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
&Bytes, 0))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
*POutputBufferLength = Bytes;
Result = STATUS_SUCCESS;
exit:
if (INVALID_HANDLE_VALUE != MgrHandle)
CloseHandle(MgrHandle);
return Result;
}
static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
{
/* only support drives for now! (format: \\.\X:) */
if (L'\0' != MountPoint[6])
return STATUS_INVALID_PARAMETER;
/* mountmgr.h */
typedef enum
{
Disabled = 0,
Enabled,
} MOUNTMGR_AUTO_MOUNT_STATE;
typedef struct
{
MOUNTMGR_AUTO_MOUNT_STATE CurrentState;
} MOUNTMGR_QUERY_AUTO_MOUNT;
typedef struct
{
MOUNTMGR_AUTO_MOUNT_STATE NewState;
} MOUNTMGR_SET_AUTO_MOUNT;
typedef struct
{
USHORT DeviceNameLength;
WCHAR DeviceName[1];
} MOUNTMGR_TARGET_NAME;
typedef struct
{
USHORT SymbolicLinkNameOffset;
USHORT SymbolicLinkNameLength;
USHORT DeviceNameOffset;
USHORT DeviceNameLength;
} MOUNTMGR_CREATE_POINT_INPUT;
GUID UniqueId;
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
MOUNTMGR_TARGET_NAME *TargetName = 0;
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize, CreatePointInputSize;
HKEY RegKey;
LONG RegResult;
WCHAR RegValueName[MAX_PATH];
UINT8 RegValueData[sizeof UniqueId];
DWORD RegValueNameSize, RegValueDataSize;
DWORD RegType;
NTSTATUS Result;
/* transform our volume into one that can be used by the MountManager */
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
if (!NT_SUCCESS(Result))
goto exit;
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
QueryAutoMountSize = sizeof QueryAutoMount;
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize;
CreatePointInputSize = sizeof *CreatePointInput +
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize;
TargetName = MemAlloc(TargetNameSize);
if (0 == TargetName)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
CreatePointInput = MemAlloc(CreatePointInputSize);
if (0 == CreatePointInput)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
/* query the current AutoMount value and save it */
Result = FspMountmgrControl(
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
/* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */
0, 0, &QueryAutoMount, &QueryAutoMountSize);
if (!NT_SUCCESS(Result))
goto exit;
/* disable AutoMount */
SetAutoMount.NewState = 0;
Result = FspMountmgrControl(
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
&SetAutoMount, sizeof SetAutoMount, 0, 0);
if (!NT_SUCCESS(Result))
goto exit;
/* announce volume arrival */
memset(TargetName, 0, sizeof *TargetName);
TargetName->DeviceNameLength = (USHORT)VolumeNameSize;
memcpy(TargetName->DeviceName,
VolumeName, TargetName->DeviceNameLength);
Result = FspMountmgrControl(
CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS),
/* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */
TargetName, TargetNameSize, 0, 0);
if (!NT_SUCCESS(Result))
goto exit;
/* reset the AutoMount value to the saved one */
SetAutoMount.NewState = QueryAutoMount.CurrentState;
FspMountmgrControl(
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
&SetAutoMount, sizeof SetAutoMount, 0, 0);
#if 0
if (!NT_SUCCESS(Result))
goto exit;
#endif
/* create mount point */
memset(CreatePointInput, 0, sizeof *CreatePointInput);
CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput;
CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
CreatePointInput->DeviceNameOffset =
CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength;
CreatePointInput->DeviceNameLength = (USHORT)VolumeNameSize;
memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset,
L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength);
((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] =
MountPoint[4] & ~0x20;
/* convert to uppercase */
memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset,
VolumeName, CreatePointInput->DeviceNameLength);
Result = FspMountmgrControl(
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_CREATE_POINT */
CreatePointInput, CreatePointInputSize, 0, 0);
if (!NT_SUCCESS(Result))
goto exit;
/* HACK: delete the MountManager registry entries */
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\MountedDevices",
0, KEY_READ | KEY_WRITE, &RegKey);
if (ERROR_SUCCESS == RegResult)
{
for (DWORD I = 0;; I++)
{
RegValueNameSize = MAX_PATH;
RegValueDataSize = sizeof RegValueData;
RegResult = RegEnumValueW(RegKey,
I, RegValueName, &RegValueNameSize, 0, &RegType, RegValueData, &RegValueDataSize);
if (ERROR_NO_MORE_ITEMS == RegResult)
break;
else if (ERROR_SUCCESS != RegResult)
continue;
if (REG_BINARY == RegType &&
sizeof RegValueData == RegValueDataSize &&
InlineIsEqualGUID((GUID *)&RegValueData, &UniqueId))
{
RegResult = RegDeleteValueW(RegKey, RegValueName);
if (ERROR_SUCCESS == RegResult)
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
I = -1;
}
}
RegCloseKey(RegKey);
}
Result = STATUS_SUCCESS;
exit:
MemFree(CreatePointInput);
MemFree(TargetName);
return Result;
}
static NTSTATUS FspMountRemove_Mountmgr(PWSTR MountPoint)
{
/* mountmgr.h */
typedef struct
{
ULONG SymbolicLinkNameOffset;
USHORT SymbolicLinkNameLength;
USHORT Reserved1;
ULONG UniqueIdOffset;
USHORT UniqueIdLength;
USHORT Reserved2;
ULONG DeviceNameOffset;
USHORT DeviceNameLength;
USHORT Reserved3;
} MOUNTMGR_MOUNT_POINT;
typedef struct
{
ULONG Size;
ULONG NumberOfMountPoints;
MOUNTMGR_MOUNT_POINT MountPoints[1];
} MOUNTMGR_MOUNT_POINTS;
MOUNTMGR_MOUNT_POINT *Input = 0;
MOUNTMGR_MOUNT_POINTS *Output = 0;
ULONG InputSize, OutputSize;
NTSTATUS Result;
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
OutputSize = 4096;
Input = MemAlloc(InputSize);
if (0 == Input)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
Output = MemAlloc(OutputSize);
if (0 == Output)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
memset(Input, 0, sizeof *Input);
Input->SymbolicLinkNameOffset = sizeof *Input;
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20;
/* convert to uppercase */
Result = FspMountmgrControl(
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
/* IOCTL_MOUNTMGR_DELETE_POINTS */
Input, InputSize, Output, &OutputSize);
if (!NT_SUCCESS(Result))
goto exit;
Result = STATUS_SUCCESS;
exit:
MemFree(Output);
MemFree(Input);
return Result;
}
static NTSTATUS FspLauncherDefineDosDevice(
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
{
if (2 != lstrlenW(MountPoint) ||
FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= lstrlenW(VolumeName))
return STATUS_INVALID_PARAMETER;
WCHAR Argv0[4];
PWSTR Argv[2];
NTSTATUS Result;
ULONG ErrorCode;
Argv0[0] = Sign;
Argv0[1] = MountPoint[0];
Argv0[2] = MountPoint[1];
Argv0[3] = L'\0';
Argv[0] = Argv0;
Argv[1] = VolumeName;
Result = FspLaunchCallLauncherPipe(FspLaunchCmdDefineDosDevice, 2, Argv, 0, 0, 0, &ErrorCode);
return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode);
}
static NTSTATUS FspMountSet_Drive(PWSTR VolumeName, PWSTR MountPoint, PHANDLE PMountHandle)
{
NTSTATUS Result;
BOOLEAN IsLocalSystem, IsServiceContext;
*PMountHandle = 0;
Result = FspServiceContextCheck(0, &IsLocalSystem);
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
if (IsServiceContext)
{
/*
* If the current process is in the service context but not LocalSystem,
* ask the launcher to DefineDosDevice for us. This is because the launcher
* runs in the LocalSystem context and can create global drives.
*
* In this case the launcher will also add DELETE access to the drive symlink
* for us, so that we can make it temporary below.
*/
Result = FspLauncherDefineDosDevice(L'+', MountPoint, VolumeName);
if (!NT_SUCCESS(Result))
return Result;
}
else
{
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
return FspNtStatusFromWin32(GetLastError());
}
if (0 != FspNtOpenSymbolicLinkObject)
{
WCHAR SymlinkBuf[6];
UNICODE_STRING Symlink;
OBJECT_ATTRIBUTES Obja;
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
SymlinkBuf[4] = MountPoint[0];
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
Symlink.Buffer = SymlinkBuf;
memset(&Obja, 0, sizeof Obja);
Obja.Length = sizeof Obja;
Obja.ObjectName = &Symlink;
Obja.Attributes = OBJ_CASE_INSENSITIVE;
Result = FspNtOpenSymbolicLinkObject(PMountHandle, DELETE, &Obja);
if (NT_SUCCESS(Result))
{
Result = FspNtMakeTemporaryObject(*PMountHandle);
if (!NT_SUCCESS(Result))
{
FspNtClose(*PMountHandle);
*PMountHandle = 0;
}
}
}
/* HACK:
*
* Handles do not use the low 2 bits (unless they are console handles).
* Abuse this fact to remember that we are running in the service context.
*/
*PMountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)*PMountHandle | IsServiceContext);
return STATUS_SUCCESS;
}
static NTSTATUS FspMountRemove_Drive(PWSTR VolumeName, PWSTR MountPoint, HANDLE MountHandle)
{
NTSTATUS Result;
BOOLEAN IsServiceContext;
IsServiceContext = 0 != ((DWORD)(UINT_PTR)MountHandle & 1);
MountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)MountHandle & ~1);
if (IsServiceContext)
/*
* If the current process is in the service context but not LocalSystem,
* ask the launcher to DefineDosDevice for us. This is because the launcher
* runs in the LocalSystem context and can remove global drives.
*/
Result = FspLauncherDefineDosDevice(L'-', MountPoint, VolumeName);
else
Result = DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
MountPoint, VolumeName) ? STATUS_SUCCESS : FspNtStatusFromWin32(GetLastError());
if (0 != MountHandle)
FspNtClose(MountHandle);
return Result;
}
static NTSTATUS FspMountSet_Directory(PWSTR VolumeName, PWSTR MountPoint,
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
{
NTSTATUS Result;
SECURITY_ATTRIBUTES SecurityAttributes;
HANDLE MountHandle = INVALID_HANDLE_VALUE;
DWORD Backslashes, Bytes;
USHORT VolumeNameLength, BackslashLength, ReparseDataLength;
PREPARSE_DATA_BUFFER ReparseData = 0;
PWSTR P, PathBuffer;
*PMountHandle = 0;
/*
* Windows does not allow mount points (junctions) to point to network file systems.
*
* Count how many backslashes our VolumeName has. If it is 3 or more this is a network
* file system. Preemptively return STATUS_NETWORK_ACCESS_DENIED.
*/
for (P = VolumeName, Backslashes = 0; *P; P++)
if (L'\\' == *P)
if (3 == ++Backslashes)
{
Result = STATUS_NETWORK_ACCESS_DENIED;
goto exit;
}
memset(&SecurityAttributes, 0, sizeof SecurityAttributes);
SecurityAttributes.nLength = sizeof SecurityAttributes;
SecurityAttributes.lpSecurityDescriptor = SecurityDescriptor;
MountHandle = CreateFileW(MountPoint,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
&SecurityAttributes,
CREATE_NEW,
FILE_ATTRIBUTE_DIRECTORY |
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE,
0);
if (INVALID_HANDLE_VALUE == MountHandle)
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
VolumeNameLength = (USHORT)lstrlenW(VolumeName);
BackslashLength = 0 == VolumeNameLength || L'\\' != VolumeName[VolumeNameLength - 1];
VolumeNameLength *= sizeof(WCHAR);
BackslashLength *= sizeof(WCHAR);
ReparseDataLength = (USHORT)(
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) -
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)) +
2 * (VolumeNameLength + BackslashLength + sizeof(WCHAR));
ReparseData = MemAlloc(REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataLength);
if (0 == ReparseData)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
ReparseData->ReparseDataLength = ReparseDataLength;
ReparseData->Reserved = 0;
ReparseData->MountPointReparseBuffer.SubstituteNameOffset = 0;
ReparseData->MountPointReparseBuffer.SubstituteNameLength =
VolumeNameLength + BackslashLength;
ReparseData->MountPointReparseBuffer.PrintNameOffset =
ReparseData->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
ReparseData->MountPointReparseBuffer.PrintNameLength =
VolumeNameLength + BackslashLength;
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer;
memcpy(PathBuffer, VolumeName, VolumeNameLength);
if (BackslashLength)
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer +
(ReparseData->MountPointReparseBuffer.PrintNameOffset) / sizeof(WCHAR);
memcpy(PathBuffer, VolumeName, VolumeNameLength);
if (BackslashLength)
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
if (!DeviceIoControl(MountHandle, FSCTL_SET_REPARSE_POINT,
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
0, 0,
&Bytes, 0))
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
*PMountHandle = MountHandle;
Result = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(Result) && INVALID_HANDLE_VALUE != MountHandle)
CloseHandle(MountHandle);
MemFree(ReparseData);
return Result;
}
static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle)
{
/* directory is marked DELETE_ON_CLOSE */
return CloseHandle(MountHandle) ? STATUS_SUCCESS : FspNtStatusFromWin32(GetLastError());
}
FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
{
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
Desc->MountHandle = 0;
if (L'*' == Desc->MountPoint[0] && ':' == Desc->MountPoint[1] && L'\0' == Desc->MountPoint[2])
{
NTSTATUS Result;
DWORD Drives;
WCHAR Drive;
Drives = GetLogicalDrives();
if (0 == Drives)
return FspNtStatusFromWin32(GetLastError());
for (Drive = 'Z'; 'D' <= Drive; Drive--)
if (0 == (Drives & (1 << (Drive - 'A'))))
{
Desc->MountPoint[0] = Drive;
Result = FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
&Desc->MountHandle);
if (NT_SUCCESS(Result))
return Result;
}
Desc->MountPoint[0] = L'*';
return STATUS_NO_SUCH_DEVICE;
}
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
return FspMountSet_Mountmgr(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint);
else if (FspPathIsDrive(Desc->MountPoint))
return FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
&Desc->MountHandle);
else
return FspMountSet_Directory(Desc->VolumeName, Desc->MountPoint, Desc->Security,
&Desc->MountHandle);
}
FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
{
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
return FspMountRemove_Mountmgr(Desc->MountPoint);
else if (FspPathIsDrive(Desc->MountPoint))
return FspMountRemove_Drive(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
else
return FspMountRemove_Directory(Desc->MountHandle);
}

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/np.c * @file dll/np.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/ntstatus.c * @file dll/ntstatus.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/path.c * @file dll/path.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/security.c * @file dll/security.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/service.c * @file dll/service.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/util.c * @file dll/util.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/wksid.c * @file dll/wksid.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemBase+Const.cs * dotnet/FileSystemBase+Const.cs
* *
* Copyright 2015-2019 Bill Zissimopoulos * Copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemBase.cs * dotnet/FileSystemBase.cs
* *
* Copyright 2015-2019 Bill Zissimopoulos * Copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -1085,8 +1085,9 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
Byte[] SecurityDescriptor, Byte[] SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
Boolean ExtraBufferIsReparsePoint,
out Object FileNode, out Object FileNode,
out Object FileDesc, out Object FileDesc,
out FileInfo FileInfo, out FileInfo FileInfo,
@ -1391,6 +1392,16 @@ namespace Fsp
} }
} }
/// <summary> /// <summary>
/// Makes a byte array that contains a reparse point.
/// </summary>
/// <returns>The reparse point byte array.</returns>
public static Byte[] MakeReparsePoint(
IntPtr Buffer,
UInt32 Size)
{
return Api.MakeReparsePoint(Buffer, (UIntPtr)Size);
}
/// <summary>
/// Gets the reparse tag from reparse data. /// Gets the reparse tag from reparse data.
/// </summary> /// </summary>
/// <param name="ReparseData"> /// <param name="ReparseData">

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemHost.cs * dotnet/FileSystemHost.cs
* *
* Copyright 2015-2019 Bill Zissimopoulos * Copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -40,6 +40,7 @@ namespace Fsp
/// <param name="FileSystem">The file system to host.</param> /// <param name="FileSystem">The file system to host.</param>
public FileSystemHost(FileSystemBase FileSystem) public FileSystemHost(FileSystemBase FileSystem)
{ {
_VolumeParams.Version = (UInt16)Marshal.SizeOf(_VolumeParams);
_VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext; _VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext;
_FileSystem = FileSystem; _FileSystem = FileSystem;
} }
@ -126,6 +127,86 @@ namespace Fsp
set { _VolumeParams.FileInfoTimeout = value; } set { _VolumeParams.FileInfoTimeout = value; }
} }
/// <summary> /// <summary>
/// Gets or sets the volume information timeout.
/// </summary>
public UInt32 VolumeInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.VolumeInfoTimeoutValid) ?
_VolumeParams.VolumeInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.VolumeInfoTimeoutValid;
_VolumeParams.VolumeInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the directory information timeout.
/// </summary>
public UInt32 DirInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.DirInfoTimeoutValid) ?
_VolumeParams.DirInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.DirInfoTimeoutValid;
_VolumeParams.DirInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the security information timeout.
/// </summary>
public UInt32 SecurityTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.SecurityTimeoutValid) ?
_VolumeParams.SecurityTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.SecurityTimeoutValid;
_VolumeParams.SecurityTimeout = value;
}
}
/// <summary>
/// Gets or sets the stream information timeout.
/// </summary>
public UInt32 StreamInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.StreamInfoTimeoutValid) ?
_VolumeParams.StreamInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.StreamInfoTimeoutValid;
_VolumeParams.StreamInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the EA information timeout.
/// </summary>
public UInt32 EaTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.EaTimeoutValid) ?
_VolumeParams.EaTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.EaTimeoutValid;
_VolumeParams.EaTimeout = value;
}
}
/// <summary>
/// Gets or sets a value that determines whether the file system is case sensitive. /// Gets or sets a value that determines whether the file system is case sensitive.
/// </summary> /// </summary>
public Boolean CaseSensitiveSearch public Boolean CaseSensitiveSearch
@ -221,6 +302,11 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); } get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); }
set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); }
} }
public Boolean WslFeatures
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.WslFeatures); }
set { _VolumeParams.Flags |= (value ? VolumeParams.WslFeatures : 0); }
}
/// <summary> /// <summary>
/// Gets or sets the prefix for a network file system. /// Gets or sets the prefix for a network file system.
/// </summary> /// </summary>
@ -274,11 +360,44 @@ namespace Fsp
/// A value of 0 disables all debug logging. /// A value of 0 disables all debug logging.
/// A value of -1 enables all debug logging. /// A value of -1 enables all debug logging.
/// </param> /// </param>
/// <returns></returns> /// <returns>STATUS_SUCCESS or error code.</returns>
public Int32 Mount(String MountPoint, public Int32 Mount(String MountPoint,
Byte[] SecurityDescriptor = null, Byte[] SecurityDescriptor = null,
Boolean Synchronized = false, Boolean Synchronized = false,
UInt32 DebugLog = 0) UInt32 DebugLog = 0)
{
return MountEx(MountPoint, 0, SecurityDescriptor, Synchronized, DebugLog);
}
/// <summary>
/// Mounts a file system.
/// </summary>
/// <param name="MountPoint">
/// The mount point for the new file system. A value of null means that
/// the file system should use the next available drive letter counting
/// downwards from Z: as its mount point.
/// </param>
/// <param name="ThreadCount">
/// Number of threads to use to service file system requests. A value
/// of 0 means that the default number of threads should be used.
/// </param>
/// <param name="SecurityDescriptor">
/// Security descriptor to use if mounting on (newly created) directory.
/// A value of null means the directory should be created with default
/// security.
/// </param>
/// <param name="Synchronized">
/// If true file system operations are synchronized using an exclusive lock.
/// </param>
/// <param name="DebugLog">
/// A value of 0 disables all debug logging.
/// A value of -1 enables all debug logging.
/// </param>
/// <returns>STATUS_SUCCESS or error code.</returns>
public Int32 MountEx(String MountPoint,
UInt32 ThreadCount,
Byte[] SecurityDescriptor = null,
Boolean Synchronized = false,
UInt32 DebugLog = 0)
{ {
Int32 Result; Int32 Result;
try try
@ -315,7 +434,7 @@ namespace Fsp
} }
if (0 <= Result) if (0 <= Result)
{ {
Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, 0); Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, ThreadCount);
if (0 > Result) if (0 > Result)
try try
{ {
@ -381,6 +500,83 @@ namespace Fsp
{ {
return Api.GetVersion(); return Api.GetVersion();
} }
/// <summary>
/// Returns a RequestHint to reference the current operation asynchronously.
/// </summary>
public UInt64 GetOperationRequestHint()
{
return Api.FspFileSystemGetOperationRequestHint();
}
/// <summary>
/// Asynchronously complete a Read operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// Number of bytes read.
/// </param>
public void SendReadResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.ReadKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/// <summary>
/// Asynchronously complete a Write operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// The number of bytes written.
/// </param>
/// <param name="FileInfo">
/// Updated file information.
/// </param>
public void SendWriteResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred, ref FileInfo FileInfo)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.WriteKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Response.WriteFileInfo = FileInfo;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/// <summary>
/// Asynchronously complete a ReadDirectory operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// Number of bytes read.
/// </param>
public void SendReadDirectoryResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.QueryDirectoryKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/* FSP_FILE_SYSTEM_INTERFACE */ /* FSP_FILE_SYSTEM_INTERFACE */
private static Byte[] ByteBufferNotNull = new Byte[0]; private static Byte[] ByteBufferNotNull = new Byte[0];
@ -472,8 +668,9 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
IntPtr SecurityDescriptor, IntPtr SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
Boolean ExtraBufferIsReparsePoint,
ref FullContext FullContext, ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo) ref OpenFileInfo OpenFileInfo)
{ {
@ -490,8 +687,9 @@ namespace Fsp
FileAttributes, FileAttributes,
Api.MakeSecurityDescriptor(SecurityDescriptor), Api.MakeSecurityDescriptor(SecurityDescriptor),
AllocationSize, AllocationSize,
Ea, ExtraBuffer,
EaLength, ExtraLength,
ExtraBufferIsReparsePoint,
out FileNode, out FileNode,
out FileDesc, out FileDesc,
out OpenFileInfo.FileInfo, out OpenFileInfo.FileInfo,

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/Interop.cs * dotnet/Interop.cs
* *
* Copyright 2015-2019 Bill Zissimopoulos * Copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -53,9 +53,16 @@ namespace Fsp.Interop
internal const UInt32 UmFileContextIsFullContext = 0x00020000; internal const UInt32 UmFileContextIsFullContext = 0x00020000;
internal const UInt32 AllowOpenInKernelMode = 0x01000000; internal const UInt32 AllowOpenInKernelMode = 0x01000000;
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000; internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
internal const UInt32 WslFeatures = 0x04000000;
internal const int PrefixSize = 192; internal const int PrefixSize = 192;
internal const int FileSystemNameSize = 16; internal const int FileSystemNameSize = 16;
internal const UInt32 VolumeInfoTimeoutValid = 0x00000001;
internal const UInt32 DirInfoTimeoutValid = 0x00000002;
internal const UInt32 SecurityTimeoutValid = 0x00000004;
internal const UInt32 StreamInfoTimeoutValid = 0x00000008;
internal const UInt32 EaTimeoutValid = 0x00000010;
internal UInt16 Version; internal UInt16 Version;
internal UInt16 SectorSize; internal UInt16 SectorSize;
internal UInt16 SectorsPerAllocationUnit; internal UInt16 SectorsPerAllocationUnit;
@ -69,6 +76,15 @@ namespace Fsp.Interop
internal UInt32 Flags; internal UInt32 Flags;
internal unsafe fixed UInt16 Prefix[PrefixSize]; internal unsafe fixed UInt16 Prefix[PrefixSize];
internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize]; internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize];
internal UInt32 AdditionalFlags;
internal UInt32 VolumeInfoTimeout;
internal UInt32 DirInfoTimeout;
internal UInt32 SecurityTimeout;
internal UInt32 StreamInfoTimeout;
internal UInt32 EaTimeout;
internal UInt32 FsextControlCode;
internal unsafe fixed UInt32 Reserved32[1];
internal unsafe fixed UInt64 Reserved64[2];
internal unsafe String GetPrefix() internal unsafe String GetPrefix()
{ {
@ -354,6 +370,65 @@ namespace Fsp.Interop
public IntPtr Information; public IntPtr Information;
} }
[StructLayout(LayoutKind.Sequential)]
internal struct IoStatus
{
internal UInt32 Information;
internal UInt32 Status;
}
internal enum FspFsctlTransact
{
ReadKind = 5,
WriteKind = 6,
QueryDirectoryKind = 14
}
[StructLayout(LayoutKind.Explicit)]
internal struct FspFsctlTransactReq
{
[FieldOffset(0)]
internal UInt16 Version;
[FieldOffset(2)]
internal UInt16 Size;
[FieldOffset(4)]
internal UInt32 Kind;
[FieldOffset(8)]
internal UInt64 Hint;
[FieldOffset(0)]
internal unsafe fixed Byte Padding[88];
}
[StructLayout(LayoutKind.Explicit)]
internal struct FspFsctlTransactRsp
{
[FieldOffset(0)]
internal UInt16 Version;
[FieldOffset(2)]
internal UInt16 Size;
[FieldOffset(4)]
internal UInt32 Kind;
[FieldOffset(8)]
internal UInt64 Hint;
[FieldOffset(16)]
internal IoStatus IoStatus;
[FieldOffset(24)]
internal FileInfo WriteFileInfo;
[FieldOffset(0)]
internal unsafe fixed Byte Padding[128];
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct FspFileSystemOperationContext
{
internal FspFsctlTransactReq *Request;
internal FspFsctlTransactRsp *Response;
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct FileSystemInterface internal struct FileSystemInterface
{ {
@ -557,8 +632,9 @@ namespace Fsp.Interop
UInt32 FileAttributes, UInt32 FileAttributes,
IntPtr SecurityDescriptor, IntPtr SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
[MarshalAs(UnmanagedType.U1)] Boolean ExtraBufferIsReparsePoint,
ref FullContext FullContext, ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo); ref OpenFileInfo OpenFileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -662,6 +738,12 @@ namespace Fsp.Interop
internal delegate Int32 FspFileSystemStopDispatcher( internal delegate Int32 FspFileSystemStopDispatcher(
IntPtr FileSystem); IntPtr FileSystem);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void FspFileSystemSendResponse(
IntPtr FileSystem,
ref FspFsctlTransactRsp Response);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal unsafe delegate FspFileSystemOperationContext *FspFileSystemGetOperationContext();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr FspFileSystemMountPointF( internal delegate IntPtr FspFileSystemMountPointF(
IntPtr FileSystem); IntPtr FileSystem);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -846,6 +928,8 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint; internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint;
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher; internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher; internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse;
internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext;
internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint; internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint;
internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy; internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy;
internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog; internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog;
@ -892,6 +976,10 @@ namespace Fsp.Interop
else else
return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero); return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero);
} }
internal static unsafe UInt64 FspFileSystemGetOperationRequestHint()
{
return FspFileSystemGetOperationContext()->Request->Hint;
}
internal static unsafe Boolean FspFileSystemAddDirInfo( internal static unsafe Boolean FspFileSystemAddDirInfo(
ref DirInfo DirInfo, ref DirInfo DirInfo,
IntPtr Buffer, IntPtr Buffer,
@ -1240,6 +1328,8 @@ namespace Fsp.Interop
FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module); FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module);
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module); FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module); FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
FspFileSystemSendResponse = GetEntryPoint<Proto.FspFileSystemSendResponse>(Module);
FspFileSystemGetOperationContext = GetEntryPoint<Proto.FspFileSystemGetOperationContext>(Module);
FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module); FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module);
FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module); FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module);
FspFileSystemSetDebugLog = GetEntryPoint<Proto.FspFileSystemSetDebugLogF>(Module); FspFileSystemSetDebugLog = GetEntryPoint<Proto.FspFileSystemSetDebugLogF>(Module);

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/Service.cs * dotnet/Service.cs
* *
* Copyright 2015-2019 Bill Zissimopoulos * Copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file fsptool/fsptool.c * @file fsptool/fsptool.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

227
src/ku/library.h Normal file
View File

@ -0,0 +1,227 @@
/**
* @file ku/library.h
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef WINFSP_KU_LIBRARY_H_INCLUDED
#define WINFSP_KU_LIBRARY_H_INCLUDED
#if !defined(_KERNEL_MODE)
#include <dll/library.h>
#include <aclapi.h>
#define _NTDEF_
#include <ntsecapi.h>
#define FSP_KU_CODE ((void)0)
#else
#include <sys/driver.h>
#define FSP_KU_CODE PAGED_CODE(); NTSTATUS fsp_ku_status = STATUS_SUCCESS; (VOID)fsp_ku_status
#define FSP_API FSP_DDI
#define BYTE UINT8
#define BOOL BOOLEAN
#define LPBOOL PBOOLEAN
#define UINT ULONG
#define GetLastError() ((DWORD)fsp_ku_status)
#define FspNtStatusFromWin32(Err) ((NTSTATUS)(Err))
#define ERROR_INSUFFICIENT_BUFFER STATUS_BUFFER_TOO_SMALL
#define InitOnceExecuteOnce(I, F, P, C) RtlRunOnceExecuteOnce(I, F, P, C)
#define INIT_ONCE RTL_RUN_ONCE
#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
#define AddAccessAllowedAce(Acl, Rev, Acc, Sid)\
(fsp_ku_status = RtlAddAccessAllowedAce(Acl, Rev, Acc, Sid),\
NT_SUCCESS(fsp_ku_status))
#define AddAccessDeniedAce(Acl, Rev, Acc, Sid)\
(fsp_ku_status = FspKuAddAccessDeniedAce(Acl, Rev, Acc, Sid),\
NT_SUCCESS(fsp_ku_status))
#define EqualSid(Sid1, Sid2) (fsp_ku_status = 0, RtlEqualSid(Sid1, Sid2))
#define GetAce(Acl, Idx, Ace) (fsp_ku_status = RtlGetAce(Acl, Idx, Ace), NT_SUCCESS(fsp_ku_status))
#define GetAclInformation(Acl, Inf, Len, Cls)\
(fsp_ku_status = FspKuQueryInformationAcl(Acl, Inf, Len, Cls),\
NT_SUCCESS(fsp_ku_status))
#define GetLengthSid(Sid) (fsp_ku_status = 0, RtlLengthSid(Sid))
#define GetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
(fsp_ku_status = RtlGetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSecurityDescriptorGroup(Sec, Grp, Def)\
(fsp_ku_status = RtlGetGroupSecurityDescriptor(Sec, Grp, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSecurityDescriptorOwner(Sec, Own, Def)\
(fsp_ku_status = RtlGetOwnerSecurityDescriptor(Sec, Own, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSidIdentifierAuthority(Sid) (fsp_ku_status = 0, &((PISID)(Sid))->IdentifierAuthority)
#define GetSidSubAuthority(Sid, Sub) (fsp_ku_status = 0, RtlSubAuthoritySid(Sid, Sub))
#define GetSidSubAuthorityCount(Sid) (fsp_ku_status = 0, RtlSubAuthorityCountSid(Sid))
#define InitializeAcl(Acl, Len, Rev) (fsp_ku_status = RtlCreateAcl(Acl, Len, Rev), NT_SUCCESS(fsp_ku_status))
#define InitializeSecurityDescriptor(Sec, Rev)\
(fsp_ku_status = RtlCreateSecurityDescriptor(Sec, Rev),\
NT_SUCCESS(fsp_ku_status))
#define InitializeSid(Sid, Aut, Cnt) (fsp_ku_status = RtlInitializeSid(Sid, Aut, Cnt), NT_SUCCESS(fsp_ku_status))
#define IsValidSid(Sid) (RtlValidSid(Sid) || (fsp_ku_status = STATUS_INVALID_SID, FALSE))
#define MakeSelfRelativeSD(Abs, Rel, Len)\
(fsp_ku_status = RtlAbsoluteToSelfRelativeSD(Abs, Rel, Len),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorControl(Sec, Msk, Bit)\
(fsp_ku_status = FspKuSetControlSecurityDescriptor(Sec, Msk, Bit),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
(fsp_ku_status = RtlSetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorGroup(Sec, Grp, Def)\
(fsp_ku_status = RtlSetGroupSecurityDescriptor(Sec, Grp, Def),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorOwner(Sec, Own, Def)\
(fsp_ku_status = RtlSetOwnerSecurityDescriptor(Sec, Own, Def),\
NT_SUCCESS(fsp_ku_status))
static inline NTSTATUS FspKuAddAccessDeniedAce(
PACL Acl,
ULONG AceRevision,
ACCESS_MASK AccessMask,
PSID Sid)
{
/* We are missing RtlAddAccessDeniedAce. So we need this malarkey! */
NTSTATUS Result;
PACE_HEADER Ace;
Result = RtlAddAccessAllowedAce(Acl, AceRevision, AccessMask, Sid);
if (!NT_SUCCESS(Result))
return Result;
Result = RtlGetAce(Acl, Acl->AceCount - 1, &Ace);
if (!NT_SUCCESS(Result))
return Result;
Ace->AceType = ACCESS_DENIED_ACE_TYPE;
return STATUS_SUCCESS;
}
typedef enum
{
AclRevisionInformation__DO_NOT_USE = 1,
AclSizeInformation,
} ACL_INFORMATION_CLASS;
typedef struct
{
DWORD AceCount;
DWORD AclBytesInUse__DO_NOT_USE;
DWORD AclBytesFree__DO_NOT_USE;
} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
static inline NTSTATUS FspKuQueryInformationAcl(
PACL Acl,
PVOID AclInformation,
ULONG AclInformationLength,
ACL_INFORMATION_CLASS AclInformationClass)
{
ASSERT(AclSizeInformation == AclInformationClass);
ASSERT(sizeof(ACL_SIZE_INFORMATION) <= AclInformationLength);
((PACL_SIZE_INFORMATION)AclInformation)->AceCount = Acl->AceCount;
return STATUS_SUCCESS;
}
static inline NTSTATUS FspKuSetControlSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor,
SECURITY_DESCRIPTOR_CONTROL ControlMask,
SECURITY_DESCRIPTOR_CONTROL ControlBits)
{
((PUSHORT)(SecurityDescriptor))[1] &= ~ControlMask;
((PUSHORT)(SecurityDescriptor))[1] |= ControlBits;
return STATUS_SUCCESS;
}
#define WideCharToMultiByte(C, F, W, w, B, b, D, d)\
(FspKuWideCharToMultiByte(C, F, W, w, B, b, D, d, &fsp_ku_status))
#define MultiByteToWideChar(C, F, B, b, W, w)\
(FspKuMultiByteToWideChar(C, F, B, b, W, w, &fsp_ku_status))
#define CP_UTF8 65001
static inline int FspKuWideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWCH lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCCH lpDefaultChar,
LPBOOL lpUsedDefaultChar,
PNTSTATUS PResult)
{
ASSERT(CP_UTF8 == CodePage);
ASSERT(0 == dwFlags);
ASSERT(0 == lpDefaultChar);
ASSERT(0 == lpUsedDefaultChar);
NTSTATUS Result;
ULONG ByteCount;
if (-1 == cchWideChar)
cchWideChar = (int)wcslen(lpWideCharStr) + 1;
Result = RtlUnicodeToUTF8N(
lpMultiByteStr, cbMultiByte, &ByteCount,
lpWideCharStr, cchWideChar * sizeof(WCHAR));
if (STATUS_SOME_NOT_MAPPED == Result)
Result = STATUS_SUCCESS;
else if (!NT_SUCCESS(Result))
return 0;
*PResult = Result;
return ByteCount;
}
static inline int FspKuMultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCCH lpMultiByteStr,
int cbMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar,
PNTSTATUS PResult)
{
ASSERT(CP_UTF8 == CodePage);
ASSERT(0 == dwFlags);
NTSTATUS Result;
ULONG ByteCount;
if (-1 == cbMultiByte)
cbMultiByte = (int)strlen(lpMultiByteStr) + 1;
Result = RtlUTF8ToUnicodeN(
lpWideCharStr, cchWideChar * sizeof(WCHAR), &ByteCount,
lpMultiByteStr, cbMultiByte);
if (STATUS_SOME_NOT_MAPPED == Result)
Result = STATUS_SUCCESS;
else if (!NT_SUCCESS(Result))
return 0;
*PResult = Result;
return ByteCount / sizeof(WCHAR);
}
static inline PGENERIC_MAPPING FspGetFileGenericMapping(VOID)
{
return IoGetFileObjectGenericMapping();
}
static inline void *MemAlloc(size_t Size)
{
return FspAlloc(Size);
}
static inline void MemFree(void *Pointer)
{
if (0 != Pointer)
FspFree(Pointer);
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/** /**
* @file dll/posix.c * @file ku/posix.c
* POSIX Interop. * POSIX Interop.
* *
* This file provides routines for Windows/POSIX interoperability. It is based * This file provides routines for Windows/POSIX interoperability. It is based
@ -14,7 +14,7 @@
* [SNAME] * [SNAME]
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html * https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -32,15 +32,67 @@
* associated repository. * associated repository.
*/ */
#include <dll/library.h> #include <ku/library.h>
#include <aclapi.h>
#define _NTDEF_
#include <ntsecapi.h>
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid);
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid);
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...); static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...);
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode);
FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
BOOLEAN Translate);
FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
BOOLEAN Translate);
FSP_API VOID FspPosixDeletePath(void *Path);
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT; #if defined(_KERNEL_MODE)
union #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspPosixMapUidToSid)
#pragma alloc_text(PAGE, FspPosixMapSidToUid)
#pragma alloc_text(PAGE, FspPosixCreateSid)
#pragma alloc_text(PAGE, FspDeleteSid)
#pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor)
#pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions)
#pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx)
#pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx)
#pragma alloc_text(PAGE, FspPosixDeletePath)
#pragma alloc_text(PAGE, FspPosixEncodeWindowsPath)
#pragma alloc_text(PAGE, FspPosixDecodeWindowsPath)
#endif
#endif
static union
{
SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
} FspWorldSidBuf =
{
/* S-1-1-0 */
.V.Revision = SID_REVISION,
.V.SubAuthorityCount = 1,
.V.IdentifierAuthority.Value[5] = 1,
.V.SubAuthority[0] = 0,
};
static union
{
SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
} FspAuthUsersSidBuf =
{
/* S-1-5-11 */
.V.Revision = SID_REVISION,
.V.SubAuthorityCount = 1,
.V.IdentifierAuthority.Value[5] = 5,
.V.SubAuthority[0] = 11,
};
static union
{ {
SID V; SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))]; UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
@ -52,11 +104,15 @@ union
.V.IdentifierAuthority.Value[5] = 0, .V.IdentifierAuthority.Value[5] = 0,
.V.SubAuthority[0] = 65534, .V.SubAuthority[0] = 65534,
}; };
static PISID FspAccountDomainSid, FspPrimaryDomainSid;
#define FspWorldSid (&FspWorldSidBuf.V)
#define FspAuthUsersSid (&FspAuthUsersSidBuf.V)
#define FspUnmappedSid (&FspUnmappedSidBuf.V) #define FspUnmappedSid (&FspUnmappedSidBuf.V)
#define FspUnmappedUid (65534) #define FspUnmappedUid (65534)
static PISID FspAccountDomainSid, FspPrimaryDomainSid;
static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
#if !defined(_KERNEL_MODE)
static BOOL WINAPI FspPosixInitialize( static BOOL WINAPI FspPosixInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
@ -120,9 +176,79 @@ VOID FspPosixFinalize(BOOLEAN Dynamic)
MemFree(FspPrimaryDomainSid); MemFree(FspPrimaryDomainSid);
} }
} }
#else
ULONG NTAPI FspPosixInitialize(
PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context)
{
static union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} FspAccountDomainSidBuf;
static union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} FspPrimaryDomainSidBuf;
UNICODE_STRING Path;
UNICODE_STRING Name;
union
{
KEY_VALUE_PARTIAL_INFORMATION V;
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + SECURITY_MAX_SID_SIZE];
} Value;
ULONG Length;
NTSTATUS Result;
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\SECURITY\\Policy\\PolAcDmS");
RtlZeroMemory(&Name, sizeof Name);
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (NT_SUCCESS(Result) && REG_NONE == Value.V.Type &&
sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
{
RtlCopyMemory(&FspAccountDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
FspAccountDomainSid = &FspAccountDomainSidBuf.V;
}
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\SECURITY\\Policy\\PolPrDmS");
RtlZeroMemory(&Name, sizeof Name);
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (NT_SUCCESS(Result) && REG_NONE == Value.V.Type &&
sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
{
RtlCopyMemory(&FspPrimaryDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V;
}
return TRUE;
}
#endif
static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2)
{
if (Sid1->Revision != Sid2->Revision)
return FALSE;
if (Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0] ||
Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1] ||
Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2] ||
Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3] ||
Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4] ||
Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5])
return FALSE;
if (Sid1->SubAuthorityCount + 1 != Sid2->SubAuthorityCount)
return FALSE;
for (ULONG I = 0; Sid1->SubAuthorityCount > I; I++)
if (Sid1->SubAuthority[I] != Sid2->SubAuthority[I])
return FALSE;
return TRUE;
}
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
{ {
FSP_KU_CODE;
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
*PSid = 0; *PSid = 0;
@ -221,7 +347,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
* S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y * S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y
*/ */
else if (0x10000 <= Uid && Uid < 0x11000) else if (0x10000 <= Uid && Uid < 0x11000)
*PSid = FspPosixCreateSid((Uid - 0x10000) >> 8, 1, (Uid - 0x10000) & 0xff); *PSid = FspPosixCreateSid((BYTE)((Uid - 0x10000) >> 8), 1, (Uid - 0x10000) & 0xff);
/* [IDMAP] /* [IDMAP]
* Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID): * Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID):
@ -238,13 +364,15 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid) FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
{ {
FSP_KU_CODE;
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
BYTE Authority; BYTE Authority;
BYTE Count; BYTE Count;
UINT32 SubAuthority0, Rid; UINT32 SubAuthority0, Rid;
*PUid = -1; *PUid = (UINT32)-1;
if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid))) if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid)))
return STATUS_INVALID_SID; return STATUS_INVALID_SID;
@ -298,12 +426,11 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
* has PrimaryDomainSid == AccountDomainSid. * has PrimaryDomainSid == AccountDomainSid.
*/ */
BOOL EqualDomains = FALSE;
if (0 != FspPrimaryDomainSid && if (0 != FspPrimaryDomainSid &&
EqualDomainSid(FspPrimaryDomainSid, Sid, &EqualDomains) && EqualDomains) FspPosixIsRelativeSid(FspPrimaryDomainSid, Sid))
*PUid = 0x100000 + Rid; *PUid = 0x100000 + Rid;
else if (0 != FspAccountDomainSid && else if (0 != FspAccountDomainSid &&
EqualDomainSid(FspAccountDomainSid, Sid, &EqualDomains) && EqualDomains) FspPosixIsRelativeSid(FspAccountDomainSid, Sid))
*PUid = 0x30000 + Rid; *PUid = 0x30000 + Rid;
/* /*
@ -348,6 +475,8 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...) static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
{ {
FSP_KU_CODE;
PISID Sid; PISID Sid;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority; SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
va_list ap; va_list ap;
@ -370,6 +499,8 @@ static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()) FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)())
{ {
FSP_KU_CODE;
if (FspUnmappedSid == Sid) if (FspUnmappedSid == Sid)
; ;
else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc) else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc)
@ -439,7 +570,9 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode, UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor) PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{ {
PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0; FSP_KU_CODE;
PSID OwnerSid = 0, GroupSid = 0;
UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm; UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm;
PACL Acl = 0; PACL Acl = 0;
SECURITY_DESCRIPTOR SecurityDescriptor; SECURITY_DESCRIPTOR SecurityDescriptor;
@ -457,13 +590,6 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
WorldSid = FspWksidGet(WinWorldSid);
if (0 == WorldSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
OwnerPerm = (Mode & 0700) >> 6; OwnerPerm = (Mode & 0700) >> 6;
GroupPerm = (Mode & 0070) >> 3; GroupPerm = (Mode & 0070) >> 3;
WorldPerm = (Mode & 0007); WorldPerm = (Mode & 0007);
@ -502,7 +628,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny); sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny);
Size += GetLengthSid(OwnerSid) - sizeof(DWORD); Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
Size += GetLengthSid(GroupSid) - sizeof(DWORD); Size += GetLengthSid(GroupSid) - sizeof(DWORD);
Size += GetLengthSid(WorldSid) - sizeof(DWORD); Size += GetLengthSid(FspWorldSid) - sizeof(DWORD);
if (OwnerDeny) if (OwnerDeny)
Size += GetLengthSid(OwnerSid) - sizeof(DWORD); Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
if (GroupDeny) if (GroupDeny)
@ -546,7 +672,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!AddAccessAllowedAce(Acl, ACL_REVISION, if (!AddAccessAllowedAce(Acl, ACL_REVISION,
FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm), FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm),
WorldSid)) FspWorldSid))
goto lasterror; goto lasterror;
if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
@ -599,6 +725,20 @@ lasterror:
goto exit; goto exit;
} }
static inline ACCESS_MASK FspPosixCanonicalizeAccessMask(ACCESS_MASK AccessMask)
{
PGENERIC_MAPPING Mapping = FspGetFileGenericMapping();
if (AccessMask & GENERIC_READ)
AccessMask |= Mapping->GenericRead;
if (AccessMask & GENERIC_WRITE)
AccessMask |= Mapping->GenericWrite;
if (AccessMask & GENERIC_EXECUTE)
AccessMask |= Mapping->GenericExecute;
if (AccessMask & GENERIC_ALL)
AccessMask |= Mapping->GenericAll;
return AccessMask & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
}
static inline UINT32 FspPosixMapAccessMaskToPermission(ACCESS_MASK AccessMask) static inline UINT32 FspPosixMapAccessMaskToPermission(ACCESS_MASK AccessMask)
{ {
/* [PERMS] /* [PERMS]
@ -621,7 +761,17 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode) PUINT32 PUid, PUINT32 PGid, PUINT32 PMode)
{ {
PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0, AuthUsersSid = 0; FSP_KU_CODE;
BOOLEAN OwnerOptional = (UINT_PTR)PUid & 1;
PUid = (PVOID)((UINT_PTR)PUid & ~1);
UINT32 OrigUid = *PUid;
BOOLEAN GroupOptional = (UINT_PTR)PGid & 1;
PGid = (PVOID)((UINT_PTR)PGid & ~1);
UINT32 OrigGid = *PGid;
PSID OwnerSid = 0, GroupSid = 0;
BOOL Defaulted, DaclPresent; BOOL Defaulted, DaclPresent;
PACL Acl = 0; PACL Acl = 0;
ACL_SIZE_INFORMATION AclSizeInfo; ACL_SIZE_INFORMATION AclSizeInfo;
@ -629,6 +779,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSID AceSid; PSID AceSid;
DWORD AceAccessMask; DWORD AceAccessMask;
DWORD OwnerAllow, OwnerDeny, GroupAllow, GroupDeny, WorldAllow, WorldDeny; DWORD OwnerAllow, OwnerDeny, GroupAllow, GroupDeny, WorldAllow, WorldDeny;
UINT32 AceUid = 0;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
NTSTATUS Result; NTSTATUS Result;
@ -643,30 +794,26 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Acl, &Defaulted)) if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Acl, &Defaulted))
goto lasterror; goto lasterror;
Result = FspPosixMapSidToUid(OwnerSid, &Uid); if (0 == OwnerSid && OwnerOptional)
if (!NT_SUCCESS(Result)) Uid = OrigUid;
goto exit; else
{
Result = FspPosixMapSidToUid(OwnerSid, &Uid);
if (!NT_SUCCESS(Result))
goto exit;
}
Result = FspPosixMapSidToUid(GroupSid, &Gid); if (0 == GroupSid && GroupOptional)
if (!NT_SUCCESS(Result)) Gid = OrigGid;
goto exit; else
{
Result = FspPosixMapSidToUid(GroupSid, &Gid);
if (!NT_SUCCESS(Result))
goto exit;
}
if (0 != Acl) if (0 != Acl)
{ {
WorldSid = FspWksidGet(WinWorldSid);
if (0 == WorldSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
if (0 == AuthUsersSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0; OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation)) if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation))
@ -696,12 +843,14 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
else else
continue; continue;
AceAccessMask = FspPosixCanonicalizeAccessMask(AceAccessMask);
/* [PERMS] /* [PERMS]
* If the ACE contains the Authenticated Users SID or the World SID then * If the ACE contains the Authenticated Users SID or the World SID then
* add the allowed or denied access right bits into the "owner", "group" * add the allowed or denied access right bits into the "owner", "group"
* and "other" collections. * and "other" collections.
*/ */
if (EqualSid(WorldSid, AceSid) || EqualSid(AuthUsersSid, AceSid)) if (EqualSid(FspWorldSid, AceSid) || EqualSid(FspAuthUsersSid, AceSid))
{ {
/* [PERMS] /* [PERMS]
* If this is an access-denied ACE, then add each access right to the set * If this is an access-denied ACE, then add each access right to the set
@ -726,6 +875,9 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
} }
else else
{ {
if (0 == OwnerSid || 0 == GroupSid)
FspPosixMapSidToUid(AceSid, &AceUid);
/* [PERMS] /* [PERMS]
* Note that if the file owner and file group SIDs are the same, * Note that if the file owner and file group SIDs are the same,
* then the access rights are saved in both the "owner" and "group" * then the access rights are saved in both the "owner" and "group"
@ -737,7 +889,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* in the "group" collection as appropriate in the corresponding set of * in the "group" collection as appropriate in the corresponding set of
* granted or denied rights (as described above). * granted or denied rights (as described above).
*/ */
if (EqualSid(GroupSid, AceSid)) if (0 != GroupSid ? EqualSid(GroupSid, AceSid) : (Gid == AceUid))
{ {
if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType) if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType)
GroupAllow |= AceAccessMask & ~GroupDeny; GroupAllow |= AceAccessMask & ~GroupDeny;
@ -750,7 +902,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* in the "owner" collection as appropriate in the corresponding set of * in the "owner" collection as appropriate in the corresponding set of
* granted or denied rights (as described above). * granted or denied rights (as described above).
*/ */
if (EqualSid(OwnerSid, AceSid)) if (0 != OwnerSid ? EqualSid(OwnerSid, AceSid) : (Uid == AceUid))
{ {
if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType) if (ACCESS_ALLOWED_ACE_TYPE == Ace->AceType)
OwnerAllow |= AceAccessMask & ~OwnerDeny; OwnerAllow |= AceAccessMask & ~OwnerDeny;
@ -812,6 +964,8 @@ static UINT32 FspPosixInvalidPathChars[4] =
FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
BOOLEAN Translate) BOOLEAN Translate)
{ {
FSP_KU_CODE;
NTSTATUS Result; NTSTATUS Result;
ULONG Size; ULONG Size;
char *PosixPath = 0, *p, *q; char *PosixPath = 0, *p, *q;
@ -874,6 +1028,8 @@ lasterror:
FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
BOOLEAN Translate) BOOLEAN Translate)
{ {
FSP_KU_CODE;
NTSTATUS Result; NTSTATUS Result;
ULONG Size; ULONG Size;
PWSTR WindowsPath = 0, p; PWSTR WindowsPath = 0, p;
@ -925,11 +1081,15 @@ lasterror:
FSP_API VOID FspPosixDeletePath(void *Path) FSP_API VOID FspPosixDeletePath(void *Path)
{ {
FSP_KU_CODE;
MemFree(Path); MemFree(Path);
} }
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size) FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{ {
FSP_KU_CODE;
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{ {
WCHAR c = *p; WCHAR c = *p;
@ -944,6 +1104,8 @@ FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size) FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{ {
FSP_KU_CODE;
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{ {
WCHAR c = *p; WCHAR c = *p;

134
src/ku/uuid5.c Normal file
View File

@ -0,0 +1,134 @@
/**
* @file dll/uuid5.c
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <ku/library.h>
#include <bcrypt.h>
/*
* This module is used to create UUID v5 identifiers. UUID v5 identifiers
* are effectively SHA1 hashes that are modified to fit within the UUID
* format. The resulting identifiers use version 5 and variant 2. The hash
* is taken over the concatenation of a namespace ID and a name; the namespace
* ID is another UUID and the name can be any string of bytes ("octets").
*
* For details see RFC 4122: https://tools.ietf.org/html/rfc4122
*/
NTSTATUS FspUuid5Make(const UUID *Namespace, const VOID *Buffer, ULONG Size, UUID *Uuid)
{
BCRYPT_ALG_HANDLE ProvHandle = 0;
BCRYPT_HASH_HANDLE HashHandle = 0;
UINT8 Temp[20];
NTSTATUS Result;
/*
* Windows UUID's are encoded in little-endian format. RFC 4122 specifies that for
* UUID v5 computation, UUID's must be converted to/from big-endian.
*
* Note that Windows is always little-endian:
* https://community.osr.com/discussion/comment/146810/#Comment_146810
*/
/* copy Namespace to local buffer in network byte order (big-endian) */
Temp[ 0] = ((PUINT8)Namespace)[ 3];
Temp[ 1] = ((PUINT8)Namespace)[ 2];
Temp[ 2] = ((PUINT8)Namespace)[ 1];
Temp[ 3] = ((PUINT8)Namespace)[ 0];
Temp[ 4] = ((PUINT8)Namespace)[ 5];
Temp[ 5] = ((PUINT8)Namespace)[ 4];
Temp[ 6] = ((PUINT8)Namespace)[ 7];
Temp[ 7] = ((PUINT8)Namespace)[ 6];
Temp[ 8] = ((PUINT8)Namespace)[ 8];
Temp[ 9] = ((PUINT8)Namespace)[ 9];
Temp[10] = ((PUINT8)Namespace)[10];
Temp[11] = ((PUINT8)Namespace)[11];
Temp[12] = ((PUINT8)Namespace)[12];
Temp[13] = ((PUINT8)Namespace)[13];
Temp[14] = ((PUINT8)Namespace)[14];
Temp[15] = ((PUINT8)Namespace)[15];
/*
* Unfortunately we cannot reuse the hashing object, because BCRYPT_HASH_REUSABLE_FLAG
* is available in Windows 8 and later. (WinFsp currently supports Windows 7 or later).
*/
Result = BCryptOpenAlgorithmProvider(&ProvHandle, BCRYPT_SHA1_ALGORITHM, 0, 0);
if (!NT_SUCCESS(Result))
goto exit;
Result = BCryptCreateHash(ProvHandle, &HashHandle, 0, 0, 0, 0, 0);
if (!NT_SUCCESS(Result))
goto exit;
Result = BCryptHashData(HashHandle, (PVOID)Temp, 16, 0);
if (!NT_SUCCESS(Result))
goto exit;
Result = BCryptHashData(HashHandle, (PVOID)Buffer, Size, 0);
if (!NT_SUCCESS(Result))
goto exit;
Result = BCryptFinishHash(HashHandle, Temp, 20, 0);
if (!NT_SUCCESS(Result))
goto exit;
/* copy local buffer to Uuid in host byte order (little-endian) */
((PUINT8)Uuid)[ 0] = Temp[ 3];
((PUINT8)Uuid)[ 1] = Temp[ 2];
((PUINT8)Uuid)[ 2] = Temp[ 1];
((PUINT8)Uuid)[ 3] = Temp[ 0];
((PUINT8)Uuid)[ 4] = Temp[ 5];
((PUINT8)Uuid)[ 5] = Temp[ 4];
((PUINT8)Uuid)[ 6] = Temp[ 7];
((PUINT8)Uuid)[ 7] = Temp[ 6];
((PUINT8)Uuid)[ 8] = Temp[ 8];
((PUINT8)Uuid)[ 9] = Temp[ 9];
((PUINT8)Uuid)[10] = Temp[10];
((PUINT8)Uuid)[11] = Temp[11];
((PUINT8)Uuid)[12] = Temp[12];
((PUINT8)Uuid)[13] = Temp[13];
((PUINT8)Uuid)[14] = Temp[14];
((PUINT8)Uuid)[15] = Temp[15];
/* [RFC 4122 Section 4.3]
* Set the four most significant bits (bits 12 through 15) of the
* time_hi_and_version field to the appropriate 4-bit version number
* from Section 4.1.3.
*/
Uuid->Data3 = (5 << 12) | (Uuid->Data3 & 0x0fff);
/* [RFC 4122 Section 4.3]
* Set the two most significant bits (bits 6 and 7) of the
* clock_seq_hi_and_reserved to zero and one, respectively.
*/
Uuid->Data4[0] = (2 << 6) | (Uuid->Data4[0] & 0x3f);
Result = STATUS_SUCCESS;
exit:
if (0 != HashHandle)
BCryptDestroyHash(HashHandle);
if (0 != ProvHandle)
BCryptCloseAlgorithmProvider(ProvHandle, 0);
return Result;
}

View File

@ -1,7 +1,7 @@
/** /**
* @file launcher/launchctl.c * @file launcher/launchctl.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file launcher/launcher.c * @file launcher/launcher.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -503,24 +503,19 @@ static SVC_INSTANCE *SvcInstanceLookup(PWSTR ClassName, PWSTR InstanceName)
return 0; return 0;
} }
static ULONG SvcInstanceArgumentLength(PWSTR Arg) static inline ULONG SvcInstanceArgumentLength(PWSTR Arg, PWSTR Pattern)
{ {
ULONG Length; PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern);
Length = 2; /* for beginning and ending quotes */ return 2 + (ULONG)(UINT_PTR)PathTransform(0, Arg, Pattern);
for (PWSTR P = Arg; *P; P++)
if (L'"' != *P)
Length++;
return Length;
} }
static PWSTR SvcInstanceArgumentCopy(PWSTR Dest, PWSTR Arg) static inline PWSTR SvcInstanceArgumentCopy(PWSTR Dest, PWSTR Arg, PWSTR Pattern)
{ {
PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern);
*Dest++ = L'"'; *Dest++ = L'"';
for (PWSTR P = Arg; *P; P++) Dest = PathTransform(Dest, Arg, Pattern);
if (L'"' != *P)
*Dest++ = *P;
*Dest++ = L'"'; *Dest++ = L'"';
return Dest; return Dest;
@ -532,6 +527,7 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
PWSTR NewString = 0, P, Q; PWSTR NewString = 0, P, Q;
PWSTR EmptyArg = L""; PWSTR EmptyArg = L"";
ULONG Length; ULONG Length;
PWSTR Pattern;
*PNewString = 0; *PNewString = 0;
@ -541,24 +537,36 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
switch (*P) switch (*P)
{ {
case L'%': case L'%':
Pattern = 0;
P++; P++;
if (L'\\' == *P)
{
Pattern = ++P;
while (!(L'\0' == *P ||
(L'0' <= *P && *P <= '9') ||
(L'A' <= *P && *P <= 'Z')))
P++;
}
if (L'0' <= *P && *P <= '9') if (L'0' <= *P && *P <= '9')
{ {
if (Argc > (ULONG)(*P - L'0')) if (Argc > (ULONG)(*P - L'0'))
Length += SvcInstanceArgumentLength(Argv[*P - L'0']); Length += SvcInstanceArgumentLength(Argv[*P - L'0'], Pattern);
else else
Length += SvcInstanceArgumentLength(EmptyArg); Length += SvcInstanceArgumentLength(EmptyArg, 0);
} }
else else
if (L'U' == *P) if (L'U' == *P)
{ {
if (0 != SvcInstanceUserName()) if (0 != SvcInstanceUserName())
Length += SvcInstanceArgumentLength(SvcInstanceUserName()); Length += SvcInstanceArgumentLength(SvcInstanceUserName(), Pattern);
else else
Length += SvcInstanceArgumentLength(EmptyArg); Length += SvcInstanceArgumentLength(EmptyArg, 0);
} }
else else
if (*P)
Length++; Length++;
else
P--;
break; break;
default: default:
Length++; Length++;
@ -575,24 +583,36 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
switch (*P) switch (*P)
{ {
case L'%': case L'%':
Pattern = 0;
P++; P++;
if (L'\\' == *P)
{
Pattern = ++P;
while (!(L'\0' == *P ||
(L'0' <= *P && *P <= '9') ||
(L'A' <= *P && *P <= 'Z')))
P++;
}
if (L'0' <= *P && *P <= '9') if (L'0' <= *P && *P <= '9')
{ {
if (Argc > (ULONG)(*P - L'0')) if (Argc > (ULONG)(*P - L'0'))
Q = SvcInstanceArgumentCopy(Q, Argv[*P - L'0']); Q = SvcInstanceArgumentCopy(Q, Argv[*P - L'0'], Pattern);
else else
Q = SvcInstanceArgumentCopy(Q, EmptyArg); Q = SvcInstanceArgumentCopy(Q, EmptyArg, 0);
} }
else else
if (L'U' == *P) if (L'U' == *P)
{ {
if (0 != SvcInstanceUserName()) if (0 != SvcInstanceUserName())
Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName()); Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName(), Pattern);
else else
Q = SvcInstanceArgumentCopy(Q, EmptyArg); Q = SvcInstanceArgumentCopy(Q, EmptyArg, 0);
} }
else else
if (*P)
*Q++ = *P; *Q++ = *P;
else
P--;
break; break;
default: default:
*Q++ = *P; *Q++ = *P;

182
src/launcher/ptrans.c Normal file
View File

@ -0,0 +1,182 @@
/**
* @file launcher/ptrans.c
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
/**
* Path Transformation Language
*
* Syntax:
* PERCENT BACKLASH replace-sep *(*sep component) [*sep UNDERSCORE] arg
*
* Arg:
* The command line argument that a rule is applied on. These are denoted
* by digits [0-9] or a capital letter (A-Z).
*
* Component:
* A path component denoted by a small letter (a-z). The letter a denotes
* the first path component, the letter b the second path component, etc.
*
* UNDERSCORE:
* The UNDERSCORE (_) denotes the "rest of the path". This is any path
* left after any path components explicitly mentioned by using small
* letters (a-z).
*
* Sep:
* A separator symbol that is used to separated components.
* E.g. slash (/), colon (:), etc.
*
* Replace-sep:
* A separator symbol that replaces the backslash (\) separator in the
* "rest of the path" (UNDERSCORE). E.g. slash (/), colon (:), etc.
*
*
* Examples:
* - %\/b:_1
* - Transforms \rclone\REMOTE\PATH\TO\FILES to REMOTE:PATH/TO/FILES
* - %\/b:/_1
* - Transforms \rclone\REMOTE\PATH\TO\FILES to REMOTE:/PATH/TO/FILES
* - %\/_1
* - Transforms \P1\P2\P3 to /P1/P2/P3
* - %\+_1
* - Transforms \P1\P2\P3 to +P1+P2+P3
* - %\\_1
* - Transforms \P1\P2\P3 to \\P1\\P2\\P3
* (Backslash is doubled up when used as a replacement separator!)
*/
#include <winfsp/launch.h>
#include <shared/minimal.h>
static PWSTR PathCopy(PWSTR Dest, PWSTR Arg, PWSTR ArgEnd, BOOLEAN WriteDest, WCHAR Replacement)
{
if (0 != Replacement)
{
for (PWSTR P = Arg, EndP = (0 != ArgEnd ? ArgEnd : (PWSTR)(UINT_PTR)~0); EndP > P && *P; P++)
if (L'\\' == *P)
{
if (L'\\' == Replacement)
{
if (WriteDest)
*Dest = Replacement;
Dest++;
}
if (WriteDest)
*Dest = Replacement;
Dest++;
}
else if (L'"' != *P)
{
if (WriteDest)
*Dest = *P;
Dest++;
}
}
else
{
for (PWSTR P = Arg, EndP = (0 != ArgEnd ? ArgEnd : (PWSTR)(UINT_PTR)~0); EndP > P && *P; P++)
if (L'"' != *P)
{
if (WriteDest)
*Dest = *P;
Dest++;
}
}
return Dest;
}
static inline BOOLEAN PatternEnd(WCHAR C)
{
return L'\0' == C ||
(L'0' <= C && C <= '9') ||
(L'A' <= C && C <= 'Z');
}
PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern)
{
BOOLEAN WriteDest = 0 != Dest;
WCHAR Replacement;
PWSTR Components[26][2];
PWSTR Remainder = Arg;
ULONG RemainderIndex = 0;
PWSTR P;
if (0 == Pattern)
return PathCopy(Dest, Arg, 0, WriteDest, 0);
for (ULONG I = 0; 26 > I; I++)
Components[I][0] = 0;
Replacement = *Pattern++;
if (PatternEnd(Replacement))
return Dest;
while (!PatternEnd(*Pattern))
{
if (L'a' <= *Pattern && *Pattern <= 'z')
{
ULONG I = *Pattern - 'a', J;
if (0 == Components[I][0])
{
P = Remainder;
J = RemainderIndex;
while (L'\\' == *P)
P++;
for (;;)
{
Components[J][0] = P;
while (*P && L'\\' != *P)
P++;
Components[J][1] = P;
while (L'\\' == *P)
P++;
if (I == J)
{
Remainder = P;
RemainderIndex = I + 1;
break;
}
J++;
}
}
Dest = PathCopy(Dest, Components[I][0], Components[I][1], WriteDest, Replacement);
}
else
if (L'_' == *Pattern)
Dest = PathCopy(Dest, Remainder, 0, WriteDest, Replacement);
else
{
if (WriteDest)
*Dest = *Pattern;
Dest++;
}
Pattern++;
}
return Dest;
}

View File

@ -1,7 +1,7 @@
/** /**
* @file shared/minimal.h * @file shared/minimal.h
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -72,6 +72,10 @@ NTSYSAPI VOID NTAPI RtlMoveMemory(VOID *Destination, CONST VOID *Source, DWORD L
#pragma function(memset) #pragma function(memset)
#pragma function(memcpy) #pragma function(memcpy)
#pragma warning(push)
#pragma warning(disable:4163) /* not available as an intrinsic function */
#pragma function(memmove)
#pragma warning(pop)
static inline static inline
void *memset(void *dst, int val, size_t siz) void *memset(void *dst, int val, size_t siz)
{ {

View File

@ -2,7 +2,7 @@
* @file sys/callbacks.c * @file sys/callbacks.c
* Fast I/O and resource acquisition callbacks. * Fast I/O and resource acquisition callbacks.
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -308,7 +308,7 @@ VOID FspPropagateTopFlags(PIRP Irp, PIRP TopLevelIrp)
{ {
DEBUGBREAK_EX(iorecu); DEBUGBREAK_EX(iorecu);
FspIrpSetTopFlags(Irp, FspIrpFlags(TopLevelIrp)); FspIrpSetTopFlags(Irp, FspIrpTopFlags(TopLevelIrp) | FspIrpFlags(TopLevelIrp));
} }
} }
} }

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/cleanup.c * @file sys/cleanup.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/close.c * @file sys/close.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/create.c * @file sys/create.c
* *
* @copyright 2015-2019 Bill Zissimopoulos * @copyright 2015-2020 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -29,7 +29,7 @@ static NTSTATUS FspFsvolCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolCreateNoLock( static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen); BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
@ -144,6 +144,7 @@ static NTSTATUS FspFsvolCreate(
PECP_LIST ExtraCreateParameters; PECP_LIST ExtraCreateParameters;
PVOID ExtraCreateParameter; PVOID ExtraCreateParameter;
BOOLEAN MainFileOpen = FALSE; BOOLEAN MainFileOpen = FALSE;
PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp = 0;
/* /*
* Check if the IRP has ECP's. * Check if the IRP has ECP's.
@ -219,6 +220,21 @@ static NTSTATUS FspFsvolCreate(
} }
} }
#endif #endif
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures)
{
// {4720bd83-52ac-4104-a130-d1ec6a8cc8e5}
static const GUID FspAtomicCreateEcpGuid =
{ 0x4720bd83, 0x52ac, 0x4104, { 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5 } };
ExtraCreateParameter = 0;
AtomicCreateEcp =
NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspAtomicCreateEcpGuid, &ExtraCreateParameter, 0)) &&
0 != ExtraCreateParameter &&
!FsRtlIsEcpFromUserMode(ExtraCreateParameter) ?
ExtraCreateParameter : 0;
}
} }
if (!MainFileOpen) if (!MainFileOpen)
@ -226,7 +242,8 @@ static NTSTATUS FspFsvolCreate(
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject); FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
try try
{ {
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, FALSE); Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp,
MainFileOpen, AtomicCreateEcp);
} }
finally finally
{ {
@ -235,14 +252,15 @@ static NTSTATUS FspFsvolCreate(
} }
} }
else else
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, TRUE); Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp,
MainFileOpen, AtomicCreateEcp);
return Result; return Result;
} }
static NTSTATUS FspFsvolCreateNoLock( static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen) BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp)
{ {
PAGED_CODE(); PAGED_CODE();
@ -266,6 +284,11 @@ static NTSTATUS FspFsvolCreateNoLock(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#if defined(FSP_DEVICE_REJECT_EARLY_IRP)
if (!FspFsvolDeviceReadyToAcceptIrp(FsvolDeviceObject))
return STATUS_CANCELLED;
#endif
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState; PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; ULONG CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
ULONG CreateOptions = IrpSp->Parameters.Create.Options; ULONG CreateOptions = IrpSp->Parameters.Create.Options;
@ -279,6 +302,8 @@ static NTSTATUS FspFsvolCreateNoLock(
USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess;
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG EaLength = IrpSp->Parameters.Create.EaLength; ULONG EaLength = IrpSp->Parameters.Create.EaLength;
PVOID ExtraBuffer = 0;
ULONG ExtraLength = 0;
ULONG Flags = IrpSp->Flags; ULONG Flags = IrpSp->Flags;
KPROCESSOR_MODE RequestorMode = KPROCESSOR_MODE RequestorMode =
FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode;
@ -292,6 +317,7 @@ static NTSTATUS FspFsvolCreateNoLock(
BOOLEAN HasRestorePrivilege = BOOLEAN HasRestorePrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE); BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE);
BOOLEAN HasTrailingBackslash = FALSE; BOOLEAN HasTrailingBackslash = FALSE;
BOOLEAN EaIsReparsePoint = FALSE;
FSP_FILE_NODE *FileNode, *RelatedFileNode; FSP_FILE_NODE *FileNode, *RelatedFileNode;
FSP_FILE_DESC *FileDesc; FSP_FILE_DESC *FileDesc;
UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 }; UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 };
@ -302,6 +328,36 @@ static NTSTATUS FspFsvolCreateNoLock(
if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID)) if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID))
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
/* is there an AtomicCreateEcp attached? */
if (0 != AtomicCreateEcp)
{
if ((FILE_CREATE != CreateDisposition && FILE_OPEN_IF != CreateDisposition) ||
0 != EaBuffer ||
RTL_SIZEOF_THROUGH_FIELD(FSP_ATOMIC_CREATE_ECP_CONTEXT, ReparseBuffer) >
AtomicCreateEcp->Size ||
/* !!!: revisit: FlagOn*/
!FlagOn(AtomicCreateEcp->InFlags,
ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT |
ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED))
return STATUS_INVALID_PARAMETER; /* docs do not say what to return on failure! */
if (FlagOn(AtomicCreateEcp->InFlags,
ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED))
{
Result = FsRtlValidateReparsePointBuffer(AtomicCreateEcp->ReparseBufferLength,
AtomicCreateEcp->ReparseBuffer);
if (!NT_SUCCESS(Result))
return Result;
/* mark that we satisfied the reparse point request, although we may fail it later! */
AtomicCreateEcp->OutFlags = ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET;
ExtraBuffer = AtomicCreateEcp->ReparseBuffer;
ExtraLength = AtomicCreateEcp->ReparseBufferLength;
EaIsReparsePoint = TRUE;
}
}
/* was an EA buffer specified? */ /* was an EA buffer specified? */
if (0 != EaBuffer) if (0 != EaBuffer)
{ {
@ -318,6 +374,9 @@ static NTSTATUS FspFsvolCreateNoLock(
EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information); EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
ExtraBuffer = EaBuffer;
ExtraLength = EaLength;
} }
/* cannot open a paging file */ /* cannot open a paging file */
@ -555,9 +614,9 @@ static NTSTATUS FspFsvolCreateNoLock(
SecurityDescriptorSize = 0; SecurityDescriptorSize = 0;
FileAttributes = 0; FileAttributes = 0;
/* cannot set EA on named stream */ /* cannot set extra buffer on named stream */
EaBuffer = 0; ExtraBuffer = 0;
EaLength = 0; ExtraLength = 0;
/* remember the main file node */ /* remember the main file node */
ASSERT(0 == FileNode->MainFileNode); ASSERT(0 == FileNode->MainFileNode);
@ -577,8 +636,8 @@ static NTSTATUS FspFsvolCreateNoLock(
/* create the user-mode file system request */ /* create the user-mode file system request */
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, Result = FspIopCreateRequestEx(Irp, &FileNode->FileName,
0 != EaBuffer ? 0 != ExtraBuffer ?
FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + EaLength : SecurityDescriptorSize, FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + ExtraLength : SecurityDescriptorSize,
FspFsvolCreateRequestFini, &Request); FspFsvolCreateRequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
@ -616,10 +675,10 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.DesiredAccess = DesiredAccess; Request->Req.Create.DesiredAccess = DesiredAccess;
Request->Req.Create.GrantedAccess = GrantedAccess; Request->Req.Create.GrantedAccess = GrantedAccess;
Request->Req.Create.ShareAccess = ShareAccess; Request->Req.Create.ShareAccess = ShareAccess;
Request->Req.Create.Ea.Offset = 0 != EaBuffer ? Request->Req.Create.Ea.Offset = 0 != ExtraBuffer ?
(0 != Request->Req.Create.SecurityDescriptor.Offset ? (0 != Request->Req.Create.SecurityDescriptor.Offset ?
NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0; NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0;
Request->Req.Create.Ea.Size = 0 != EaBuffer ? (UINT16)EaLength : 0; Request->Req.Create.Ea.Size = 0 != ExtraBuffer ? (UINT16)ExtraLength : 0;
Request->Req.Create.UserMode = UserMode == RequestorMode; Request->Req.Create.UserMode = UserMode == RequestorMode;
Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege;
Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege; Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege;
@ -628,10 +687,10 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.CaseSensitive = CaseSensitive; Request->Req.Create.CaseSensitive = CaseSensitive;
Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash; Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash;
Request->Req.Create.NamedStream = MainFileName.Length; Request->Req.Create.NamedStream = MainFileName.Length;
#undef NEXTOFS
Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream && Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream &&
!!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode; !!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode;
Request->Req.Create.EaIsReparsePoint = EaIsReparsePoint;
#undef NEXTOFS
ASSERT( ASSERT(
0 == StreamPart.Length && 0 == MainFileName.Length || 0 == StreamPart.Length && 0 == MainFileName.Length ||
@ -642,10 +701,10 @@ static NTSTATUS FspFsvolCreateNoLock(
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
SecurityDescriptor, SecurityDescriptorSize); SecurityDescriptor, SecurityDescriptorSize);
/* copy the EA buffer (if any) into the request */ /* copy the extra buffer (if any) into the request */
if (0 != EaBuffer) if (0 != ExtraBuffer)
RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset,
EaBuffer, EaLength); ExtraBuffer, ExtraLength);
/* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */ /* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */
if (Request->Req.Create.OpenTargetDirectory) if (Request->Req.Create.OpenTargetDirectory)

Some files were not shown because too many files have changed in this diff Show More