Compare commits

..

77 Commits

Author SHA1 Message Date
90d67bc07d tools: build: sign cab file using SHA-256 2021-11-08 15:20:54 +00:00
70643f40a0 update changelog 2021-11-08 13:38:02 +00:00
366a9c562f art: update with Win11 colors 2021-11-08 13:17:35 +00:00
d7a8b0d9fb launcher: SvcInstanceStartWithArgvCopy: properly handle timeout condition 2021-10-31 12:35:30 +00:00
52dd6f7478 dll: fuse: FSP_FUSE_CAP_DELETE_ACCESS 2021-10-26 13:21:57 +01:00
73359d682b dll: fuse: convert EPERM/EACCES from unlink/rmdir to STATUS_CANNOT_DELETE 2021-10-25 13:58:52 +01:00
2a3f1a3990 doc: update NTFS compatibility 2021-10-22 15:22:08 +01:00
e823103334 doc: update API documentation 2021-10-22 14:47:58 +01:00
1208c6c652 doc: fix code in WinFsp Delete Redesign document 2021-10-22 12:22:33 +01:00
b13b24e0b1 doc: add WinFsp Delete Redesign document 2021-10-22 12:15:16 +01:00
91aa0ac2d0 inc: winfsp.h: fix source doc for Delete 2021-10-22 11:39:05 +01:00
dcce0d44a7 build: bump version to 2021.1 Beta3 2021-10-21 21:52:18 +01:00
af257d4bff tst: winfsp-tests: eliminate use of symbol FILE_SUPPORTS_POSIX_UNLINK_RENAME 2021-10-21 15:56:58 +01:00
9eaaefd154 sys,dll: debug support for DispositionEx, RenameEx 2021-10-21 15:54:38 +01:00
bb3e92df6c sys, dll: implement POSIX semantics for Rename 2021-10-21 15:39:25 +01:00
76bfa395a8 dotnet: implement new Delete design and POSIX semantics 2021-10-20 12:23:14 +01:00
81248f3899 dotnet: FileSystemHost: zero-init allocations made using Marshal.AllocHGlobal 2021-10-20 09:04:20 +01:00
a4d7aee6f5 dll: fuse: implement new Delete design and POSIX semantics 2021-10-19 17:54:01 +01:00
19823d84de sys,dll,inc: implement new Delete design and POSIX semantics 2021-10-19 15:23:15 +01:00
3e66082f11 sys: FspFsvolQueryDirectoryCopy: fix issue #380 2021-10-13 16:35:02 +01:00
490d021b22 dll: mount: MountDoNotUseLauncher registry setting 2021-08-11 16:27:29 +01:00
2d41693f3c src: dotnet: fix newlines 2021-06-20 20:44:06 +03:00
068270fa7f update changelog 2021-06-13 12:40:41 -07:00
f51bdef534 dll: fuse: fix path arg to release on Create error
When the kernel sends a `Create` message the WinFsp-FUSE layer creates
and opens the file (as per Windows semantics). Sometimes an additional
operation needs to be performed after the file has been opened, which
may fail. In this case the just opened file must be released.

In this particular case the WinFsp-FUSE layer used to call `release`
with an uninitialized path. This commit fixes the problem.

This problem was originally reported in cgofuse (billziss-gh/cgofuse#58)
2021-06-09 10:17:59 -07:00
63f91cc667 build: bump version 2021-06-09 10:13:41 -07:00
6e3e469fcb doc: update known file systems 2021-06-08 12:22:26 -07:00
efcc82b5dd build: update version 2021-06-08 10:38:27 -07:00
cad5e68ac8 art: update logo 2021-06-01 13:49:00 -07:00
6e3a8f70b2 update source copyright to 2021 2021-05-21 15:57:05 -07:00
6bc0fe4ac5 art: update logo 2021-05-21 14:53:52 -07:00
07f097220f changelog: update for v1.10B1 2021-05-21 11:41:35 -07:00
ca832988ed dll,sys: fix issue #369
The original WinFsp protocol for shutting down a file system was to issue
an FSP_FSCTL_STOP control code to the fsctl device. This would set the IOQ
to the "stopped" state and would also cancel all active IRP's. Cancelation
of IRP's would sometimes free buffers that may have still been in use by
the user mode file system threads; hence access violation.

To fix this problem a new control code FSP_FSCTL_STOP0 is introduced. The
new file system shutdown protocol is backwards compatible with the original
one and works as follows:

- First the file system process issues an FSP_FSCTL_STOP0 control code which
sets the IOQ to the "stopped" state but does NOT cancel IRP's.

- Then the file system process waits for its dispatcher threads to complete
(see FspFileSystemStopDispatcher).

- Finally the file system process issues an FSP_FSCTL_STOP control code
which stops the (already stopped) IOQ and cancels all IRP's.
2021-05-18 12:30:17 -07:00
23e401e312 Merge pull request #371 from lemourin/mingw-fix
inc: don't redeclare _FILE_FULL_EA_INFORMATION for mingw
2021-05-17 10:00:17 -07:00
bde57697f9 Add Paweł Wegner to contributors. 2021-05-15 14:59:10 +02:00
f62aa00a1e inc: don't redeclare _FILE_FULL_EA_INFORMATION for mingw
mingw-w64 declares _FILE_FULL_EA_INFORMATION since Jan 18, 2010 [1].

The change allows the winfsp client library to be consumed by projects built with mingw.

[1]: afd1465722
2021-05-14 14:08:02 +02:00
a27994289d art: update 2021-05-07 16:50:58 -07:00
3b10145e93 tst: winfsp-tests: disable new tests that fail on passthrough 2021-04-19 13:34:35 -07:00
33c6e7ee61 sys: fix issue #364 2021-04-16 16:43:34 -07:00
d0d67998c1 inc: fsctl.h: fix class guid's when used outside our build system 2021-04-13 15:33:57 -07:00
aa7888effc tools: wixguid.py 2021-04-13 15:22:42 -07:00
3c7e712e57 tools: build.bat: skip choco build for non-WinFsp brands 2021-04-13 14:38:51 -07:00
f8ee12f592 build: fix inadvertently broken DLL build on VS2015 2021-04-12 22:07:04 -07:00
c84d47aa3e doc: WinFsp rebranding document 2021-04-12 21:38:09 -07:00
023c925fb6 WinFsp rebranding support 2021-04-12 17:47:34 -07:00
a7cfabeff8 tools: add batch file that fixes issue #162 2021-04-08 15:00:55 -07:00
d4a70da611 Merge branch 'pvt-tsfix' 2021-04-08 14:06:52 -07:00
50892bfa19 shared: posix: DistinctPermsForSameOwnerGroup 2021-04-06 15:00:31 -07:00
b2e677a3d3 sys: FspFsvolSetBasicInformation: issue #362
According to the FILE_BASIC_INFORMATION doc a file system should not update a file timestamp when it receives a value of -1 in the corresponding time field.

This commit converts a -1 timestamp to a 0 timestamp; this directs a WinFsp file system not to update the corresponding file timestamp.

This commit fixes issue #362
2021-04-06 13:41:35 -07:00
9d76495340 update Changlog for v1.9 2021-04-06 13:01:33 -07:00
41c604b0fd update Changelog for v1.9B2 2021-04-06 13:00:30 -07:00
28a9534a65 build: version.properties: bump version 2021-04-06 12:53:33 -07:00
b87c907af8 build: version.properties: bump version 2021-02-02 16:50:52 -08:00
9d5efe5f98 dll: fuse: FileSecurity option 2021-01-25 16:54:59 -08:00
c5b850be35 sys: improve trace functionality 2021-01-25 13:11:10 -08:00
0af0bfbe7c sys: FspFsvolClose: convert CLOSE requests to synchronous when above the IOQ watermark 2021-01-25 12:45:33 -08:00
1dbcae3985 sys: FspTraceNtStatus: fix spelling mistake 2021-01-25 12:44:59 -08:00
a5726c820b sys: add trace functionality 2021-01-13 16:15:06 -08:00
870c54253a Merge pull request #342 from gaotxg/master
Credential: Default do not save password
2021-01-05 19:47:51 -08:00
f9cbbea386 Update Contributors.asciidoc 2021-01-06 10:47:42 +08:00
a939d9997b Credential: Default do not save password
If user want to save password, click save and credential window won't appear again.
Do not remember password should be default option.
2020-12-30 11:19:57 +08:00
c803ef24f8 dll: fuse: truncate fixed size options
Some options (VolumePrefix, FileSystemName, volname) have a fixed maximum size.
This commit adds functionality to truncate user-specified long options to their fixed maximum size.
2020-12-22 15:44:37 -08:00
2d5d058d2f dll: FspFsctlStartService:make thread safe 2020-12-19 11:05:24 -08:00
a372c6ee40 changelog: add note about notifyfs file systems 2020-12-18 16:57:08 -08:00
c8a5f52fb1 installer: add notifyfs-dotnet file system 2020-12-18 16:47:20 -08:00
40052b143e tst: notifyfs-dotnet: add .NET file system to demo file notification mechanism 2020-12-18 16:39:30 -08:00
8006763367 dotnet: Interop: NotifyInfoInternal: fix FileNameBufOffset 2020-12-18 16:37:08 -08:00
7ed9c56005 Merge pull request #336 from alonsohki/fix-notify-interop-alignment
Fix an alignment problem in the FspFileSystemNotify interop
2020-12-18 15:45:48 -08:00
12fd8942f7 tst: notifyfs: root dir does not have dot entries 2020-12-18 15:19:47 -08:00
3eb1f48174 installer: add notifyfs file system 2020-12-17 15:26:57 -08:00
ac26bde9ee tst: notifyfs: add file system to demo file notification mechanism 2020-12-17 15:20:02 -08:00
6421dd92a9 Fix an alignment problem in the FspFileSystemNotify interop that would leave a buffer size not aligned to a multiple of 8, and make notify calls fail. 2020-12-02 13:18:42 +02:00
b05d5e286e dotnet: rename NotifyInfoFilter and NotifyInfoAction 2020-11-27 10:37:22 -08:00
2d0df701e3 Merge pull request #335 from alonsohki/document-notifyinfo-fields
Document the NotifyInfo fields for the .NET interop layer.
2020-11-27 10:28:37 -08:00
2f1a5b98e2 Update NotifyInfoAction and NotifyInfoFilter enum constants for more readability. 2020-11-26 15:00:03 +02:00
21a636aaae Update Contributors.asciidoc 2020-11-24 20:07:31 +02:00
3b90908e01 Document the NotifyInfo fields for the .NET interop layer. 2020-11-24 20:02:02 +02:00
90e86d4592 workflows: update AntiVirus monitor 2020-11-17 09:19:21 -08:00
211 changed files with 4108 additions and 595 deletions

View File

@ -13,3 +13,4 @@ jobs:
files: | files: |
https://github.com/billziss-gh/winfsp/releases/download/v1.6/winfsp-1.6.20027.msi https://github.com/billziss-gh/winfsp/releases/download/v1.6/winfsp-1.6.20027.msi
https://github.com/billziss-gh/winfsp/releases/download/v1.7B1/winfsp-1.7.20038.msi https://github.com/billziss-gh/winfsp/releases/download/v1.7B1/winfsp-1.7.20038.msi
https://github.com/billziss-gh/winfsp/releases/download/v1.8/winfsp-1.8.20304.msi

View File

@ -1,6 +1,106 @@
= Changelog = Changelog
v1.10B2 (2021.1 Beta2)::
Changes since v1.9:
* [NEW] Official Windows 11 support.
* [NEW] WinFsp has had its Delete functionality redesigned in release 2021.1 Beta3. This redesign unifies all Windows file deletion semantics under a single file system operation that also supports the new POSIX semantics introduced in Windows 10 Redstone 1. The new Delete design is recommended for new file systems, however existing file systems will continue to work without any changes. See https://github.com/billziss-gh/winfsp/wiki/WinFsp-Delete-Redesign for more information.
* [NEW] Support for `FileDispositionInformationEx` and `FileRenameInformationEx` has been added (see above).
* [NEW] WinFsp now supports rebranding of the build products. This is primarily useful to commercial licensees. See https://github.com/billziss-gh/winfsp/wiki/WinFsp-Rebranding for more information.
* [NEW] WinFsp-FUSE has a new capability `FSP_FUSE_CAP_DELETE_ACCESS`. If this capability is specified WinFsp will call the FUSE `access` method with the WinFsp-specific flag `FSP_FUSE_DELETE_OK` to check whether the deletion should be allowed. This can be used to disallow deletion of files and directories that would normally be allowed under the FUSE/POSIX model.
* [NEW] WinFsp-FUSE has a new method for determining file access in the case where the user's primary SID (Windows Security Identifier) and group SID are the same (for example, this can happen when someone uses a Microsoft account as their primary login).
** Previously when the user SID and group SID were the same WinFsp-FUSE looked at the UNIX permissions for the owner and the UNIX permissions for the group and used the MOST restrictive permissions, which often resulted in inadvertent "access denied" errors. (For example, if the owner permission was `rw-` and the group permission was `---` the result was `---` and therefore access denied).
** Going forward this behavior will change. The user and group mode permissions will not be considered together even in the case where the user SID and group SID are the same. This will resolve the access denied errors.
** However to preserve backward compatibility (there might be some file systems that rely on the old behavior) we will do so in stages. For release v1.10 (2021.1) there is a new registry setting under `HKLM\SOFTWARE\WinFsp` (or `HKLM\SOFTWARE\WOW6432Node\WinFsp` on a 64-bit system) called `DistinctPermsForSameOwnerGroup`, which if set to 1 will direct WinFsp-FUSE to use the new behavior. The default value is 0 which directs WinFsp-FUSE to use the old behavior. This default will change in a future release.
* [NEW] A new registry setting under `HKLM\SOFTWARE\WinFsp` (or `HKLM\SOFTWARE\WOW6432Node\WinFsp` on a 64-bit system) called `MountDoNotUseLauncher` has been introduced, which if set to 1 will disable the use of the Launcher during mounting. The default value is 0 which allows the use of the Launcher during mounting in those rare cases when necessary. (In general the Launcher is not necessary for mounting. However when running a file system in the Windows Service context (session 0) under an account that is not LocalSystem (e.g. `NT AUTHORITY\NETWORK SERVICE`), the Launcher is used to create global drives.)
* [FIX] File share access when overwriting a file (e.g. when using `TRUNCATE_EXISTING`) is now done in a manner compatible with NTFS (previously there were cases when overwriting a file where behavior diverged from the NTFS one). (See GitHub issue #364.)
* [FIX] The FSD will now report a file's reparse tag in the `EaSize` field of `FILE_FULL_DIR_INFORMATION` and friends. This fixes problems such as `cmd.exe` not recognizing symlinks in a `dir` command. (See GitHub issue #380.)
* [FIX] Fixed a problem in the file system shutdown protocol which resolves an occasional access violation in the user mode file system process. Previously it was possible for a file system to crash when stopping itself using `FspFileSystemStopDispatcher`; this problem has been rectified. (See GitHub issue #369.)
* [FIX] Fixed a problem in the FUSE layer where in some rare circumstances the `release` operation could be called with an uninitialized `path` argument. (See GitHub issue billziss-gh/cgofuse#58 and commit f51bdef53427d1bba688fb6c768792fdc22ffc7b).
* [FIX] Fixed a potential problem when launching file system instances using the Launcher. (See GitHub issue #356.)
* [FIX] The `winfsp.h` header no longer defines `FILE_FULL_EA_INFORMATION` when compiled under mingw. This is because the mingw tool chain already includes a definition of this type. (GitHub PR #371. Thanks @lemourin.)
v1.10B1 (2021.1 Beta1)::
Changes since v1.9:
* [NEW] WinFsp now supports rebranding of the build products. This is primarily useful to commercial licensees. See https://github.com/billziss-gh/winfsp/wiki/WinFsp-Rebranding for more information.
* [NEW] WinFsp-FUSE has a new method for determining file access in the case where the user's primary SID (Windows Security Identifier) and group SID are the same (for example, this can happen when someone uses a Microsoft account as their primary login).
** Previously when the user SID and group SID were the same WinFsp-FUSE looked at the UNIX permissions for the owner and the UNIX permissions for the group and used the MOST restrictive permissions, which often resulted in inadvertent "access denied" errors. (For example, if the owner permission was `rw-` and the group permission was `---` the result was `---` and therefore access denied).
** Going forward this behavior will change. The user and group mode permissions will not be considered together even in the case where the user SID and group SID are the same. This will resolve the access denied errors.
** However to preserve backward compatibility (there might be some file systems that rely on the old behavior) we will do so in stages. For release v1.10 (2021.1) there is a new registry setting under `HKLM\SOFTWARE\WinFsp` (or `HKLM\SOFTWARE\WOW6432Node\WinFsp` on a 64-bit system) called `DistinctPermsForSameOwnerGroup`, which if set to 1 will direct WinFsp-FUSE to use the new behavior. The default value is 0 which directs WinFsp-FUSE to use the old behavior. This default will change in a future release.
* [FIX] File share access when overwriting a file (e.g. when using `TRUNCATE_EXISTING`) is now done in a manner compatible with NTFS (previously there were cases when overwriting a file where behavior diverged from the NTFS one). (See GitHub issue #364.)
* [FIX] Fixed a problem in the file system shutdown protocol which resolves an occasional access violation in the user mode file system process. Previously it was possible for a file system to crash when stopping itself using `FspFileSystemStopDispatcher`; this problem has been rectified. (See GitHub issue #369.)
* [FIX] The `winfsp.h` header no longer defines `FILE_FULL_EA_INFORMATION` when compiled under mingw. This is because the mingw tool chain already includes a definition of this type. (GitHub PR #371. Thanks @lemourin.)
v1.9 (2021)::
Changes since v1.8:
* [NEW] WinFsp now supports file change notifications and cache invalidations. This functionality is offered via the following new API's:
** Native API: `FspFileSystemNotify`
** FUSE API: `fuse_notify`
** .NET API: `FileSystemHost.Notify`
* [NEW] A native file system (notifyfs) and a .NET file system (notifyfs-dotnet) have been added to showcase the new file change notification API.
* [NEW] A new WinFsp-FUSE option `FileSecurity` has been added that allows the complete specification of file security descriptors using SDDL. (See GitHub issue https://github.com/rclone/rclone/issues/4717#issuecomment-767723287.)
* [FIX] The FSD now correctly handles a rare situation where receiving too many CLOSE calls from the OS (e.g. when caching thousands of files) could result in a bogus "insufficient resources" error. (See commit 0af0bfbe7c45e353d693a2a45965d99fa81f2163.)
* [FIX] WinFsp-FUSE correctly maps SID's from trusted domains to POSIX UID's in a multi-domain environment (using the "trustPosixOffset" attribute). Previously WinFsp-FUSE only handled SID's from the primary domain correctly.
* [FIX] WinFsp-FUSE options such as `volname`, `VolumePrefix`, `FileSystemName`, `ExactFileSystemName` are now truncated when too long. (See GitHub issue #311.)
* [FIX] The WinFsp driver is now started in a thread-safe manner if it is not already running. (See GitHub issue billziss-gh/cgofuse#51.)
* [FIX] Credentials entered in the Credentials dialog (when mapping network drives) are no longer saved by default. (See GitHub PR #342. Thanks @gaotxg.)
v1.9B2 (2021 Beta2)::
Changes since v1.8:
* [NEW] WinFsp now supports file change notifications and cache invalidations. This functionality is offered via the following new API's:
** Native API: `FspFileSystemNotify`
** FUSE API: `fuse_notify`
** .NET API: `FileSystemHost.Notify`
* [NEW] A native file system (notifyfs) and a .NET file system (notifyfs-dotnet) have been added to showcase the new file change notification API.
* [NEW] A new WinFsp-FUSE option `FileSecurity` has been added that allows the complete specification of file security descriptors using SDDL. (See GitHub issue https://github.com/rclone/rclone/issues/4717#issuecomment-767723287.)
* [FIX] The FSD now correctly handles a rare situation where receiving too many CLOSE calls from the OS (e.g. when caching thousands of files) could result in a bogus "insufficient resources" error. (See commit 0af0bfbe7c45e353d693a2a45965d99fa81f2163.)
* [FIX] WinFsp-FUSE correctly maps SID's from trusted domains to POSIX UID's in a multi-domain environment (using the "trustPosixOffset" attribute). Previously WinFsp-FUSE only handled SID's from the primary domain correctly.
* [FIX] WinFsp-FUSE options such as `volname`, `VolumePrefix`, `FileSystemName`, `ExactFileSystemName` are now truncated when too long. (See GitHub issue #311.)
* [FIX] The WinFsp driver is now started in a thread-safe manner if it is not already running. (See GitHub issue billziss-gh/cgofuse#51.)
* [FIX] Credentials entered in the Credentials dialog (when mapping network drives) are no longer saved by default. (See GitHub PR #342. Thanks @gaotxg.)
v1.9B1 (2021 Beta1):: v1.9B1 (2021 Beta1)::
Changes since v1.8: Changes since v1.8:

View File

@ -54,6 +54,7 @@ This CONTRIBUTOR AGREEMENT applies to any contribution that you make to the WinF
CONTRIBUTOR LIST CONTRIBUTOR LIST
---------------- ----------------
|=== |===
|Alberto Alonso |alberto at alonso.xyz
|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 |Brett Dutro |brett.dutro at gmail.com
@ -64,8 +65,10 @@ CONTRIBUTOR LIST
|Gal Hammer (Red Hat, https://www.redhat.com) |ghammer at redhat.com |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 |John Tyner |jtyner at gmail.com
|Paweł Wegner (Google LLC, https://google.com) |lemourin at google.com
|Pedro Frejo (Arpa System, https://arpasystem.com) |pedro.frejo at arpasystem.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
|Victor Gao |victgm at outlook.com
|=== |===

View File

@ -1,8 +1,8 @@
<h1 align="center"> <h1 align="center">
<img src="art/winfsp-glow.png" width="256"/>
<br/>
<br/>
WinFsp &middot; Windows File System Proxy WinFsp &middot; Windows File System Proxy
<a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fbillziss-gh%2Fwinfsp&text=Do%20you%20want%20to%20write%20a%20file%20system%20on%20Windows%3F%20WinFsp%20is%20well%20tested%2C%20very%20fast%20and%20easy%20to%20use%21&hashtags=windows%2Cfilesystem">
<img src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Share"/>
</a>
</h1> </h1>
<p align="center"> <p align="center">
@ -17,24 +17,12 @@
<img src="https://img.shields.io/badge/choco-install%20winfsp-black.svg?style=for-the-badge"/> <img src="https://img.shields.io/badge/choco-install%20winfsp-black.svg?style=for-the-badge"/>
</a> </a>
<br/> <br/>
<b>Quick Links</b><br/>
<a href="#benefits">Benefits</a> |
<a href="https://github.com/billziss-gh/winfsp/wiki">Wiki</a> |
<a href="https://groups.google.com/forum/#!forum/winfsp">Questions</a> |
<a href="https://twitter.com/BZissimopoulos">Author's Twitter</a>
<br/>
<br/> <br/>
<a href="https://ci.appveyor.com/project/billziss-gh/winfsp"> <a href="https://ci.appveyor.com/project/billziss-gh/winfsp">
<img src="https://img.shields.io/appveyor/ci/billziss-gh/winfsp.svg"/> <img src="https://img.shields.io/appveyor/ci/billziss-gh/winfsp.svg"/>
</a> </a>
<br/> <br/>
<br/> <br/>
<b>Check out my new kernel driver project <a href="https://github.com/billziss-gh/winspd">WinSpd</a>.</b>
<br/>
<br/>
</p>
<p align="center">
WinFsp is a set of software components for Windows computers that allows the creation of user mode file systems. In this sense it is similar to FUSE (Filesystem in Userspace), which provides the same functionality on UNIX-like computers. WinFsp is a set of software components for Windows computers that allows the creation of user mode file systems. In this sense it is similar to FUSE (Filesystem in Userspace), which provides the same functionality on UNIX-like computers.
<br/> <br/>
<br/> <br/>

View File

@ -42,8 +42,8 @@ install:
build_script: build_script:
- appveyor AddMessage "Reboot complete" -Category Information - appveyor AddMessage "Reboot complete" -Category Information
# build cygfuse # build cygfuse
- C:\cygwin64\setup-x86_64.exe -qnNd -P cygport #- C:\cygwin64\setup-x86_64.exe -qnNd -P cygport
- C:\cygwin64\bin\bash --login -c "make -C '%CD%\opt\cygfuse' dist" #- C:\cygwin64\bin\bash --login -c "make -C '%CD%\opt\cygfuse' dist"
#- C:\cygwin\setup-x86.exe -qnNd -P cygport #- C:\cygwin\setup-x86.exe -qnNd -P cygport
#- C:\cygwin\bin\bash --login -c "make -C '%CD%\opt\cygfuse' dist" #- C:\cygwin\bin\bash --login -c "make -C '%CD%\opt\cygfuse' dist"
# build winfsp # build winfsp

BIN
art/winfsp-glow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
art/winfsp.afdesign Normal file

Binary file not shown.

BIN
art/wixbanner.afdesign Normal file

Binary file not shown.

Binary file not shown.

BIN
art/wixdialog.afdesign Normal file

Binary file not shown.

Binary file not shown.

View File

@ -9,7 +9,7 @@
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<ProjectName>winfsp.net</ProjectName> <ProjectName>winfsp.net</ProjectName>
<RootNamespace>Fsp</RootNamespace> <RootNamespace>Fsp</RootNamespace>
<AssemblyName>winfsp-msil</AssemblyName> <AssemblyName>$(MyProductFileName)-msil</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
@ -25,7 +25,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml</DocumentationFile> <DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\$(MyProductFileName)-msil.xml</DocumentationFile>
<NoWarn>1591</NoWarn> <NoWarn>1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@ -38,7 +38,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml</DocumentationFile> <DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\$(MyProductFileName)-msil.xml</DocumentationFile>
<NoWarn>1591</NoWarn> <NoWarn>1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

View File

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

View File

@ -20,7 +20,7 @@
AllowSameVersionUpgrades="no" AllowSameVersionUpgrades="no"
DisallowUpgradeErrorMessage="An older version of $(var.MyProductName) is already installed. You must uninstall it before you can install this version." DisallowUpgradeErrorMessage="An older version of $(var.MyProductName) is already installed. You must uninstall it before you can install this version."
DowngradeErrorMessage="A newer version of $(var.MyProductName) is already installed." /> DowngradeErrorMessage="A newer version of $(var.MyProductName) is already installed." />
<Media Id="1" Cabinet="WinFsp.cab" EmbedCab="yes" /> <Media Id="1" Cabinet="$(var.MyProductName).cab" EmbedCab="yes" />
<Property Id="P.LauncherName">$(var.MyProductName).Launcher</Property> <Property Id="P.LauncherName">$(var.MyProductName).Launcher</Property>
<Property Id="P.LauncherRegistryKey">Software\$(var.MyProductName)\Services</Property> <Property Id="P.LauncherRegistryKey">Software\$(var.MyProductName)\Services</Property>
@ -36,7 +36,7 @@
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder"> <Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="WinFsp"> <Directory Id="INSTALLDIR" Name="$(var.MyProductName)">
<Directory Id="BINDIR" Name="bin" /> <Directory Id="BINDIR" Name="bin" />
<Directory Id="INCDIR" Name="inc" /> <Directory Id="INCDIR" Name="inc" />
<Directory Id="LIBDIR" Name="lib" /> <Directory Id="LIBDIR" Name="lib" />
@ -55,54 +55,54 @@
Name="InstallDir" Name="InstallDir"
Type="string" Type="string"
Value="[INSTALLDIR]" /> Value="[INSTALLDIR]" />
<dep:Provides Key="WinFsp" /> <dep:Provides Key="$(var.MyProductName)" />
</Component> </Component>
<Component Id="C.License.txt"> <Component Id="C.License.txt">
<File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" /> <File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" />
</Component> </Component>
</DirectoryRef> </DirectoryRef>
<DirectoryRef Id="BINDIR" FileSource="..\build\$(var.Configuration)"> <DirectoryRef Id="BINDIR" FileSource="..\build\$(var.Configuration)">
<Component Id="C.winfsp_x64.sys"> <Component Id="C.$(var.MyProductFileName)_x64.sys">
<File Name="winfsp-x64.sys" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x64.sys" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_x86.sys"> <Component Id="C.$(var.MyProductFileName)_x86.sys">
<File Name="winfsp-x86.sys" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x86.sys" KeyPath="yes" />
</Component> </Component>
<!-- On Win64 register winfsp-x64.dll --> <!-- On Win64 register $(var.MyProductFileName)-x64.dll -->
<Component Id="C.winfsp_x64.dll.selfreg" Guid="F0A67746-1A9C-4976-8EC0-882E9407FA6D"> <Component Id="C.$(var.MyProductFileName)_x64.dll.selfreg" Guid="F0A67746-1A9C-4976-8EC0-882E9407FA6D">
<File Id="FILE.winfsp_x64.dll.selfreg" Name="winfsp-x64.dll" KeyPath="yes" SelfRegCost="1" /> <File Id="FILE.$(var.MyProductFileName)_x64.dll.selfreg" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" SelfRegCost="1" />
<Condition>VersionNT64</Condition> <Condition>VersionNT64</Condition>
</Component> </Component>
<Component Id="C.winfsp_x86.dll" Guid="950492FB-12F7-4E27-9124-8325A2BC9927"> <Component Id="C.$(var.MyProductFileName)_x86.dll" Guid="950492FB-12F7-4E27-9124-8325A2BC9927">
<File Name="winfsp-x86.dll" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" />
<Condition>VersionNT64</Condition> <Condition>VersionNT64</Condition>
</Component> </Component>
<!-- On Win32 register winfsp-x86.dll --> <!-- On Win32 register $(var.MyProductFileName)-x86.dll -->
<Component Id="C.winfsp_x64.dll" Guid="4D6E7A8E-0CA6-49BE-B312-1EDADE725756"> <Component Id="C.$(var.MyProductFileName)_x64.dll" Guid="4D6E7A8E-0CA6-49BE-B312-1EDADE725756">
<File Name="winfsp-x64.dll" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" />
<Condition>NOT VersionNT64</Condition> <Condition>NOT VersionNT64</Condition>
</Component> </Component>
<Component Id="C.winfsp_x86.dll.selfreg" Guid="F0DEF7A6-AF55-419F-A58A-DF4018C6FA73"> <Component Id="C.$(var.MyProductFileName)_x86.dll.selfreg" Guid="F0DEF7A6-AF55-419F-A58A-DF4018C6FA73">
<File Id="FILE.winfsp_x86.dll.selfreg" Name="winfsp-x86.dll" KeyPath="yes" SelfRegCost="1" /> <File Id="FILE.$(var.MyProductFileName)_x86.dll.selfreg" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" SelfRegCost="1" />
<Condition>NOT VersionNT64</Condition> <Condition>NOT VersionNT64</Condition>
</Component> </Component>
<!-- install assembly --> <!-- install assembly -->
<Component Id="C.winfsp_msil.dll" Guid="0D8BA6AE-9F87-402B-AE1A-95B0AE3BE179"> <Component Id="C.$(var.MyProductFileName)_msil.dll" Guid="0D8BA6AE-9F87-402B-AE1A-95B0AE3BE179">
<File Id="FILE.winfsp_msil.dll" Name="winfsp-msil.dll" KeyPath="yes" /> <File Id="FILE.$(var.MyProductFileName)_msil.dll" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_msil.xml" Guid="1657F707-C112-454C-91AE-0FDEBBF454AB"> <Component Id="C.$(var.MyProductFileName)_msil.xml" Guid="1657F707-C112-454C-91AE-0FDEBBF454AB">
<File Id="FILE.winfsp_msil.xml" Name="winfsp-msil.xml" KeyPath="yes" /> <File Id="FILE.$(var.MyProductFileName)_msil.xml" Name="$(var.MyProductFileName)-msil.xml" KeyPath="yes" />
</Component> </Component>
<!-- <!--
<Component Id="C.winfsp_msil.dll.GAC" Guid="6469467D-8C90-4889-8138-4028F9DA6E85"> <Component Id="C.$(var.MyProductFileName)_msil.dll.GAC" Guid="6469467D-8C90-4889-8138-4028F9DA6E85">
<File Id="FILE.winfsp_msil.dll.GAC" Name="winfsp-msil.dll" KeyPath="yes" Assembly=".net" /> <File Id="FILE.$(var.MyProductFileName)_msil.dll.GAC" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" Assembly=".net" />
</Component> </Component>
<Component Id="C.policy.winfsp_msil.dll.GAC"> <Component Id="C.policy.$(var.MyProductFileName)_msil.dll.GAC">
<File Name="policy.1.0.winfsp-msil.dll" KeyPath="yes" Assembly=".net" /> <File Name="policy.1.0.$(var.MyProductFileName)-msil.dll" KeyPath="yes" Assembly=".net" />
<File Name="policy.1.0.winfsp-msil.config" KeyPath="no" /> <File Name="policy.1.0.$(var.MyProductFileName)-msil.config" KeyPath="no" />
</Component> </Component>
--> -->
@ -297,11 +297,11 @@
</Directory> </Directory>
</DirectoryRef> </DirectoryRef>
<DirectoryRef Id="LIBDIR" FileSource="..\build\$(var.Configuration)"> <DirectoryRef Id="LIBDIR" FileSource="..\build\$(var.Configuration)">
<Component Id="C.winfsp_x64.lib"> <Component Id="C.$(var.MyProductFileName)_x64.lib">
<File Name="winfsp-x64.lib" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x64.lib" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_x86.lib"> <Component Id="C.$(var.MyProductFileName)_x86.lib">
<File Name="winfsp-x86.lib" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x86.lib" KeyPath="yes" />
</Component> </Component>
<!-- On Win64 copy fuse-x64.pc --> <!-- On Win64 copy fuse-x64.pc -->
@ -538,19 +538,44 @@
<File Name="passthrough-dotnet.csproj" KeyPath="yes" /> <File Name="passthrough-dotnet.csproj" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="SMPDIR.notifyfs" Name="notifyfs">
<Component Id="C.notifyfs.c">
<File Name="notifyfs.c" KeyPath="yes" />
</Component>
<Component Id="C.notifyfs.sln">
<File Name="notifyfs.sln" KeyPath="yes" />
</Component>
<Component Id="C.notifyfs.vcxproj">
<File Name="notifyfs.vcxproj" KeyPath="yes" />
</Component>
<Component Id="C.notifyfs.vcxproj.filters">
<File Name="notifyfs.vcxproj.filters" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="SMPDIR.notifyfs_dotnet" Name="notifyfs-dotnet">
<Component Id="C.notifyfs_dotnet.Program.cs">
<File Id="FILE.notifyfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
</Component>
<Component Id="C.notifyfs_dotnet.sln">
<File Name="notifyfs-dotnet.sln" KeyPath="yes" />
</Component>
<Component Id="C.notifyfs_dotnet.csproj">
<File Name="notifyfs-dotnet.csproj" KeyPath="yes" />
</Component>
</Directory>
</DirectoryRef> </DirectoryRef>
<DirectoryRef Id="SYMDIR"> <DirectoryRef Id="SYMDIR">
<Component Id="C.winfsp_x64.sys.pdb"> <Component Id="C.$(var.MyProductFileName)_x64.sys.pdb">
<File Name="winfsp-x64.sys.pdb" Source="..\build\$(var.Configuration)\winfsp-x64.sys.public.pdb" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x64.sys.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x64.sys.public.pdb" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_x86.sys.pdb"> <Component Id="C.$(var.MyProductFileName)_x86.sys.pdb">
<File Name="winfsp-x86.sys.pdb" Source="..\build\$(var.Configuration)\winfsp-x86.sys.public.pdb" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x86.sys.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x86.sys.public.pdb" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_x64.dll.pdb"> <Component Id="C.$(var.MyProductFileName)_x64.dll.pdb">
<File Name="winfsp-x64.dll.pdb" Source="..\build\$(var.Configuration)\winfsp-x64.dll.public.pdb" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x64.dll.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x64.dll.public.pdb" KeyPath="yes" />
</Component> </Component>
<Component Id="C.winfsp_x86.dll.pdb"> <Component Id="C.$(var.MyProductFileName)_x86.dll.pdb">
<File Name="winfsp-x86.dll.pdb" Source="..\build\$(var.Configuration)\winfsp-x86.dll.public.pdb" KeyPath="yes" /> <File Name="$(var.MyProductFileName)-x86.dll.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x86.dll.public.pdb" KeyPath="yes" />
</Component> </Component>
<Component Id="C.launcher_x64.pdb"> <Component Id="C.launcher_x64.pdb">
<File Name="launcher-x64.pdb" Source="..\build\$(var.Configuration)\launcher-x64.public.pdb" KeyPath="yes" /> <File Name="launcher-x64.pdb" Source="..\build\$(var.Configuration)\launcher-x64.public.pdb" KeyPath="yes" />
@ -578,13 +603,13 @@
</Component> </Component>
</DirectoryRef> </DirectoryRef>
<ComponentGroup Id="C.WinFsp.bin"> <ComponentGroup Id="C.$(var.MyProductName).bin">
<ComponentRef Id="C.winfsp_x64.sys" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.sys" />
<ComponentRef Id="C.winfsp_x86.sys" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.sys" />
<ComponentRef Id="C.winfsp_x64.dll.selfreg" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.dll.selfreg" />
<ComponentRef Id="C.winfsp_x86.dll" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.dll" />
<ComponentRef Id="C.winfsp_x64.dll" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.dll" />
<ComponentRef Id="C.winfsp_x86.dll.selfreg" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.dll.selfreg" />
<ComponentRef Id="C.launcher_x64.exe.svcinst" /> <ComponentRef Id="C.launcher_x64.exe.svcinst" />
<ComponentRef Id="C.launcher_x86.exe" /> <ComponentRef Id="C.launcher_x86.exe" />
<ComponentRef Id="C.launcher_x64.exe" /> <ComponentRef Id="C.launcher_x64.exe" />
@ -596,7 +621,7 @@
<ComponentRef Id="C.diag.bat" /> <ComponentRef Id="C.diag.bat" />
<ComponentRef Id="C.fsreg.bat" /> <ComponentRef Id="C.fsreg.bat" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.inc"> <ComponentGroup Id="C.$(var.MyProductName).inc">
<ComponentRef Id="C.fsctl.h" /> <ComponentRef Id="C.fsctl.h" />
<ComponentRef Id="C.winfsp.h" /> <ComponentRef Id="C.winfsp.h" />
<ComponentRef Id="C.launch.h" /> <ComponentRef Id="C.launch.h" />
@ -610,15 +635,15 @@
<ComponentRef Id="C.fuse3_opt.h" /> <ComponentRef Id="C.fuse3_opt.h" />
<ComponentRef Id="C.winfsp_fuse3.h" /> <ComponentRef Id="C.winfsp_fuse3.h" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.lib"> <ComponentGroup Id="C.$(var.MyProductName).lib">
<ComponentRef Id="C.winfsp_x64.lib" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.lib" />
<ComponentRef Id="C.winfsp_x86.lib" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.lib" />
<ComponentRef Id="C.fuse_x64.pc" /> <ComponentRef Id="C.fuse_x64.pc" />
<ComponentRef Id="C.fuse_x86.pc" /> <ComponentRef Id="C.fuse_x86.pc" />
<ComponentRef Id="C.fuse3_x64.pc" /> <ComponentRef Id="C.fuse3_x64.pc" />
<ComponentRef Id="C.fuse3_x86.pc" /> <ComponentRef Id="C.fuse3_x86.pc" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.opt.fuse"> <ComponentGroup Id="C.$(var.MyProductName).opt.fuse">
<ComponentRef Id="C.fuse.tar.xz.x64" /> <ComponentRef Id="C.fuse.tar.xz.x64" />
<ComponentRef Id="C.fuse.tar.xz.x86" /> <ComponentRef Id="C.fuse.tar.xz.x86" />
<ComponentRef Id="C.fuse3.tar.xz.x64" /> <ComponentRef Id="C.fuse3.tar.xz.x64" />
@ -626,12 +651,12 @@
<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"> <ComponentGroup Id="C.$(var.MyProductName).opt.fsext">
<ComponentRef Id="C.fsext.h" /> <ComponentRef Id="C.fsext.h" />
<ComponentRef Id="C.fsext.winfsp_x64.lib" /> <ComponentRef Id="C.fsext.winfsp_x64.lib" />
<ComponentRef Id="C.fsext.winfsp_x86.lib" /> <ComponentRef Id="C.fsext.winfsp_x86.lib" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.smp"> <ComponentGroup Id="C.$(var.MyProductName).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" />
@ -674,12 +699,16 @@
<ComponentRef Id="C.passthrough_fuse3.vcxproj.filters" /> <ComponentRef Id="C.passthrough_fuse3.vcxproj.filters" />
<ComponentRef Id="C.passthrough_fuse3.Makefile" /> <ComponentRef Id="C.passthrough_fuse3.Makefile" />
<ComponentRef Id="C.passthrough_fuse3.README.md" /> <ComponentRef Id="C.passthrough_fuse3.README.md" />
<ComponentRef Id="C.notifyfs.c" />
<ComponentRef Id="C.notifyfs.sln" />
<ComponentRef Id="C.notifyfs.vcxproj" />
<ComponentRef Id="C.notifyfs.vcxproj.filters" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.sym"> <ComponentGroup Id="C.$(var.MyProductName).sym">
<ComponentRef Id="C.winfsp_x64.sys.pdb" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.sys.pdb" />
<ComponentRef Id="C.winfsp_x86.sys.pdb" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.sys.pdb" />
<ComponentRef Id="C.winfsp_x86.dll.pdb" /> <ComponentRef Id="C.$(var.MyProductFileName)_x86.dll.pdb" />
<ComponentRef Id="C.winfsp_x64.dll.pdb" /> <ComponentRef Id="C.$(var.MyProductFileName)_x64.dll.pdb" />
<ComponentRef Id="C.launcher_x86.pdb" /> <ComponentRef Id="C.launcher_x86.pdb" />
<ComponentRef Id="C.launcher_x64.pdb" /> <ComponentRef Id="C.launcher_x64.pdb" />
<ComponentRef Id="C.launchctl_x64.pdb" /> <ComponentRef Id="C.launchctl_x64.pdb" />
@ -689,20 +718,23 @@
<ComponentRef Id="C.memfs_x64.pdb" /> <ComponentRef Id="C.memfs_x64.pdb" />
<ComponentRef Id="C.memfs_x86.pdb" /> <ComponentRef Id="C.memfs_x86.pdb" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.net"> <ComponentGroup Id="C.$(var.MyProductName).net">
<ComponentRef Id="C.winfsp_msil.dll" /> <ComponentRef Id="C.$(var.MyProductFileName)_msil.dll" />
<ComponentRef Id="C.winfsp_msil.xml" /> <ComponentRef Id="C.$(var.MyProductFileName)_msil.xml" />
<!-- <!--
<ComponentRef Id="C.winfsp_msil.dll.GAC" /> <ComponentRef Id="C.$(var.MyProductFileName)_msil.dll.GAC" />
<ComponentRef Id="C.policy.winfsp_msil.dll.GAC" /> <ComponentRef Id="C.policy.$(var.MyProductFileName)_msil.dll.GAC" />
--> -->
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.smp.net"> <ComponentGroup Id="C.$(var.MyProductName).smp.net">
<ComponentRef Id="C.memfs_dotnet_msil.exe" /> <ComponentRef Id="C.memfs_dotnet_msil.exe" />
<ComponentRef Id="C.memfs_dotnet.Program.cs" /> <ComponentRef Id="C.memfs_dotnet.Program.cs" />
<ComponentRef Id="C.passthrough_dotnet.Program.cs" /> <ComponentRef Id="C.passthrough_dotnet.Program.cs" />
<ComponentRef Id="C.passthrough_dotnet.sln" /> <ComponentRef Id="C.passthrough_dotnet.sln" />
<ComponentRef Id="C.passthrough_dotnet.csproj" /> <ComponentRef Id="C.passthrough_dotnet.csproj" />
<ComponentRef Id="C.notifyfs_dotnet.Program.cs" />
<ComponentRef Id="C.notifyfs_dotnet.sln" />
<ComponentRef Id="C.notifyfs_dotnet.csproj" />
</ComponentGroup> </ComponentGroup>
<Feature <Feature
@ -725,8 +757,8 @@
AllowAdvertise="no" AllowAdvertise="no"
InstallDefault="local" InstallDefault="local"
Absent="disallow"> Absent="disallow">
<ComponentGroupRef Id="C.WinFsp.bin" /> <ComponentGroupRef Id="C.$(var.MyProductName).bin" />
<ComponentGroupRef Id="C.WinFsp.net" /> <ComponentGroupRef Id="C.$(var.MyProductName).net" />
</Feature> </Feature>
<!-- <!--
<Feature <Feature
@ -737,7 +769,7 @@
AllowAdvertise="no" AllowAdvertise="no"
InstallDefault="local" InstallDefault="local"
Absent="allow"> Absent="allow">
<ComponentGroupRef Id="C.WinFsp.net" /> <ComponentGroupRef Id="C.$(var.MyProductName).net" />
</Feature> </Feature>
--> -->
<Feature <Feature
@ -748,11 +780,11 @@
AllowAdvertise="no" AllowAdvertise="no"
InstallDefault="local" InstallDefault="local"
Absent="allow"> Absent="allow">
<ComponentGroupRef Id="C.WinFsp.inc" /> <ComponentGroupRef Id="C.$(var.MyProductName).inc" />
<ComponentGroupRef Id="C.WinFsp.lib" /> <ComponentGroupRef Id="C.$(var.MyProductName).lib" />
<ComponentGroupRef Id="C.WinFsp.smp" /> <ComponentGroupRef Id="C.$(var.MyProductName).smp" />
<ComponentGroupRef Id="C.WinFsp.smp.net" /> <ComponentGroupRef Id="C.$(var.MyProductName).smp.net" />
<ComponentGroupRef Id="C.WinFsp.sym" /> <ComponentGroupRef Id="C.$(var.MyProductName).sym" />
</Feature> </Feature>
<Feature <Feature
Id="F.KernelDeveloper" Id="F.KernelDeveloper"
@ -762,7 +794,7 @@
AllowAdvertise="no" AllowAdvertise="no"
InstallDefault="local" InstallDefault="local"
Absent="allow"> Absent="allow">
<ComponentGroupRef Id="C.WinFsp.opt.fsext" /> <ComponentGroupRef Id="C.$(var.MyProductName).opt.fsext" />
</Feature> </Feature>
<Feature <Feature
Id="F.Cygfuse" Id="F.Cygfuse"
@ -772,7 +804,7 @@
AllowAdvertise="no" AllowAdvertise="no"
InstallDefault="local" InstallDefault="local"
Absent="allow"> Absent="allow">
<ComponentGroupRef Id="C.WinFsp.opt.fuse" /> <ComponentGroupRef Id="C.$(var.MyProductName).opt.fuse" />
</Feature> </Feature>
</Feature> </Feature>

View File

@ -7,7 +7,7 @@
<ProductVersion>3.10</ProductVersion> <ProductVersion>3.10</ProductVersion>
<ProjectGuid>d53aac39-4c57-4ca5-a4f3-c2b24888c594</ProjectGuid> <ProjectGuid>d53aac39-4c57-4ca5-a4f3-c2b24888c594</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<OutputName>winfsp-$(MyVersion)</OutputName> <OutputName>$(MyProductFileName)-$(MyVersion)</OutputName>
<OutputType>Package</OutputType> <OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
@ -16,7 +16,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath> <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath> <IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
<DefineConstants>Debug;MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants> <DefineConstants>Debug;MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
<SuppressAllWarnings>False</SuppressAllWarnings> <SuppressAllWarnings>False</SuppressAllWarnings>
<Pedantic>True</Pedantic> <Pedantic>True</Pedantic>
<SuppressPdbOutput>True</SuppressPdbOutput> <SuppressPdbOutput>True</SuppressPdbOutput>
@ -25,7 +25,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath> <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath> <IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
<DefineConstants>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants> <DefineConstants>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
<SuppressAllWarnings>False</SuppressAllWarnings> <SuppressAllWarnings>False</SuppressAllWarnings>
<Pedantic>True</Pedantic> <Pedantic>True</Pedantic>
<SuppressPdbOutput>True</SuppressPdbOutput> <SuppressPdbOutput>True</SuppressPdbOutput>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 451 KiB

View File

@ -12,13 +12,14 @@
<MyGitRevision Condition="!$(MyGitHead.StartsWith(ref: ))">$(MyGitHead.Substring(0, 7))</MyGitRevision> <MyGitRevision Condition="!$(MyGitHead.StartsWith(ref: ))">$(MyGitHead.Substring(0, 7))</MyGitRevision>
<MyProductName>WinFsp</MyProductName> <MyProductName>WinFsp</MyProductName>
<MyProductFileName>winfsp</MyProductFileName>
<MyDescription>Windows File System Proxy</MyDescription> <MyDescription>Windows File System Proxy</MyDescription>
<MyCompanyName>Navimatics LLC</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.9</MyCanonicalVersion> <MyCanonicalVersion>1.10</MyCanonicalVersion>
<MyProductVersion>2021 Beta1</MyProductVersion> <MyProductVersion>2021.1 Beta3</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
@ -27,14 +28,18 @@
<MyAssemblyPolicyVersion>$(MyCanonicalVersion.Substring(0,$(MyVersion.IndexOf('.')))).0</MyAssemblyPolicyVersion> <MyAssemblyPolicyVersion>$(MyCanonicalVersion.Substring(0,$(MyVersion.IndexOf('.')))).0</MyAssemblyPolicyVersion>
<MyAssemblyVersion>$(MyAssemblyPolicyVersion).0.0</MyAssemblyVersion> <MyAssemblyVersion>$(MyAssemblyPolicyVersion).0.0</MyAssemblyVersion>
<!-- When rebranding WinFsp you MUST change the following GUIDs - use VS "Create GUID" tool -->
<MyFspFsctlDeviceClassGuid>{ 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } }</MyFspFsctlDeviceClassGuid>
<MyFspFsvrtDeviceClassGuid>{ 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } }</MyFspFsvrtDeviceClassGuid>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601</PreprocessorDefinitions> <PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601;MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<ResourceCompile> <ResourceCompile>
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions> <PreprocessorDefinitions>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(IsKernelModeToolset)'=='true'"> <ItemDefinitionGroup Condition="'$(IsKernelModeToolset)'=='true'">

View File

@ -182,25 +182,25 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>

View File

@ -75,28 +75,28 @@
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
<EnableInf2cat>false</EnableInf2cat> <EnableInf2cat>false</EnableInf2cat>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
<EnableInf2cat>false</EnableInf2cat> <EnableInf2cat>false</EnableInf2cat>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
<EnableInf2cat>false</EnableInf2cat> <EnableInf2cat>false</EnableInf2cat>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir> <IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
<TargetName>$(SolutionName)-$(PlatformTarget)</TargetName> <TargetName>$(MyProductFileName)-$(PlatformTarget)</TargetName>
<EnableInf2cat>false</EnableInf2cat> <EnableInf2cat>false</EnableInf2cat>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -187,6 +187,7 @@
<ClCompile Include="..\..\src\sys\shutdown.c" /> <ClCompile Include="..\..\src\sys\shutdown.c" />
<ClCompile Include="..\..\src\sys\silo.c" /> <ClCompile Include="..\..\src\sys\silo.c" />
<ClCompile Include="..\..\src\sys\statistics.c" /> <ClCompile Include="..\..\src\sys\statistics.c" />
<ClCompile Include="..\..\src\sys\trace.c" />
<ClCompile Include="..\..\src\sys\util.c" /> <ClCompile Include="..\..\src\sys\util.c" />
<ClCompile Include="..\..\src\sys\volinfo.c" /> <ClCompile Include="..\..\src\sys\volinfo.c" />
<ClCompile Include="..\..\src\sys\volume.c" /> <ClCompile Include="..\..\src\sys\volume.c" />

View File

@ -125,6 +125,9 @@
<ClCompile Include="..\..\src\sys\silo.c"> <ClCompile Include="..\..\src\sys\silo.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\sys\trace.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h"> <ClInclude Include="..\..\src\sys\driver.h">

View File

@ -1,6 +1,6 @@
= Known File Systems and File System Libraries = Known File Systems and File System Libraries
This document contains a list of known file systems and file system libraries that run on WinFsp. Please contact the WinFsp project to have your file system solution added to this list. This document contains a list of known open-source file systems and file system libraries that run on WinFsp. Please contact the WinFsp project to have your file system solution added to this list.
== File Systems == File Systems
@ -9,13 +9,16 @@ This document contains a list of known file systems and file system libraries th
- https://github.com/lowleveldesign/fsmemfs[fsmemfs] - Memory File System written in F# - 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/sganis/golddrive[golddrive] - Windows ssh network drive - https://github.com/sganis/golddrive[golddrive] - Windows ssh network drive
- https://github.com/billziss-gh/hubfs[hubfs] - File system for GitHub
- 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
- https://github.com/billziss-gh/objfs[objfs] - Object Storage File System
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage - https://github.com/ncw/rclone[rclone] - rsync for cloud storage
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives - https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
- 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/printpagestopdf/WordpressDrive[WordpressDrive] - Windows Userspace Filesystem based on WinFsp that presents a Wordpress Site as a Windows Drive
- https://github.com/emoose/xbox-winfsp[xbox-winfsp] - Adds native support to Windows for the FATX, STFS & GDFX (aka XGD/XDVDFS) Xbox filesystems. - https://github.com/emoose/xbox-winfsp[xbox-winfsp] - Adds native support to Windows for the FATX, STFS & GDFX (aka XGD/XDVDFS) Xbox filesystems.
- https://github.com/UtrechtUniversity/YodaDrive[YodaDrive] - Mount a Yoda drive as a local drive - https://github.com/UtrechtUniversity/YodaDrive[YodaDrive] - Mount a Yoda drive as a local drive

View File

@ -17,13 +17,14 @@ WinFsp supports the following NTFS features:
- Opportunistic locks. - Opportunistic locks.
- Open, create, close, delete, query named streams. - Open, create, close, delete, query named streams.
- Reparse points with special support for symbolic links. - Reparse points with special support for symbolic links.
- Extended attributes.
- Traditional Windows and POSIX semantics for delete and rename.
== Unsupported features == Unsupported features
WinFsp does not support the following NTFS features: WinFsp does not support the following NTFS features:
- Hard links. Rather rarely used on Windows. However it might be worthwhile to implement them for WinFsp. - Hard links. Rather rarely used on Windows. However it might be worthwhile to implement them for WinFsp.
- Extended attributes. Although popular with POSIX file systems, they are severely hampered and rarely used on Windows. They are also not exposed via the Win32 API.
- Short file names. Short file names are a relic of the past. WinFsp made a conscious decision not to support them. - Short file names. Short file names are a relic of the past. WinFsp made a conscious decision not to support them.
- Paging files. Providing paging file support via a user mode file system is impossible for a number of reasons. - Paging files. Providing paging file support via a user mode file system is impossible for a number of reasons.
- Object ID's. Opening files by ID (+FILE_OPEN_BY_FILE_ID+) is not supported. - Object ID's. Opening files by ID (+FILE_OPEN_BY_FILE_ID+) is not supported.

View File

@ -397,11 +397,13 @@ typedef struct _FSP_LAUNCH_REG_RECORD {
PWSTR RunAs; PWSTR RunAs;
PWSTR Security; PWSTR Security;
PWSTR AuthPackage; PWSTR AuthPackage;
PVOID Reserved0[5]; PWSTR Stderr;
PVOID Reserved0[4];
ULONG JobControl; ULONG JobControl;
ULONG Credentials; ULONG Credentials;
ULONG AuthPackageId; ULONG AuthPackageId;
ULONG Reserved1[5]; ULONG Recovery;
ULONG Reserved1[4];
UINT8 Buffer[]; UINT8 Buffer[];
} FSP_LAUNCH_REG_RECORD; } FSP_LAUNCH_REG_RECORD;
``` ```
@ -414,7 +416,7 @@ typedef struct _FSP_LAUNCH_REG_RECORD {
<br/> <br/>
<p align="center"> <p align="center">
<sub> <sub>
Copyright © 2015-2020 Bill Zissimopoulos Copyright © 2015-2021 Bill Zissimopoulos
<br/> <br/>
Generated with <a href="https://github.com/billziss-gh/prettydoc">prettydoc</a> Generated with <a href="https://github.com/billziss-gh/prettydoc">prettydoc</a>
</sub> </sub>

View File

@ -83,6 +83,8 @@ STATUS\_SUCCESS or error code.
**Discussion** **Discussion**
(NOTE: use of this function is not recommended; use Delete instead.)
This function tests whether a file or directory can be safely deleted. This function does This function tests whether a file or directory can be safely deleted. This function does
not need to perform access checks, but may performs tasks such as check for empty not need to perform access checks, but may performs tasks such as check for empty
directories, etc. directories, etc.
@ -100,6 +102,7 @@ most file systems need only implement the CanDelete operation.
- Cleanup - Cleanup
- SetDelete - SetDelete
- Delete
</blockquote> </blockquote>
@ -129,6 +132,9 @@ VOID ( *Cleanup)(
**Discussion** **Discussion**
(NOTE: use of this function with the FspCleanupDelete flag is not recommended;
use Delete instead.)
When CreateFile is used to open or create a file the kernel creates a kernel mode file When CreateFile is used to open or create a file the kernel creates a kernel mode file
object (type FILE\_OBJECT) and a handle for it, which it returns to user-mode. The handle may object (type FILE\_OBJECT) and a handle for it, which it returns to user-mode. The handle may
be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same
@ -179,6 +185,7 @@ the file was modified/deleted.
- Close - Close
- CanDelete - CanDelete
- SetDelete - SetDelete
- Delete
</blockquote> </blockquote>
@ -368,6 +375,90 @@ 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.
</blockquote>
</details>
<details>
<summary>
<b>Delete</b> - Set the file delete flag or delete a file.
</summary>
<blockquote>
<br/>
```c
NTSTATUS ( *Delete)(
FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext,
PWSTR FileName,
ULONG Flags);
```
**Parameters**
- _FileSystem_ \- The file system on which this request is posted.
- _FileContext_ \- The file context of the file or directory to set the delete flag for.
- _FileName_ \- The name of the file or directory to set the delete flag for.
- _Flags_ \- File disposition flags
**Return Value**
STATUS\_SUCCESS or error code.
**Discussion**
This function replaces CanDelete, SetDelete and uses of Cleanup with the FspCleanupDelete flag
and is recommended for use in all new code.
Due to the complexity of file deletion in the Windows file system this function is used
in many scenarios. Its usage is controlled by the Flags parameter:
- FILE\_DISPOSITION\_DO\_NOT\_DELETE: Unmark the file for deletion.
Do **NOT** delete the file either now or at Cleanup time.
- FILE\_DISPOSITION\_DELETE: Mark the file for deletion,
but do **NOT** delete the file. The file will be deleted at Cleanup time
(via a call to Delete with Flags = -1).
This function does not need to perform access checks, but may
performs tasks such as check for empty directories, etc.
- FILE\_DISPOSITION\_DELETE | FILE\_DISPOSITION\_POSIX\_SEMANTICS: Delete the file**NOW** using POSIX semantics. Open user mode handles to the file remain valid.
This case will be received only when FSP\_FSCTL\_VOLUME\_PARAMS :: SupportsPosixUnlinkRename is set.
- -1: Delete the file **NOW** using regular Windows semantics.
Called during Cleanup with no open user mode handles remaining.
If a file system implements Delete, Cleanup should **NOT** be used for deletion anymore.
This function gets called in all file deletion scenarios:
- When the DeleteFile or RemoveDirectory API's are used.
- When the SetInformationByHandle API with FileDispositionInfo or FileDispositionInfoEx is used.
- When a file is opened using FILE\_DELETE\_ON\_CLOSE.
- Etc.
NOTE: Delete takes precedence over CanDelete, SetDelete and Cleanup with the FspCleanupDelete flag.
This means that if Delete is defined, CanDelete and SetDelete will never be called and
Cleanup will never be called with the FspCleanupDelete flag.
**See Also**
- Cleanup
- CanDelete
- SetDelete
</blockquote> </blockquote>
</details> </details>
@ -1111,6 +1202,8 @@ STATUS\_SUCCESS or error code.
**Discussion** **Discussion**
(NOTE: use of this function is not recommended; use Delete instead.)
This function sets a flag to indicates whether the FSD file should delete a file This function sets a flag to indicates whether the FSD file should delete a file
when it is closed. This function does not need to perform access checks, but may when it is closed. This function does not need to perform access checks, but may
performs tasks such as check for empty directories, etc. performs tasks such as check for empty directories, etc.
@ -1128,6 +1221,7 @@ most file systems need only implement the CanDelete operation.
- Cleanup - Cleanup
- CanDelete - CanDelete
- Delete
</blockquote> </blockquote>
@ -1504,6 +1598,47 @@ This is a helper for implementing the GetEa operation.
- GetEa - GetEa
</blockquote>
</details>
<details>
<summary>
<b>FspFileSystemAddNotifyInfo</b> - Add notify information to a buffer.
</summary>
<blockquote>
<br/>
```c
FSP_API BOOLEAN FspFileSystemAddNotifyInfo(
FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
PVOID Buffer,
ULONG Length,
PULONG PBytesTransferred);
```
**Parameters**
- _NotifyInfo_ \- The notify information to add.
- _Buffer_ \- Pointer to a buffer that will receive the notify information.
- _Length_ \- Length of buffer.
- _PBytesTransferred_ \- [out]
Pointer to a memory location that will receive the actual number of bytes stored. This should
be initialized to 0 prior to the first call to FspFileSystemAddNotifyInfo for a particular
buffer.
**Return Value**
TRUE if the notify information was added, FALSE if there was not enough space to add it.
**Discussion**
This is a helper for filling a buffer to use with FspFileSystemNotify.
**See Also**
- FspFileSystemNotify
</blockquote> </blockquote>
</details> </details>
@ -1851,6 +1986,123 @@ The current operation context is stored in thread local storage. It allows acces
Request and Response associated with this operation. Request and Response associated with this operation.
</blockquote>
</details>
<details>
<summary>
<b>FspFileSystemNotify</b> - Notify Windows that the file system has file changes.
</summary>
<blockquote>
<br/>
```c
FSP_API NTSTATUS FspFileSystemNotify(
FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
SIZE_T Size);
```
**Parameters**
- _FileSystem_ \- The file system object.
- _NotifyInfo_ \- Buffer containing information about file changes.
- _Size_ \- Size of buffer.
**Return Value**
STATUS\_SUCCESS or error code.
**Discussion**
A file system that wishes to notify Windows about file changes must
first issue an FspFileSystemBegin call, followed by 0 or more
FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
Note that FspFileSystemNotify requires file names to be normalized. A
normalized file name is one that contains the correct case of all characters
in the file name.
For case-sensitive file systems all file names are normalized by definition.
For case-insensitive file systems that implement file name normalization,
a normalized file name is the one that the file system specifies in the
response to Create or Open (see also FspFileSystemGetOpenFileInfo). For
case-insensitive file systems that do not implement file name normalization
a normalized file name is the upper case version of the file name used
to open the file.
</blockquote>
</details>
<details>
<summary>
<b>FspFileSystemNotifyBegin</b> - Begin notifying Windows that the file system has file changes.
</summary>
<blockquote>
<br/>
```c
FSP_API NTSTATUS FspFileSystemNotifyBegin(
FSP_FILE_SYSTEM *FileSystem,
ULONG Timeout);
```
**Parameters**
- _FileSystem_ \- The file system object.
**Return Value**
STATUS\_SUCCESS or error code. The error code STATUS\_CANT\_WAIT means that
a file rename operation is currently in progress and the operation must be
retried at a later time.
**Discussion**
A file system that wishes to notify Windows about file changes must
first issue an FspFileSystemBegin call, followed by 0 or more
FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
This operation blocks concurrent file rename operations. File rename
operations may interfere with file notification, because a file being
notified may also be concurrently renamed. After all file change
notifications have been issued, you must make sure to call
FspFileSystemNotifyEnd to allow file rename operations to proceed.
</blockquote>
</details>
<details>
<summary>
<b>FspFileSystemNotifyEnd</b> - End notifying Windows that the file system has file changes.
</summary>
<blockquote>
<br/>
```c
FSP_API NTSTATUS FspFileSystemNotifyEnd(
FSP_FILE_SYSTEM *FileSystem);
```
**Parameters**
- _FileSystem_ \- The file system object.
**Return Value**
STATUS\_SUCCESS or error code.
**Discussion**
A file system that wishes to notify Windows about file changes must
first issue an FspFileSystemBegin call, followed by 0 or more
FspFileSystemNotify calls, followed by an FspFileSystemNotifyEnd call.
This operation allows any blocked file rename operations to proceed.
</blockquote> </blockquote>
</details> </details>
@ -2613,7 +2865,7 @@ in a clean manner by calling this function.
<br/> <br/>
<p align="center"> <p align="center">
<sub> <sub>
Copyright © 2015-2020 Bill Zissimopoulos Copyright © 2015-2021 Bill Zissimopoulos
<br/> <br/>
Generated with <a href="https://github.com/billziss-gh/prettydoc">prettydoc</a> Generated with <a href="https://github.com/billziss-gh/prettydoc">prettydoc</a>
</sub> </sub>

View File

@ -0,0 +1,124 @@
= WinFsp Delete Redesign
WinFsp has had its Delete functionality redesigned in release 2021.1 Beta3. This redesign unifies all Windows file deletion semantics under a single file system operation that also supports the new POSIX semantics introduced in Windows 10 Redstone 1. The new Delete design is recommended for new file systems, however existing file systems will continue to work without any changes.
== Background
In this section we discuss how file deletion worked in Windows traditionally as well as the changes introduced in recent versions of Windows 10.
=== Traditional File Deletion
The traditional method for deleting a file or directory on Windows involves the following steps:
- Open the file using https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntopenfile[`NtOpenFile`] (or equivalent) with `DELETE` access.
- Set the "disposition" flag on the file handle using https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntsetinformationfile[`NtSetInformationFile`] with `FileDispositionInformation`. This only marks the file for deletion and does not delete the file.
- Close the file using https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntclose[`NtClose`] (or equivalent). Provided that there are no other open handles to the file, the file is actually deleted at this stage.
This is the method that https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilew[`DeleteFileW`] and https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectoryw[`RemoveDirectoryW`] use to delete a file or directory.
An alternative method involves the `FILE_DELETE_ON_CLOSE` flag:
- Open the file using https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntopenfile[`NtOpenFile`] (or equivalent) with the `FILE_DELETE_ON_CLOSE` option.
- Close the file using https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntclose[`NtClose`] (or equivalent). Provided that there are no other open handles to the file, the file is actually deleted at this stage.
This alternative method does not set the disposition flag and therefore does not have chance to perform any associated checks. An important disposition flag check is whether a directory is empty: attempting to remove a non-empty directory using `FILE_DELETE_ON_CLOSE` will fail silently, because there is no way to communicate a file deletion error from `NtClose`.
In order to better understand those scenarios let's examine what happens within the kernel and the file system driver (FSD).
When the kernel receives a file API call such as `NtOpenFile`, it packages the call arguments into a data structure called an "I/O Request Packet" (IRP) and forwards it to the appropriate FSD. Each IRP contains a field that describes its function, for example, `IRP_MJ_CREATE` for `NtOpenFile` and `IRP_MJ_SET_INFORMATION` for `NtSetInformationFile`.
With this knowledge we can now examine what happens in the `DeleteFileW` / `RemoveDirectoryW` scenario:
- Open the file using `NtOpenFile`: The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-create[`IRP_MJ_CREATE`] IRP, places inside it a newly created https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_object[`FILE_OBJECT`] and forwards it to the FSD. If opening the file succeeds, the kernel will also create a `HANDLE` that is used to refer to this `FILE_OBJECT`; if opening the file fails, this `FILE_OBJECT` will be destroyed.
- Set the "disposition" flag on the file handle using `NtSetInformationFile` with `FileDispositionInformation`: The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-set-information[`IRP_MJ_SET_INFORMATION`] IRP and passes the `FileDispositionInformation` information in it. The FSD performs some checks (e.g. if a directory is empty) and if they succeed it marks the file for deletion.
- Close the file using `NtClose`: The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-cleanup[`IRP_MJ_CLEANUP`] IRP, which denotes that all ``HANDLE``s that refer to a `FILE_OBJECT` are closed. (It is possible to have multiple ``HANDLE``s to the same `FILE_OBJECT` by using an API such as https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle[`DuplicateHandle`].) The FSD checks and if this is the last `FILE_OBJECT` cleaned up for the file and if the file is marked for deletion, it deletes the file. Traditionally there was no way to return an error from `IRP_MJ_CLEANUP`.
- Notice that while the file is closed from the perspective of user mode, it is not closed from the perspective of kernel mode. The kernel and the FSD maintain both a handle count and a reference count for the `FILE_OBJECT`. When the handle count goes to `0` then an `IRP_MJ_CLEANUP` IRP is issued (see above). When the reference count goes to `0` then a different https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/irp-mj-close[`IRP_MJ_CLOSE`] IRP is issued to the FSD. This signifies to the FSD that the `FILE_OBJECT` is going away and the file is fully closed (including from the kernel perspective). There is no way to return an error from `IRP_MJ_CLOSE`.
The situation is similar in the `FILE_DELETE_ON_CLOSE` scenario, with the important difference that the FSD marks the file for deletion immediately upon receiving the `IRP_MJ_CREATE` IRP and that it never receives the `IRP_MJ_SET_INFORMATION` IRP. As before the actual deletion happens in `IRP_MJ_CLEANUP` and only when the last `HANDLE` to the file is closed.
Some important takeaways:
- It is possible for a file to already be open when a `DeleteFileW` / `RemoveDirectoryW` (or equivalent sequence of `NtOpenFile`, `NtSetInformationFile`, `NtClose`, etc.) is executed. This means that the file may NOT be deleted upon return from the `DeleteFileW` / `RemoveDirectoryW` call even though these API's report success. **Traditionally a successful return from `DeleteFileW` / `RemoveDirectory` signifies only that the file or directory has been successfully marked for deletion and not that it has been deleted!**
- The `NtClose` call does not return error codes from `IRP_MJ_CLEANUP`. This means that it is impossible for user mode to know whether a file marked for deletion was deleted or not.
- The `FILE_OBJECT` remains valid even after a file has been deleted in `IRP_MJ_CLEANUP`. It is therefore possible to receive additional I/O (e.g. read/write) on the file. Many Windows file systems (including at least some versions of NTFS) do not handle this case very well.
=== File Deletion in Recent Versions of Windows 10
In Windows 10 Redstone 1 Microsoft introduced the `FileDispositionInformationEx` information class. This new information class can be used to request POSIX semantics for file deletion during the `NtSetInformationFile` call. POSIX semantics for file deletion mean that when a file is deleted any open handles to it remain valid and can be used for I/O such as read/write.
Some time later (unclear exactly when) Microsoft changed the `DeleteFileW` / `RemoveDirectoryW` API's to use the `FileDispositionInformationEx` information class and only if this fails (e.g. because the file system is not capable) fall back to the old `FileDispositionInformation` information class. With this change `DeleteFileW` and `RemoveDirectoryW` actually delete the file or directory rather than simply mark it for deletion. (This change is in general a good thing, but can create incompatibility problems for applications that expect the traditional behavior.)
Let's examine the `DeleteFileW` / `RemoveDirectoryW` scenario again:
- Open the file using `NtOpenFile`: The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-create[`IRP_MJ_CREATE`] IRP, places inside it a newly created https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_file_object[`FILE_OBJECT`] and forwards it to the FSD. If opening the file succeeds, the kernel will also create a `HANDLE` that is used to refer to this `FILE_OBJECT`; if opening the file fails, this `FILE_OBJECT` will be destroyed.
- Intruct the file system to delete the file with POSIX semantics using `NtSetInformationFile` with `FileDispositionInformationEx`. The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-set-information[`IRP_MJ_SET_INFORMATION`] IRP and passes the `FileDispositionInformationEx` information in it. The FSD performs some checks (e.g. if a directory is empty) and if they succeed it deletes the file or directory (as opposed to simply mark it for deletion).
- Close the file using `NtClose`. The kernel creates an https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/irp-mj-cleanup[`IRP_MJ_CLEANUP`] IRP, which denotes that all ``HANDLE``s that refer to a `FILE_OBJECT` are closed. The FSD has already deleted the file and does not need to do anything else.
- As before an `IRP_MJ_CLOSE` IRP will also be sent to the FSD eventually.
Notice that the actual file deletion happens during `NtSetInformationFile` and the return code from this API reports on the success or failure of the file deletion. Thus we no longer have the problems discussed earlier and `DeleteFileW` / `RemoveDirectoryW` correctly report whether the file was deleted or not.
== WinFsp Support for POSIX Unlink
WinFsp gained support for POSIX Unlink (`FileDispositionInformationEx`) and POSIX Rename (`FileRenameInformationEx`) in release 2021.1 Beta3. To enable this support a native or .NET file system must set the `SupportsPosixUnlinkRename` flag when the file system is created. FUSE file systems have this flag enabled by default (but can be disabled with the command line option `-o LegacyUnlinkRename`).
The POSIX Unlink support spurred some changes in the WinFsp native and .NET API's with regards to file deletion. The WinFsp FUSE layer transparently supports these changes.
Prior to release 2021.1 Beta3, user mode file systems handled file deletion by implementing `CanDelete` / `SetDelete` to check the file disposition flag and `Cleanup` with the `FspCleanupDelete` flag to perform the actual file deletion. From release 2021.1 Beta3 forward the recommended method is to use the new `Delete` file system operation to handle all aspects of file deletion.
The new `Delete` operation follows the general pattern below:
[source,c]
----
NTSTATUS Delete(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, ULONG Flags)
{
switch (Flags)
{
case FILE_DISPOSITION_DO_NOT_DELETE:
// set file disposition flag: do not delete file at Cleanup time
case FILE_DISPOSITION_DELETE:
// set file disposition flag: delete file at Cleanup time
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
// delete file now; open handles to file remain valid
case -1:
// delete file now; called during Cleanup time
default:
return STATUS_INVALID_PARAMETER;
}
}
----
As can be seen the `Delete` operation handles marking (`FILE_DISPOSITION_DELETE`) and unmarking (`FILE_DISPOSITION_DO_NOT_DELETE`) a file for deletion, performing file deletion with POSIX semantics (`FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS`) and performing file deletion with traditional Windows semantics (`-1`). If the Delete operation is defined it is used instead of `CanDelete` / `SetDelete` and `Cleanup` with the `FspCleanupDelete` flag, even if these operations are also defined.
A sensible implementation of `Delete` might look something similar to the following:
[source,c]
----
NTSTATUS Delete(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, ULONG Flags)
{
switch (Flags)
{
case FILE_DISPOSITION_DO_NOT_DELETE:
return STATUS_SUCCESS;
case FILE_DISPOSITION_DELETE:
if (IsNotEmptyDirectory(FileSystem, FileContext))
return STATUS_DIRECTORY_NOT_EMPTY;
return STATUS_SUCCESS;
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
case -1:
if (IsNotEmptyDirectory(FileSystem, FileContext))
return STATUS_DIRECTORY_NOT_EMPTY;
return RealDeleteFileOrDirectory(FileSystem, FileContext);
default:
return STATUS_INVALID_PARAMETER;
}
}
----

View File

@ -0,0 +1,59 @@
= WinFsp Rebranding
If you have a commercial WinFsp license and wish to produce a rebranded version of WinFsp, you can follow the instructions in this document.
== Overview
The WinFsp build is controlled by the file `build\VStudio\version.properties`. The file contains properties that control the final build output in a number of ways. Some of the properties in this file control how the final build product is branded, others how it is versioned, etc.
=== Branding
The properties that control branding are the following:
* `MyProductName`: This is the overall product name. It should be a short name without spaces. For example: `MyCompanyFSP`. The default value is `WinFsp`.
* `MyProductFileName`: This is the file name that will be used for the primary WinFsp components. For example: if you use `mycompanyfsp` the FSD will be named `mycompanyfsp-x64.sys` and `mycompanyfsp-x86.sys`, the DLL will be named `mycompanyfsp-x64.dll` and `mycompanyfsp-x86.dll`, etc. The default value is `winfsp`. (Note that due to a limitation the WinFsp .NET implementation assumes that `MyProductFileName` is the lowercase version of `MyProductName`.)
* `MyDescription`: This is a longer product description. For example: `MyCompany File System Proxy`. The default value is `Windows File System Proxy`.
* `MyCompanyName`: This is the company name.
* `MyCopyright`: This is the product's copyright.
* `MyFspFsctlDeviceClassGuid`, `MyFspFsvrtDeviceClassGuid`: When creating devices the FSD needs to assign GUID classes to them; it uses the GUIDs specified by these properties. You MUST change these GUIDs when rebranding; otherwise your product and "official" WinFsp releases may interfere with each other. From the Visual Studio main menu use Tools > Create GUID and select option "3. static const struct GUID" to produce GUIDs in the correct format.
=== Versioning
The properties that control versioning are the following:
* `MyCanonicalVersion`: This is the "canonical" (i.e. non-marketing) version of the product. WinFsp uses a `major.minor.build` versioning scheme. The `major.minor` portion of the version comes from this property; build numbers are computed automatically from the current date.
** Some WinFsp components check that canonical versions of different components match. For example, the WinFsp .NET implementation checks that its major version matches the one from the WinFsp DLL.
* `MyProductVersion`: This is the product (i.e. marketing) version of the product. WinFsp uses the release year as the product version; it also adds a point release for subsequent releases (thus 2021 is the first release in 2021, and 2021.1 is the second release, etc). This property may be an arbitrary string.
* `MyProductStage`: This specifies the kind of the build. Allowed values are `Beta`, `RC` (Release Candidate) and `Gold` (Final).
== Limitations
Currently WinFsp supports rebranding of the core WinFsp components:
* The WinFsp FSD (File System Driver).
* The WinFsp DLL (user mode DLL). This includes the DLL import libraries.
* The WinFsp Launcher (Windows service that allows for easy launching of file systems).
Currently WinFsp does not support rebranding of the following components:
* Development files such as header files, samples, etc. These are not end-user visible and therefore are not necessary to be rebranded.
* WinFsp test suites.
* FUSE for Cygwin.
* Chocolatey builds.
Additional limitations:
* The default installer (in file `build\VStudio\installer\Product.wxs`) contains a number of GUIDs. These MUST be changed if the default installer is used by a rebranded product; otherwise installation of your product and "official" WinFsp releases may interfere with each other. There is a Python script at `tools\gensrc\wixguid.py` that can help with this.

View File

@ -1,7 +1,7 @@
/** /**
* @file tlib/callstack.c * @file tlib/callstack.c
* *
* @copyright 2014-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2014-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -79,7 +79,7 @@ struct fuse_operations
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi); /* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
/* S */ void *(*init)(struct fuse_conn_info *conn); /* S */ void *(*init)(struct fuse_conn_info *conn);
/* S */ void (*destroy)(void *data); /* S */ void (*destroy)(void *data);
/* _ */ int (*access)(const char *path, int mask); /* S */ int (*access)(const char *path, int mask);
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi); /* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi); /* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi); /* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);

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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -54,6 +54,7 @@ extern "C" {
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */ #define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */ #define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */ #define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
#define FSP_FUSE_CAP_DELETE_ACCESS (1 << 24) /* file system supports access with DELETE_OK */
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE #define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
#define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_COMPAT (1 << 0)
@ -79,6 +80,9 @@ extern "C" {
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE #define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
#endif #endif
/* delete access */
#define FSP_FUSE_DELETE_OK 0x40000000
/* notify extension */ /* notify extension */
#define FSP_FUSE_NOTIFY_MKDIR 0x0001 #define FSP_FUSE_NOTIFY_MKDIR 0x0001
#define FSP_FUSE_NOTIFY_RMDIR 0x0002 #define FSP_FUSE_NOTIFY_RMDIR 0x0002

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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -35,17 +35,36 @@ extern "C" {
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(1,"") #define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(1,"")
#endif #endif
#define FSP_FSCTL_DRIVER_NAME "WinFsp" #define FSP_FSCTL_STR(x) FSP_FSCTL_STR_(x)
#define FSP_FSCTL_DISK_DEVICE_NAME "WinFsp.Disk" #define FSP_FSCTL_STR_(x) #x
#define FSP_FSCTL_NET_DEVICE_NAME "WinFsp.Net" #if defined(MyProductName)
#define FSP_FSCTL_MUP_DEVICE_NAME "WinFsp.Mup" #define FSP_FSCTL_PRODUCT_NAME FSP_FSCTL_STR(MyProductName)
#else
#define FSP_FSCTL_PRODUCT_NAME "WinFsp"
#endif
#if defined(MyProductFileName)
#define FSP_FSCTL_PRODUCT_FILE_NAME FSP_FSCTL_STR(MyProductFileName)
#else
#define FSP_FSCTL_PRODUCT_FILE_NAME "winfsp"
#endif
// {6F9D25FA-6DEE-4A9D-80F5-E98E14F35E54} #define FSP_FSCTL_DRIVER_NAME FSP_FSCTL_PRODUCT_NAME
#define FSP_FSCTL_DISK_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Disk"
#define FSP_FSCTL_NET_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Net"
#define FSP_FSCTL_MUP_DEVICE_NAME FSP_FSCTL_DRIVER_NAME ".Mup"
#if defined(MyFspFsctlDeviceClassGuid)
extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = MyFspFsctlDeviceClassGuid;
#else
extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid = extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid =
{ 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } }; { 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } };
// {B48171C3-DD50-4852-83A3-344C50D93B17} #endif
#if defined(MyFspFsvrtDeviceClassGuid)
extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = MyFspFsvrtDeviceClassGuid;
#else
extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
{ 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } }; { 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } };
#endif
/* alignment macros */ /* alignment macros */
#define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s) - 1L)) & ~((s) - 1L)) #define FSP_FSCTL_ALIGN_UP(x, s) (((x) + ((s) - 1L)) & ~((s) - 1L))
@ -66,6 +85,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 't', METHOD_OUT_DIRECT, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 't', METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#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)
#define FSP_FSCTL_STOP0 \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 's', METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSP_FSCTL_NOTIFY \ #define FSP_FSCTL_NOTIFY \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'n', METHOD_NEITHER, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'n', METHOD_NEITHER, FILE_ANY_ACCESS)
@ -183,7 +204,8 @@ enum
UINT32 WslFeatures:1; /* support features required for WSLinux */\ UINT32 WslFeatures:1; /* support features required for WSLinux */\
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\ 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 RejectIrpPriorToTransact0:1; /* reject IRP's prior to FspFsctlTransact with 0 buffers */\
UINT32 KmReservedFlags:3;\ UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\
UINT32 KmReservedFlags:2;\
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\
@ -392,6 +414,10 @@ typedef struct
UINT32 Delete:1; UINT32 Delete:1;
} Disposition; } Disposition;
struct struct
{
UINT32 Flags;
} DispositionEx;
struct
{ {
UINT64 FileSize; UINT64 FileSize;
} EndOfFile; } EndOfFile;
@ -400,6 +426,12 @@ typedef struct
FSP_FSCTL_TRANSACT_BUF NewFileName; FSP_FSCTL_TRANSACT_BUF NewFileName;
UINT64 AccessToken; /* request access token (PID,HANDLE) */ UINT64 AccessToken; /* request access token (PID,HANDLE) */
} Rename; } Rename;
struct
{
FSP_FSCTL_TRANSACT_BUF NewFileName;
UINT64 AccessToken; /* request access token (PID,HANDLE) */
UINT32 Flags;
} RenameEx;
} Info; } Info;
} SetInformation; } SetInformation;
struct struct
@ -628,6 +660,7 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
PVOID RequestBuf, SIZE_T *PRequestBufSize, PVOID RequestBuf, SIZE_T *PRequestBufSize,
BOOLEAN Batch); BOOLEAN Batch);
FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle); FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle);
FSP_API NTSTATUS FspFsctlStop0(HANDLE VolumeHandle);
FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle, FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle,
FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size); FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size);
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath, FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,

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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -32,10 +32,10 @@
extern "C" { extern "C" {
#endif #endif
#define FSP_LAUNCH_REGKEY "Software\\WinFsp\\Services" #define FSP_LAUNCH_REGKEY "Software\\" FSP_FSCTL_PRODUCT_NAME "\\Services"
#define FSP_LAUNCH_REGKEY_WOW64 KEY_WOW64_32KEY #define FSP_LAUNCH_REGKEY_WOW64 KEY_WOW64_32KEY
#define FSP_LAUNCH_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" #define FSP_LAUNCH_PIPE_NAME "\\\\.\\pipe\\" FSP_FSCTL_PRODUCT_NAME ".{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
#define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096 #define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096
#define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid) #define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid)

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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -47,6 +47,19 @@
extern "C" { extern "C" {
#endif #endif
/*
* The FILE_DISPOSITION_* definitions appear to be missing from the user mode headers.
*/
#if !defined(FILE_DISPOSITION_DELETE)
#define FILE_DISPOSITION_DO_NOT_DELETE 0x00000000
#define FILE_DISPOSITION_DELETE 0x00000001
#define FILE_DISPOSITION_POSIX_SEMANTICS 0x00000002
/* remaining flags are not needed for user mode file systems but included for completeness */
#define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK 0x00000004
#define FILE_DISPOSITION_ON_CLOSE 0x00000008
#define FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE 0x00000010
#endif
/* /*
* The REPARSE_DATA_BUFFER definitions appear to be missing from the user mode headers. * The REPARSE_DATA_BUFFER definitions appear to be missing from the user mode headers.
*/ */
@ -91,6 +104,7 @@ typedef struct _REPARSE_DATA_BUFFER
#if !defined(FILE_NEED_EA) #if !defined(FILE_NEED_EA)
#define FILE_NEED_EA 0x00000080 #define FILE_NEED_EA 0x00000080
#endif #endif
#if !defined(__MINGW32__)
typedef struct _FILE_FULL_EA_INFORMATION typedef struct _FILE_FULL_EA_INFORMATION
{ {
ULONG NextEntryOffset; ULONG NextEntryOffset;
@ -99,6 +113,7 @@ typedef struct _FILE_FULL_EA_INFORMATION
USHORT EaValueLength; USHORT EaValueLength;
CHAR EaName[1]; CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION; } FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
#endif
/** /**
* @group File System * @group File System
@ -346,6 +361,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
/** /**
* Cleanup a file. * Cleanup a file.
* *
* (NOTE: use of this function with the FspCleanupDelete flag is not recommended;
* use Delete instead.)
*
* When CreateFile is used to open or create a file the kernel creates a kernel mode file * When CreateFile is used to open or create a file the kernel creates a kernel mode file
* object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may * object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may
* be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same * be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same
@ -400,6 +418,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* Close * Close
* CanDelete * CanDelete
* SetDelete * SetDelete
* Delete
*/ */
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, ULONG Flags); PVOID FileContext, PWSTR FileName, ULONG Flags);
@ -573,6 +592,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
/** /**
* Determine whether a file or directory can be deleted. * Determine whether a file or directory can be deleted.
* *
* (NOTE: use of this function is not recommended; use Delete instead.)
*
* This function tests whether a file or directory can be safely deleted. This function does * This function tests whether a file or directory can be safely deleted. This function does
* not need to perform access checks, but may performs tasks such as check for empty * not need to perform access checks, but may performs tasks such as check for empty
* directories, etc. * directories, etc.
@ -597,6 +618,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* @see * @see
* Cleanup * Cleanup
* SetDelete * SetDelete
* Delete
*/ */
NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName); PVOID FileContext, PWSTR FileName);
@ -878,6 +900,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
/** /**
* Set the file delete flag. * Set the file delete flag.
* *
* (NOTE: use of this function is not recommended; use Delete instead.)
*
* This function sets a flag to indicates whether the FSD file should delete a file * This function sets a flag to indicates whether the FSD file should delete a file
* when it is closed. This function does not need to perform access checks, but may * when it is closed. This function does not need to perform access checks, but may
* performs tasks such as check for empty directories, etc. * performs tasks such as check for empty directories, etc.
@ -906,6 +930,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* @see * @see
* Cleanup * Cleanup
* CanDelete * CanDelete
* Delete
*/ */
NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile); PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile);
@ -1038,12 +1063,65 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
PVOID FileContext, PVOID FileContext,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
FSP_FSCTL_FILE_INFO *FileInfo); FSP_FSCTL_FILE_INFO *FileInfo);
/**
* Set the file delete flag or delete a file.
*
* This function replaces CanDelete, SetDelete and uses of Cleanup with the FspCleanupDelete flag
* and is recommended for use in all new code.
*
* Due to the complexity of file deletion in the Windows file system this function is used
* in many scenarios. Its usage is controlled by the Flags parameter:
* <ul>
* <li>FILE_DISPOSITION_DO_NOT_DELETE: Unmark the file for deletion.
* Do <b>NOT</b> delete the file either now or at Cleanup time.</li>
* <li>FILE_DISPOSITION_DELETE: Mark the file for deletion,
* but do <b>NOT</b> delete the file. The file will be deleted at Cleanup time
* (via a call to Delete with Flags = -1).
* This function does not need to perform access checks, but may
* performs tasks such as check for empty directories, etc.</li>
* <li>FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS: Delete the file
* <b>NOW</b> using POSIX semantics. Open user mode handles to the file remain valid.
* This case will be received only when FSP_FSCTL_VOLUME_PARAMS :: SupportsPosixUnlinkRename is set.</li>
* <li>-1: Delete the file <b>NOW</b> using regular Windows semantics.
* Called during Cleanup with no open user mode handles remaining.
* If a file system implements Delete, Cleanup should <b>NOT</b> be used for deletion anymore.</li>
* </ul>
*
* This function gets called in all file deletion scenarios:
* <ul>
* <li>When the DeleteFile or RemoveDirectory API's are used.</li>
* <li>When the SetInformationByHandle API with FileDispositionInfo or FileDispositionInfoEx is used.</li>
* <li>When a file is opened using FILE_DELETE_ON_CLOSE.</li>
* <li>Etc.</li>
* </ul>
*
* NOTE: Delete takes precedence over CanDelete, SetDelete and Cleanup with the FspCleanupDelete flag.
* This means that if Delete is defined, CanDelete and SetDelete will never be called and
* Cleanup will never be called with the FspCleanupDelete flag.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the file or directory to set the delete flag for.
* @param FileName
* The name of the file or directory to set the delete flag for.
* @param Flags
* File disposition flags
* @return
* STATUS_SUCCESS or error code.
* @see
* Cleanup
* CanDelete
* SetDelete
*/
NTSTATUS (*Delete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, ULONG Flags);
/* /*
* This ensures that this interface will always contain 64 function pointers. * This ensures that this interface will always contain 64 function pointers.
* Please update when changing the interface as it is important for future compatibility. * Please update when changing the interface as it is important for future compatibility.
*/ */
NTSTATUS (*Reserved[33])(); NTSTATUS (*Reserved[32])();
} FSP_FILE_SYSTEM_INTERFACE; } FSP_FILE_SYSTEM_INTERFACE;
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()), FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries."); "FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
@ -1381,7 +1459,8 @@ UINT32 FspFileSystemOperationProcessId(VOID)
case FspFsctlTransactCreateKind: case FspFsctlTransactCreateKind:
return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken); return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken);
case FspFsctlTransactSetInformationKind: case FspFsctlTransactSetInformationKind:
if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass)
return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken); return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken);
/* fall through! */ /* fall through! */
default: default:
@ -1826,6 +1905,10 @@ FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode, UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor); PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMergePermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR ExistingSecurityDescriptor,
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); PUINT32 PUid, PUINT32 PGid, PUINT32 PMode);
@ -2108,9 +2191,9 @@ static inline
NTSTATUS FspLoad(PVOID *PModule) NTSTATUS FspLoad(PVOID *PModule)
{ {
#if defined(_WIN64) #if defined(_WIN64)
#define FSP_DLLNAME "winfsp-x64.dll" #define FSP_DLLNAME FSP_FSCTL_PRODUCT_FILE_NAME "-x64.dll"
#else #else
#define FSP_DLLNAME "winfsp-x86.dll" #define FSP_DLLNAME FSP_FSCTL_PRODUCT_FILE_NAME "-x86.dll"
#endif #endif
#define FSP_DLLPATH "bin\\" FSP_DLLNAME #define FSP_DLLPATH "bin\\" FSP_DLLNAME
@ -2138,7 +2221,7 @@ NTSTATUS FspLoad(PVOID *PModule)
Module = LoadLibraryW(L"" FSP_DLLNAME); Module = LoadLibraryW(L"" FSP_DLLNAME);
if (0 == Module) if (0 == Module)
{ {
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\WinFsp", Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\" FSP_FSCTL_PRODUCT_NAME,
0, KEY_READ | KEY_WOW64_32KEY, &RegKey); 0, KEY_READ | KEY_WOW64_32KEY, &RegKey);
if (ERROR_SUCCESS == Result) if (ERROR_SUCCESS == Result)
{ {

View File

@ -2,7 +2,7 @@
* @file winfsp/winfsp.hpp * @file winfsp/winfsp.hpp
* WinFsp C++ Layer. * WinFsp C++ Layer.
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -649,7 +649,7 @@ public:
NTSTATUS Preflight(PWSTR MountPoint) NTSTATUS Preflight(PWSTR MountPoint)
{ {
return FspFileSystemPreflight( return FspFileSystemPreflight(
_VolumeParams.Prefix[0] ? L"WinFsp.Net" : L"WinFsp.Disk", _VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME,
MountPoint); MountPoint);
} }
NTSTATUS Mount(PWSTR MountPoint, NTSTATUS Mount(PWSTR MountPoint,
@ -669,7 +669,7 @@ public:
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
Result = FspFileSystemCreate( Result = FspFileSystemCreate(
_VolumeParams.Prefix[0] ? L"WinFsp.Net" : L"WinFsp.Disk", _VolumeParams.Prefix[0] ? L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME,
&_VolumeParams, Interface(), &_FileSystemPtr); &_VolumeParams, Interface(), &_FileSystemPtr);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;

View File

@ -1,7 +1,7 @@
/** /**
* @file fuse/cygfuse.c * @file fuse/cygfuse.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file winfsp/fsext.h * @file winfsp/fsext.h
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/debug.c * @file dll/debug.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -477,6 +477,18 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
UserContextBuf), UserContextBuf),
Request->Req.SetInformation.Info.Disposition.Delete ? "Delete" : "Undelete"); Request->Req.SetInformation.Info.Disposition.Delete ? "Delete" : "Undelete");
break; break;
case 64/*FileDispositionInformationEx*/:
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [DispositionEx] %s%S%s%s, "
"Flags=%lx\n",
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
Request->FileName.Size ? "\"" : "",
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
Request->FileName.Size ? "\", " : "",
FspDebugLogUserContextString(
Request->Req.SetInformation.UserContext, Request->Req.SetInformation.UserContext2,
UserContextBuf),
Request->Req.SetInformation.Info.DispositionEx.Flags);
break;
case 10/*FileRenameInformation*/: case 10/*FileRenameInformation*/:
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [Rename] %s%S%s%s, " FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [Rename] %s%S%s%s, "
"NewFileName=\"%S\", AccessToken=%p[PID=%lx]\n", "NewFileName=\"%S\", AccessToken=%p[PID=%lx]\n",
@ -491,6 +503,21 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken), FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken),
FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken)); FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken));
break; break;
case 65/*FileRenameInformationEx*/:
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [RenameEx] %s%S%s%s, "
"NewFileName=\"%S\", AccessToken=%p[PID=%lx], Flags=%lx\n",
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
Request->FileName.Size ? "\"" : "",
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
Request->FileName.Size ? "\", " : "",
FspDebugLogUserContextString(
Request->Req.SetInformation.UserContext, Request->Req.SetInformation.UserContext2,
UserContextBuf),
(PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken),
FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken),
Request->Req.SetInformation.Info.RenameEx.Flags);
break;
default: default:
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [INVALID] %s%S%s%s\n", FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [INVALID] %s%S%s%s\n",
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint, FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/dirbuf.c * @file dll/dirbuf.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -349,7 +349,7 @@ exit:
FspFileSystemSetDispatcherResult(FileSystem, Result); FspFileSystemSetDispatcherResult(FileSystem, Result);
FspFsctlStop(FileSystem->VolumeHandle); FspFsctlStop0(FileSystem->VolumeHandle);
if (0 != DispatcherThread) if (0 != DispatcherThread)
{ {
@ -398,11 +398,13 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem)
if (0 == FileSystem->DispatcherThread) if (0 == FileSystem->DispatcherThread)
return; return;
FspFsctlStop(FileSystem->VolumeHandle); FspFsctlStop0(FileSystem->VolumeHandle);
WaitForSingleObject(FileSystem->DispatcherThread, INFINITE); WaitForSingleObject(FileSystem->DispatcherThread, INFINITE);
CloseHandle(FileSystem->DispatcherThread); CloseHandle(FileSystem->DispatcherThread);
FileSystem->DispatcherThread = 0; FileSystem->DispatcherThread = 0;
FspFsctlStop(FileSystem->VolumeHandle);
} }
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
@ -423,7 +425,7 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
{ {
FspFileSystemSetDispatcherResult(FileSystem, Result); FspFileSystemSetDispatcherResult(FileSystem, Result);
FspFsctlStop(FileSystem->VolumeHandle); FspFsctlStop0(FileSystem->VolumeHandle);
} }
} }

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fsctl.c * @file dll/fsctl.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -161,6 +161,16 @@ FSP_API NTSTATUS FspFsctlStop(HANDLE VolumeHandle)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
FSP_API NTSTATUS FspFsctlStop0(HANDLE VolumeHandle)
{
DWORD Bytes;
if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_STOP0, 0, 0, 0, 0, &Bytes, 0))
return FspNtStatusFromWin32(GetLastError());
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle, FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle,
FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size) FSP_FSCTL_NOTIFY_INFO *NotifyInfo, SIZE_T Size)
{ {
@ -254,6 +264,7 @@ FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath)
static NTSTATUS FspFsctlStartService(VOID) static NTSTATUS FspFsctlStartService(VOID)
{ {
static SRWLOCK Lock = SRWLOCK_INIT;
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME; PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
SC_HANDLE ScmHandle = 0; SC_HANDLE ScmHandle = 0;
SC_HANDLE SvcHandle = 0; SC_HANDLE SvcHandle = 0;
@ -261,6 +272,8 @@ static NTSTATUS FspFsctlStartService(VOID)
DWORD LastError; DWORD LastError;
NTSTATUS Result; NTSTATUS Result;
AcquireSRWLockExclusive(&Lock);
/* Determine if we are running inside container. /* Determine if we are running inside container.
* *
* See https://github.com/microsoft/perfview/blob/V1.9.65/src/TraceEvent/TraceEventSession.cs#L525 * See https://github.com/microsoft/perfview/blob/V1.9.65/src/TraceEvent/TraceEventSession.cs#L525
@ -331,6 +344,8 @@ exit:
if (0 != ScmHandle) if (0 != ScmHandle)
CloseServiceHandle(ScmHandle); CloseServiceHandle(ScmHandle);
ReleaseSRWLockExclusive(&Lock);
return Result; return Result;
} }

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fsop.c * @file dll/fsop.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -56,7 +56,10 @@ FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
(FspFsctlTransactCleanupKind == Request->Kind && (FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) || Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) || (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ == (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactSetVolumeInformationKind == Request->Kind || FspFsctlTransactSetVolumeInformationKind == Request->Kind ||
(FspFsctlTransactFlushBuffersKind == Request->Kind && (FspFsctlTransactFlushBuffersKind == Request->Kind &&
0 == Request->Req.FlushBuffers.UserContext && 0 == Request->Req.FlushBuffers.UserContext &&
@ -67,7 +70,9 @@ FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
else else
if (FspFsctlTransactCreateKind == Request->Kind || if (FspFsctlTransactCreateKind == Request->Kind ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) || (13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ != (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactQueryDirectoryKind == Request->Kind || FspFsctlTransactQueryDirectoryKind == Request->Kind ||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind) FspFsctlTransactQueryVolumeInformationKind == Request->Kind)
{ {
@ -95,7 +100,10 @@ FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
(FspFsctlTransactCleanupKind == Request->Kind && (FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) || Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) || (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ == (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactSetVolumeInformationKind == Request->Kind || FspFsctlTransactSetVolumeInformationKind == Request->Kind ||
(FspFsctlTransactFlushBuffersKind == Request->Kind && (FspFsctlTransactFlushBuffersKind == Request->Kind &&
0 == Request->Req.FlushBuffers.UserContext && 0 == Request->Req.FlushBuffers.UserContext &&
@ -106,7 +114,9 @@ FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
else else
if (FspFsctlTransactCreateKind == Request->Kind || if (FspFsctlTransactCreateKind == Request->Kind ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) || (13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ != (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactQueryDirectoryKind == Request->Kind || FspFsctlTransactQueryDirectoryKind == Request->Kind ||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind) FspFsctlTransactQueryVolumeInformationKind == Request->Kind)
{ {
@ -373,7 +383,10 @@ NTSTATUS FspFileSystemRenameCheck(FSP_FILE_SYSTEM *FileSystem,
Request->Req.SetInformation.Info.Rename.NewFileName.Size; Request->Req.SetInformation.Info.Rename.NewFileName.Size;
CreateRequest->Kind = FspFsctlTransactCreateKind; CreateRequest->Kind = FspFsctlTransactCreateKind;
CreateRequest->Req.Create.CreateOptions = CreateRequest->Req.Create.CreateOptions =
FILE_DELETE_ON_CLOSE | /* force read-only check! */ (65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
0 != (0x40/*IGNORE_READONLY_ATTRIBUTE*/ & Request->Req.SetInformation.Info.RenameEx.Flags) ?
0 :
FILE_DELETE_ON_CLOSE) | /* force read-only check! */
FILE_OPEN_REPARSE_POINT; /* allow rename over reparse point */ FILE_OPEN_REPARSE_POINT; /* allow rename over reparse point */
CreateRequest->Req.Create.AccessToken = Request->Req.SetInformation.Info.Rename.AccessToken; CreateRequest->Req.Create.AccessToken = Request->Req.SetInformation.Info.Rename.AccessToken;
CreateRequest->Req.Create.UserMode = TRUE; CreateRequest->Req.Create.UserMode = TRUE;
@ -978,16 +991,37 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
ULONG CleanupFlags =
(0 != Request->Req.Cleanup.Delete ? FspCleanupDelete : 0) |
(0 != Request->Req.Cleanup.SetAllocationSize ? FspCleanupSetAllocationSize : 0) |
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0);
if (Request->Req.Cleanup.Delete && 0 != FileSystem->Interface->Delete)
{
NTSTATUS Result = FileSystem->Interface->Delete(FileSystem,
(PVOID)ValOfFileContext(Request->Req.Cleanup),
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
(ULONG)-1);
/*
* If Delete returns STATUS_NOT_IMPLEMENTED it means that it is unable
* to handle file deletion during the Cleanup phase. In this case we
* will handle file deletion in Cleanup with the FspCleanupDelete flag.
*
* This is necessary for file systems like the .NET layer where Delete
* may be implemented but unable to handle all file deletion cases.
*/
if (STATUS_NOT_IMPLEMENTED != Result)
CleanupFlags &= ~FspCleanupDelete;
}
if (0 != FileSystem->Interface->Cleanup) if (0 != FileSystem->Interface->Cleanup)
FileSystem->Interface->Cleanup(FileSystem, FileSystem->Interface->Cleanup(FileSystem,
(PVOID)ValOfFileContext(Request->Req.Cleanup), (PVOID)ValOfFileContext(Request->Req.Cleanup),
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0, 0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
(0 != Request->Req.Cleanup.Delete ? FspCleanupDelete : 0) | CleanupFlags);
(0 != Request->Req.Cleanup.SetAllocationSize ? FspCleanupSetAllocationSize : 0) |
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1134,7 +1168,9 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
&FileInfo); &FileInfo);
break; break;
case 13/*FileDispositionInformation*/: case 13/*FileDispositionInformation*/:
if (0 != FileSystem->Interface->GetFileInfo) case 64/*FileDispositionInformationEx*/:
if (0 == (0x10/*IGNORE_READONLY_ATTRIBUTE*/ & Request->Req.SetInformation.Info.DispositionEx.Flags) &&
0 != FileSystem->Interface->GetFileInfo)
{ {
Result = FileSystem->Interface->GetFileInfo(FileSystem, Result = FileSystem->Interface->GetFileInfo(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetInformation), &FileInfo); (PVOID)ValOfFileContext(Request->Req.SetInformation), &FileInfo);
@ -1144,7 +1180,17 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
break; break;
} }
} }
if (0 != FileSystem->Interface->SetDelete) if (0 != FileSystem->Interface->Delete)
{
Result = FileSystem->Interface->Delete(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetInformation),
(PWSTR)Request->Buffer,
Request->Req.SetInformation.Info.DispositionEx.Flags & 3/*DELETE|POSIX_SEMANTICS*/);
}
else if (0 != (2/*POSIX_SEMANTICS*/ & Request->Req.SetInformation.Info.DispositionEx.Flags))
/* only FSP_FILE_SYSTEM_INTERFACE::Delete can do POSIX semantics; return error if unimplemented */
Result = STATUS_INVALID_PARAMETER;
else if (0 != FileSystem->Interface->SetDelete)
{ {
Result = FileSystem->Interface->SetDelete(FileSystem, Result = FileSystem->Interface->SetDelete(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetInformation), (PVOID)ValOfFileContext(Request->Req.SetInformation),
@ -1162,6 +1208,7 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
} }
break; break;
case 10/*FileRenameInformation*/: case 10/*FileRenameInformation*/:
case 65/*FileRenameInformationEx*/:
if (0 != FileSystem->Interface->Rename) if (0 != FileSystem->Interface->Rename)
{ {
if (0 != Request->Req.SetInformation.Info.Rename.AccessToken) if (0 != Request->Req.SetInformation.Info.Rename.AccessToken)

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse.c * @file dll/fuse/fuse.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -20,6 +20,7 @@
*/ */
#include <dll/fuse/library.h> #include <dll/fuse/library.h>
#include <sddl.h>
struct fuse_chan struct fuse_chan
{ {
@ -95,6 +96,7 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1), FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1),
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0), FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0),
FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1), FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1),
FSP_FUSE_CORE_OPT("LegacyUnlinkRename=", set_LegacyUnlinkRename, 1),
FSP_FUSE_CORE_OPT("ThreadCount=%u", ThreadCount, 0), FSP_FUSE_CORE_OPT("ThreadCount=%u", ThreadCount, 0),
FUSE_OPT_KEY("UNC=", 'U'), FUSE_OPT_KEY("UNC=", 'U'),
FUSE_OPT_KEY("--UNC=", 'U'), FUSE_OPT_KEY("--UNC=", 'U'),
@ -105,6 +107,8 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FUSE_OPT_KEY("ExactFileSystemName=", 'E'), FUSE_OPT_KEY("ExactFileSystemName=", 'E'),
FUSE_OPT_KEY("--ExactFileSystemName=", 'E'), FUSE_OPT_KEY("--ExactFileSystemName=", 'E'),
FUSE_OPT_KEY("FileSecurity=", 's'),
FUSE_OPT_KEY("--FileSecurity=", 's'),
FSP_FUSE_CORE_OPT("UserName=", set_uid, 1), FSP_FUSE_CORE_OPT("UserName=", set_uid, 1),
FUSE_OPT_KEY("UserName=", 'u'), FUSE_OPT_KEY("UserName=", 'u'),
FSP_FUSE_CORE_OPT("--UserName=", set_uid, 1), FSP_FUSE_CORE_OPT("--UserName=", set_uid, 1),
@ -266,6 +270,29 @@ 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_sddl_to_security(const char *Sddl, PUINT8 Security, PULONG PSecuritySize)
{
PSECURITY_DESCRIPTOR SecurityDescriptor;
ULONG SecurityDescriptorSize;
int res = -1;
if (ConvertStringSecurityDescriptorToSecurityDescriptorA(
Sddl, SDDL_REVISION_1, &SecurityDescriptor, &SecurityDescriptorSize))
{
if (*PSecuritySize >= SecurityDescriptorSize)
{
memcpy(Security, SecurityDescriptor, SecurityDescriptorSize);
*PSecuritySize = SecurityDescriptorSize;
res = 0;
}
LocalFree(SecurityDescriptor);
}
return res;
}
static int fsp_fuse_username_to_uid(const char *username, int *puid) static int fsp_fuse_username_to_uid(const char *username, int *puid)
{ {
union union
@ -303,6 +330,63 @@ static int fsp_fuse_username_to_uid(const char *username, int *puid)
return 0; return 0;
} }
static int fsp_fuse_utf8towcs_trunc(
const char *Str, int StrLen,
PWSTR Wcs, int WcsLen)
{
if (0 == StrLen)
return 0;
int Size = MultiByteToWideChar(CP_UTF8, 0, Str, StrLen, Wcs, WcsLen);
if (0 != Size)
return Size;
if (0 == WcsLen)
return 0;
PWSTR Buf = 0;
Size = MultiByteToWideChar(CP_UTF8, 0, Str, StrLen, 0, 0);
if (0 == Size)
goto exit;
Buf = MemAlloc(Size * sizeof(WCHAR));
if (0 == Buf)
{
SetLastError(ERROR_NO_SYSTEM_RESOURCES);
Size = 0;
goto exit;
}
Size = MultiByteToWideChar(CP_UTF8, 0, Str, StrLen, Buf, Size);
if (0 == Size)
goto exit;
if (-1 == StrLen)
{
if (Size >= WcsLen)
{
Size = WcsLen - 1;
memcpy(Wcs, Buf, Size * sizeof(WCHAR));
Wcs[Size] = L'\0';
Size++;
}
else
memcpy(Wcs, Buf, Size * sizeof(WCHAR));
}
else
{
if (Size >= WcsLen)
Size = WcsLen;
memcpy(Wcs, Buf, Size * sizeof(WCHAR));
}
exit:
MemFree(Buf);
return Size;
}
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)
{ {
@ -317,6 +401,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
FspServiceLog(EVENTLOG_ERROR_TYPE, L"" FspServiceLog(EVENTLOG_ERROR_TYPE, L""
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 FileSecurity=SDDL set file DACL (SDDL format)\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_file_umask=MASK for files only\n"
" -o create_dir_umask=MASK for directories only\n" " -o create_dir_umask=MASK for directories only\n"
@ -337,6 +422,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
" -o EaTimeout=N extended attribute timeout (millis)\n" " -o EaTimeout=N extended attribute timeout (millis)\n"
" -o VolumeInfoTimeout=N volume info timeout (millis)\n" " -o VolumeInfoTimeout=N volume info timeout (millis)\n"
" -o KeepFileCache do not discard cache when files are closed\n" " -o KeepFileCache do not discard cache when files are closed\n"
" -o LegacyUnlinkRename do not support new POSIX unlink/rename\n"
" -o ThreadCount number of file system dispatcher threads\n" " -o ThreadCount number of file system dispatcher threads\n"
); );
opt_data->help = 1; opt_data->help = 1;
@ -367,7 +453,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
arg += sizeof "VolumePrefix=" - 1; arg += sizeof "VolumePrefix=" - 1;
else if ('V' == arg[2]) else if ('V' == arg[2])
arg += sizeof "--VolumePrefix=" - 1; arg += sizeof "--VolumePrefix=" - 1;
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1, if (0 == fsp_fuse_utf8towcs_trunc(arg, -1,
opt_data->VolumeParams.Prefix, sizeof opt_data->VolumeParams.Prefix / sizeof(WCHAR))) opt_data->VolumeParams.Prefix, sizeof opt_data->VolumeParams.Prefix / sizeof(WCHAR)))
return -1; return -1;
opt_data->VolumeParams.Prefix opt_data->VolumeParams.Prefix
@ -383,7 +469,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
arg += sizeof "FileSystemName=" - 1; arg += sizeof "FileSystemName=" - 1;
else if ('F' == arg[2]) else if ('F' == arg[2])
arg += sizeof "--FileSystemName=" - 1; arg += sizeof "--FileSystemName=" - 1;
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1, if (0 == fsp_fuse_utf8towcs_trunc(arg, -1,
opt_data->VolumeParams.FileSystemName + 5, opt_data->VolumeParams.FileSystemName + 5,
sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 5)) sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 5))
return -1; return -1;
@ -396,13 +482,25 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
arg += sizeof "ExactFileSystemName=" - 1; arg += sizeof "ExactFileSystemName=" - 1;
else if ('E' == arg[2]) else if ('E' == arg[2])
arg += sizeof "--ExactFileSystemName=" - 1; arg += sizeof "--ExactFileSystemName=" - 1;
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1, if (0 == fsp_fuse_utf8towcs_trunc(arg, -1,
opt_data->VolumeParams.FileSystemName, opt_data->VolumeParams.FileSystemName,
sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR))) sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR)))
return -1; return -1;
opt_data->VolumeParams.FileSystemName opt_data->VolumeParams.FileSystemName
[sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0'; [sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0';
return 0; return 0;
case 's':
if ('F' == arg[0])
arg += sizeof "FileSecurity=" - 1;
else if ('F' == arg[2])
arg += sizeof "--FileSecurity=" - 1;
opt_data->FileSecuritySize = sizeof opt_data->FileSecurityBuf;
if (-1 == fsp_fuse_sddl_to_security(arg, opt_data->FileSecurityBuf, &opt_data->FileSecuritySize))
{
opt_data->FileSecuritySize = (ULONG)-1;
return -1;
}
return 0;
case 'u': case 'u':
if ('U' == arg[0]) if ('U' == arg[0])
arg += sizeof "UserName=" - 1; arg += sizeof "UserName=" - 1;
@ -428,7 +526,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
case 'v': case 'v':
arg += sizeof "volname=" - 1; arg += sizeof "volname=" - 1;
opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) * opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) *
MultiByteToWideChar(CP_UTF8, 0, arg, lstrlenA(arg), fsp_fuse_utf8towcs_trunc(arg, lstrlenA(arg),
opt_data->VolumeLabel, sizeof opt_data->VolumeLabel / sizeof(WCHAR))); opt_data->VolumeLabel, sizeof opt_data->VolumeLabel / sizeof(WCHAR)));
if (0 == opt_data->VolumeLabelLength) if (0 == opt_data->VolumeLabelLength)
return -1; return -1;
@ -467,10 +565,16 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.Version = sizeof(FSP_FSCTL_VOLUME_PARAMS); opt_data.VolumeParams.Version = sizeof(FSP_FSCTL_VOLUME_PARAMS);
opt_data.VolumeParams.FileInfoTimeout = 1000; opt_data.VolumeParams.FileInfoTimeout = 1000;
opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE; opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE;
opt_data.VolumeParams.SupportsPosixUnlinkRename = 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) if ((ULONG)-1 == opt_data.FileSecuritySize)
{
ErrorMessage = L": invalid file security.";
goto fail;
}
else if (-1 == opt_data.username_to_uid_result)
{ {
ErrorMessage = L": invalid user or group name."; ErrorMessage = L": invalid user or group name.";
goto fail; goto fail;
@ -522,6 +626,8 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.VolumeInfoTimeoutValid = 1; opt_data.VolumeParams.VolumeInfoTimeoutValid = 1;
if (opt_data.set_KeepFileCache) if (opt_data.set_KeepFileCache)
opt_data.VolumeParams.FlushAndPurgeOnCleanup = FALSE; opt_data.VolumeParams.FlushAndPurgeOnCleanup = FALSE;
if (opt_data.set_LegacyUnlinkRename)
opt_data.VolumeParams.SupportsPosixUnlinkRename = FALSE;
opt_data.VolumeParams.CaseSensitiveSearch = TRUE; opt_data.VolumeParams.CaseSensitiveSearch = TRUE;
opt_data.VolumeParams.CasePreservedNames = TRUE; opt_data.VolumeParams.CasePreservedNames = TRUE;
opt_data.VolumeParams.PersistentAcls = TRUE; opt_data.VolumeParams.PersistentAcls = TRUE;
@ -539,7 +645,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
if (L'\0' == opt_data.VolumeParams.FileSystemName[0]) if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR)); memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
f = fsp_fuse_obj_alloc(env, sizeof *f); f = fsp_fuse_obj_alloc(env, sizeof *f + opt_data.FileSecuritySize);
if (0 == f) if (0 == f)
goto fail; goto fail;
@ -559,6 +665,11 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
memcpy(&f->VolumeParams, &opt_data.VolumeParams, sizeof opt_data.VolumeParams); memcpy(&f->VolumeParams, &opt_data.VolumeParams, sizeof opt_data.VolumeParams);
f->VolumeLabelLength = opt_data.VolumeLabelLength; f->VolumeLabelLength = opt_data.VolumeLabelLength;
memcpy(&f->VolumeLabel, &opt_data.VolumeLabel, opt_data.VolumeLabelLength); memcpy(&f->VolumeLabel, &opt_data.VolumeLabel, opt_data.VolumeLabelLength);
if (0 != opt_data.FileSecuritySize)
{
memcpy(f->FileSecurityBuf, opt_data.FileSecurityBuf, opt_data.FileSecuritySize);
f->FileSecurity = f->FileSecurityBuf;
}
Size = (lstrlenW(ch->MountPoint) + 1) * sizeof(WCHAR); Size = (lstrlenW(ch->MountPoint) + 1) * sizeof(WCHAR);
f->MountPoint = fsp_fuse_obj_alloc(env, Size); f->MountPoint = fsp_fuse_obj_alloc(env, Size);

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_compat.c * @file dll/fuse/fuse_compat.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -34,7 +34,10 @@ VOID fsp_fuse_op_enter_lock(FSP_FILE_SYSTEM *FileSystem,
(FspFsctlTransactCleanupKind == Request->Kind && (FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) || Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) || (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ == (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactSetVolumeInformationKind == Request->Kind || FspFsctlTransactSetVolumeInformationKind == Request->Kind ||
(FspFsctlTransactFlushBuffersKind == Request->Kind && (FspFsctlTransactFlushBuffersKind == Request->Kind &&
0 == Request->Req.FlushBuffers.UserContext && 0 == Request->Req.FlushBuffers.UserContext &&
@ -48,7 +51,9 @@ VOID fsp_fuse_op_enter_lock(FSP_FILE_SYSTEM *FileSystem,
else else
if (FspFsctlTransactCreateKind == Request->Kind || if (FspFsctlTransactCreateKind == Request->Kind ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) || (13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ != (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactQueryDirectoryKind == Request->Kind || FspFsctlTransactQueryDirectoryKind == Request->Kind ||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind || FspFsctlTransactQueryVolumeInformationKind == Request->Kind ||
/* FSCTL_GET_REPARSE_POINT may access namespace */ /* FSCTL_GET_REPARSE_POINT may access namespace */
@ -78,7 +83,10 @@ VOID fsp_fuse_op_leave_unlock(FSP_FILE_SYSTEM *FileSystem,
(FspFsctlTransactCleanupKind == Request->Kind && (FspFsctlTransactCleanupKind == Request->Kind &&
Request->Req.Cleanup.Delete) || Request->Req.Cleanup.Delete) ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) || (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ == (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactSetVolumeInformationKind == Request->Kind || FspFsctlTransactSetVolumeInformationKind == Request->Kind ||
(FspFsctlTransactFlushBuffersKind == Request->Kind && (FspFsctlTransactFlushBuffersKind == Request->Kind &&
0 == Request->Req.FlushBuffers.UserContext && 0 == Request->Req.FlushBuffers.UserContext &&
@ -92,7 +100,9 @@ VOID fsp_fuse_op_leave_unlock(FSP_FILE_SYSTEM *FileSystem,
else else
if (FspFsctlTransactCreateKind == Request->Kind || if (FspFsctlTransactCreateKind == Request->Kind ||
(FspFsctlTransactSetInformationKind == Request->Kind && (FspFsctlTransactSetInformationKind == Request->Kind &&
13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass) || (13/*FileDispositionInformation*/ == Request->Req.SetInformation.FileInformationClass ||
(64/*FileDispositionInformationEx*/ == Request->Req.SetInformation.FileInformationClass &&
3/*DELETE|POSIX_SEMANTICS*/ != (3 & Request->Req.SetInformation.Info.DispositionEx.Flags)))) ||
FspFsctlTransactQueryDirectoryKind == Request->Kind || FspFsctlTransactQueryDirectoryKind == Request->Kind ||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind || FspFsctlTransactQueryVolumeInformationKind == Request->Kind ||
/* FSCTL_GET_REPARSE_POINT may access namespace */ /* FSCTL_GET_REPARSE_POINT may access namespace */
@ -131,7 +141,8 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
AccessToken = Request->Req.Create.AccessToken; AccessToken = Request->Req.Create.AccessToken;
} }
else if (FspFsctlTransactSetInformationKind == Request->Kind && else if (FspFsctlTransactSetInformationKind == Request->Kind &&
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass) (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass ||
65/*FileRenameInformationEx*/ == Request->Req.SetInformation.FileInformationClass))
{ {
FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset); FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset);
AccessToken = Request->Req.SetInformation.Info.Rename.AccessToken; AccessToken = Request->Req.SetInformation.Info.Rename.AccessToken;
@ -472,7 +483,8 @@ static NTSTATUS fsp_fuse_intf_GetSecurityEx(FSP_FILE_SYSTEM *FileSystem,
if (0 != PSecurityDescriptorSize) if (0 != PSecurityDescriptorSize)
{ {
Result = FspPosixMapPermissionsToSecurityDescriptor(Uid, Gid, Mode, &SecurityDescriptor); Result = FspPosixMergePermissionsToSecurityDescriptor(Uid, Gid, Mode, f->FileSecurity,
&SecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -498,7 +510,7 @@ static NTSTATUS fsp_fuse_intf_GetSecurityEx(FSP_FILE_SYSTEM *FileSystem,
exit: exit:
if (0 != SecurityDescriptor) if (0 != SecurityDescriptor)
FspDeleteSecurityDescriptor(SecurityDescriptor, FspDeleteSecurityDescriptor(SecurityDescriptor,
FspPosixMapPermissionsToSecurityDescriptor); FspPosixMergePermissionsToSecurityDescriptor);
return Result; return Result;
} }
@ -950,12 +962,12 @@ exit:
if (CreateOptions & FILE_DIRECTORY_FILE) if (CreateOptions & FILE_DIRECTORY_FILE)
{ {
if (0 != f->ops.releasedir) if (0 != f->ops.releasedir)
f->ops.releasedir(filedesc->PosixPath, &fi); f->ops.releasedir(contexthdr->PosixPath, &fi);
} }
else else
{ {
if (0 != f->ops.release) if (0 != f->ops.release)
f->ops.release(filedesc->PosixPath, &fi); f->ops.release(contexthdr->PosixPath, &fi);
} }
} }
@ -979,6 +991,19 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
int err; int err;
NTSTATUS Result; NTSTATUS Result;
if (0 != (CreateOptions & FILE_DELETE_ON_CLOSE) &&
0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
{
err = f->ops.access(contexthdr->PosixPath, FSP_FUSE_DELETE_OK);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
{
if (STATUS_ACCESS_DENIED == Result)
Result = STATUS_CANNOT_DELETE;
goto exit;
}
}
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, 0, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, 0,
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -1156,42 +1181,6 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, PWSTR FileName, ULONG Flags)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
/*
* In Windows a DeleteFile/RemoveDirectory is the sequence of the following:
* Create(FILE_OPEN)
* SetInformation(Disposition)
* Cleanup
* Close
*
* The FSD maintains a count of how many handles are currently open for a file. When the
* last handle is closed *and* the disposition flag is set the FSD sends us a Cleanup with
* the Delete flag set.
*
* Notice that when we receive a Cleanup with Delete set there can be no open handles other
* than ours. [Even if there is a concurrent Open of this file, the FSD will fail it with
* STATUS_DELETE_PENDING.] This means that we do not need to worry about the hard_remove
* FUSE option and can safely remove the file at this time.
*/
if (Flags & FspCleanupDelete)
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
{
if (0 != f->ops.rmdir)
f->ops.rmdir(filedesc->PosixPath);
}
else
{
if (0 != f->ops.unlink)
f->ops.unlink(filedesc->PosixPath);
}
}
static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem, static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc) PVOID FileDesc)
{ {
@ -1604,6 +1593,72 @@ static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS fsp_fuse_intf_Delete(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, PWSTR FileName, ULONG Flags)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
int err;
NTSTATUS Result;
switch (Flags)
{
case FILE_DISPOSITION_DO_NOT_DELETE:
return STATUS_SUCCESS;
case FILE_DISPOSITION_DELETE:
Result = STATUS_SUCCESS;
if (0 != (f->conn_want & FSP_FUSE_CAP_DELETE_ACCESS) && 0 != f->ops.access)
{
err = f->ops.access(filedesc->PosixPath, FSP_FUSE_DELETE_OK);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
if (STATUS_INVALID_DEVICE_REQUEST == Result)
Result = STATUS_SUCCESS;
}
if (NT_SUCCESS(Result))
Result = fsp_fuse_intf_CanDelete(FileSystem, FileDesc, FileName);
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
if (STATUS_ACCESS_DENIED == Result)
Result = STATUS_CANNOT_DELETE;
return Result;
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
case -1:
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
{
if (0 != f->ops.rmdir)
{
err = f->ops.rmdir(filedesc->PosixPath);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
}
else
Result = STATUS_INVALID_DEVICE_REQUEST;
}
else
{
if (0 != f->ops.unlink)
{
err = f->ops.unlink(filedesc->PosixPath);
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
}
else
Result = STATUS_INVALID_DEVICE_REQUEST;
}
/* when doing unlink/rmdir convert EPERM/EACCES to STATUS_CANNOT_DELETE */
if (STATUS_ACCESS_DENIED == Result)
Result = STATUS_CANNOT_DELETE;
return Result;
default:
return STATUS_INVALID_PARAMETER;
}
}
static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, PVOID FileDesc,
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists)
@ -1682,7 +1737,8 @@ static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
Result = FspPosixMapPermissionsToSecurityDescriptor(Uid, Gid, Mode, &SecurityDescriptor); Result = FspPosixMergePermissionsToSecurityDescriptor(Uid, Gid, Mode, f->FileSecurity,
&SecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1729,7 +1785,7 @@ exit:
if (0 != SecurityDescriptor) if (0 != SecurityDescriptor)
FspDeleteSecurityDescriptor(SecurityDescriptor, FspDeleteSecurityDescriptor(SecurityDescriptor,
FspPosixMapPermissionsToSecurityDescriptor); FspPosixMergePermissionsToSecurityDescriptor);
return Result; return Result;
} }
@ -2422,7 +2478,7 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
0, 0,
fsp_fuse_intf_Open, fsp_fuse_intf_Open,
0, 0,
fsp_fuse_intf_Cleanup, 0,
fsp_fuse_intf_Close, fsp_fuse_intf_Close,
fsp_fuse_intf_Read, fsp_fuse_intf_Read,
fsp_fuse_intf_Write, fsp_fuse_intf_Write,
@ -2430,7 +2486,7 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
fsp_fuse_intf_GetFileInfo, fsp_fuse_intf_GetFileInfo,
fsp_fuse_intf_SetBasicInfo, fsp_fuse_intf_SetBasicInfo,
fsp_fuse_intf_SetFileSize, fsp_fuse_intf_SetFileSize,
fsp_fuse_intf_CanDelete, 0,
fsp_fuse_intf_Rename, fsp_fuse_intf_Rename,
fsp_fuse_intf_GetSecurity, fsp_fuse_intf_GetSecurity,
fsp_fuse_intf_SetSecurity, fsp_fuse_intf_SetSecurity,
@ -2447,6 +2503,7 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
fsp_fuse_intf_Overwrite, fsp_fuse_intf_Overwrite,
fsp_fuse_intf_GetEa, fsp_fuse_intf_GetEa,
fsp_fuse_intf_SetEa, fsp_fuse_intf_SetEa,
fsp_fuse_intf_Delete,
}; };
/* /*

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_loop.c * @file dll/fuse/fuse_loop.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -88,6 +88,7 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f)
FSP_FUSE_CAP_READDIR_PLUS | FSP_FUSE_CAP_READDIR_PLUS |
FSP_FUSE_CAP_READ_ONLY | FSP_FUSE_CAP_READ_ONLY |
FSP_FUSE_CAP_STAT_EX | FSP_FUSE_CAP_STAT_EX |
FSP_FUSE_CAP_DELETE_ACCESS |
FSP_FUSE_CAP_CASE_INSENSITIVE; FSP_FUSE_CAP_CASE_INSENSITIVE;
if (0 != f->ops.init) if (0 != f->ops.init)
{ {

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_main.c * @file dll/fuse/fuse_main.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/library.h * @file dll/fuse/library.h
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -72,6 +72,8 @@ struct fuse
FSP_FILE_SYSTEM *FileSystem; FSP_FILE_SYSTEM *FileSystem;
volatile int exited; volatile int exited;
struct fuse3 *fuse3; struct fuse3 *fuse3;
PSECURITY_DESCRIPTOR FileSecurity;
FSP_FSCTL_DECLSPEC_ALIGN UINT8 FileSecurityBuf[];
}; };
struct fsp_fuse_context_header struct fsp_fuse_context_header
{ {
@ -151,11 +153,14 @@ struct fsp_fuse_core_opt_data
set_DirInfoTimeout, set_DirInfoTimeout,
set_EaTimeout, set_EaTimeout,
set_VolumeInfoTimeout, set_VolumeInfoTimeout,
set_KeepFileCache; set_KeepFileCache,
set_LegacyUnlinkRename;
unsigned ThreadCount; unsigned ThreadCount;
FSP_FSCTL_VOLUME_PARAMS VolumeParams; FSP_FSCTL_VOLUME_PARAMS VolumeParams;
UINT16 VolumeLabelLength; UINT16 VolumeLabelLength;
WCHAR VolumeLabel[sizeof ((FSP_FSCTL_VOLUME_INFO *)0)->VolumeLabel / sizeof(WCHAR)]; WCHAR VolumeLabel[sizeof ((FSP_FSCTL_VOLUME_INFO *)0)->VolumeLabel / sizeof(WCHAR)];
ULONG FileSecuritySize;
FSP_FSCTL_DECLSPEC_ALIGN UINT8 FileSecurityBuf[1024];
}; };
FSP_FSCTL_STATIC_ASSERT( FSP_FSCTL_STATIC_ASSERT(
sizeof ((struct fuse *)0)->VolumeLabel == sizeof ((struct fsp_fuse_core_opt_data *)0)->VolumeLabel, sizeof ((struct fuse *)0)->VolumeLabel == sizeof ((struct fsp_fuse_core_opt_data *)0)->VolumeLabel,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse3/fuse2to3.c * @file dll/fuse3/fuse2to3.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/ldap.c * @file dll/ldap.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -30,7 +30,7 @@
#include <shared/ku/config.h> #include <shared/ku/config.h>
#define LIBRARY_NAME "WinFsp" #define LIBRARY_NAME FSP_FSCTL_PRODUCT_NAME
/* DEBUGLOG */ /* DEBUGLOG */
#if !defined(NDEBUG) #if !defined(NDEBUG)

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/mount.c * @file dll/mount.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -28,6 +28,29 @@ static NTSTATUS (NTAPI *FspNtMakeTemporaryObject)(
HANDLE Handle); HANDLE Handle);
static NTSTATUS (NTAPI *FspNtClose)( static NTSTATUS (NTAPI *FspNtClose)(
HANDLE Handle); HANDLE Handle);
static BOOLEAN FspMountDoNotUseLauncher;
static VOID FspMountInitializeFromRegistry(VOID)
{
HKEY RegKey;
LONG Result;
DWORD Size;
DWORD MountDoNotUseLauncher;
MountDoNotUseLauncher = 0;
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\" FSP_FSCTL_PRODUCT_NAME,
0, KEY_READ | KEY_WOW64_32KEY, &RegKey);
if (ERROR_SUCCESS == Result)
{
Size = sizeof MountDoNotUseLauncher;
Result = RegGetValueW(RegKey, 0, L"MountDoNotUseLauncher",
RRF_RT_REG_DWORD, 0, &MountDoNotUseLauncher, &Size);
RegCloseKey(RegKey);
}
FspMountDoNotUseLauncher = !!MountDoNotUseLauncher;
}
static BOOL WINAPI FspMountInitialize( static BOOL WINAPI FspMountInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
@ -49,6 +72,8 @@ static BOOL WINAPI FspMountInitialize(
} }
} }
FspMountInitializeFromRegistry();
return TRUE; return TRUE;
} }
@ -366,7 +391,7 @@ static NTSTATUS FspMountSet_Drive(PWSTR VolumeName, PWSTR MountPoint, PHANDLE PM
Result = FspServiceContextCheck(0, &IsLocalSystem); Result = FspServiceContextCheck(0, &IsLocalSystem);
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem; IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
if (IsServiceContext) if (IsServiceContext && !FspMountDoNotUseLauncher)
{ {
/* /*
* If the current process is in the service context but not LocalSystem, * If the current process is in the service context but not LocalSystem,

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/np.c * @file dll/np.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -742,7 +742,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
DWORD AuthPackage, CredentialsKind; DWORD AuthPackage, CredentialsKind;
WCHAR UserName[CREDUI_MAX_USERNAME_LENGTH + 1], Password[CREDUI_MAX_PASSWORD_LENGTH + 1]; WCHAR UserName[CREDUI_MAX_USERNAME_LENGTH + 1], Password[CREDUI_MAX_PASSWORD_LENGTH + 1];
#if defined(FSP_NP_CREDENTIAL_MANAGER) #if defined(FSP_NP_CREDENTIAL_MANAGER)
BOOL Save = TRUE; BOOL Save = FALSE;
#endif #endif
//dwFlags |= CONNECT_INTERACTIVE | CONNECT_PROMPT; /* TESTING ONLY! */ //dwFlags |= CONNECT_INTERACTIVE | CONNECT_PROMPT; /* TESTING ONLY! */

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/ntstatus.c * @file dll/ntstatus.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -488,7 +488,8 @@ FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor
return; return;
if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc || if ((NTSTATUS (*)())FspAccessCheckEx == CreateFunc ||
(NTSTATUS (*)())FspPosixMapPermissionsToSecurityDescriptor == CreateFunc) (NTSTATUS (*)())FspPosixMapPermissionsToSecurityDescriptor == CreateFunc ||
(NTSTATUS (*)())FspPosixMergePermissionsToSecurityDescriptor == CreateFunc)
MemFree(SecurityDescriptor); MemFree(SecurityDescriptor);
else else
if ((NTSTATUS (*)())FspCreateSecurityDescriptor == CreateFunc || if ((NTSTATUS (*)())FspCreateSecurityDescriptor == CreateFunc ||

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/service.c * @file dll/service.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -23,9 +23,9 @@ BEGIN
VALUE "CompanyName", STR(MyCompanyName) VALUE "CompanyName", STR(MyCompanyName)
VALUE "FileDescription", STR(MyDescription) VALUE "FileDescription", STR(MyDescription)
VALUE "FileVersion", STR(MyFullVersion) VALUE "FileVersion", STR(MyFullVersion)
VALUE "InternalName", "winfsp.dll" VALUE "InternalName", STR(MyProductFileName) ".dll"
VALUE "LegalCopyright", STR(MyCopyright) VALUE "LegalCopyright", STR(MyCopyright)
VALUE "OriginalFilename", "winfsp.dll" VALUE "OriginalFilename", STR(MyProductFileName) ".dll"
VALUE "ProductName", STR(MyProductName) VALUE "ProductName", STR(MyProductName)
VALUE "ProductVersion", STR(MyProductVersion) VALUE "ProductVersion", STR(MyProductVersion)
END END

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/wksid.c * @file dll/wksid.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * Copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -57,6 +57,14 @@ namespace Fsp
public const UInt32 CleanupSetLastWriteTime = 0x40; public const UInt32 CleanupSetLastWriteTime = 0x40;
public const UInt32 CleanupSetChangeTime = 0x80; public const UInt32 CleanupSetChangeTime = 0x80;
/* Disposition */
public const UInt32 FILE_DISPOSITION_DO_NOT_DELETE = 0x00000000;
public const UInt32 FILE_DISPOSITION_DELETE = 0x00000001;
public const UInt32 FILE_DISPOSITION_POSIX_SEMANTICS = 0x00000002;
public const UInt32 FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x00000004;
public const UInt32 FILE_DISPOSITION_ON_CLOSE = 0x00000008;
public const UInt32 FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE = 0x00000010;
/* NTSTATUS */ /* NTSTATUS */
public const Int32 STATUS_SUCCESS = unchecked((Int32)0x00000000); public const Int32 STATUS_SUCCESS = unchecked((Int32)0x00000000);
public const Int32 STATUS_WAIT_1 = unchecked((Int32)0x00000001); public const Int32 STATUS_WAIT_1 = unchecked((Int32)0x00000001);

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemBase.cs * dotnet/FileSystemBase.cs
* *
* Copyright 2015-2020 Bill Zissimopoulos * Copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -289,6 +289,9 @@ namespace Fsp
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// (NOTE: use of this function with the CleanupDelete flag is not recommended;
/// use Delete instead.)
/// </para><para>
/// When CreateFile is used to open or create a file the kernel creates a kernel mode file /// When CreateFile is used to open or create a file the kernel creates a kernel mode file
/// object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may /// object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may
/// be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same /// be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same
@ -342,6 +345,7 @@ namespace Fsp
/// </param> /// </param>
/// <seealso cref="CanDelete"/> /// <seealso cref="CanDelete"/>
/// <seealso cref="SetDelete"/> /// <seealso cref="SetDelete"/>
/// <seealso cref="Delete"/>
/// <seealso cref="Close"/> /// <seealso cref="Close"/>
public virtual void Cleanup( public virtual void Cleanup(
Object FileNode, Object FileNode,
@ -598,12 +602,14 @@ namespace Fsp
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// (NOTE: use of this function is not recommended; use Delete instead.)
/// </para><para>
/// This function tests whether a file or directory can be safely deleted. This function does /// This function tests whether a file or directory can be safely deleted. This function does
/// not need to perform access checks, but may performs tasks such as check for empty /// not need to perform access checks, but may performs tasks such as check for empty
/// directories, etc. /// directories, etc.
/// </para><para> /// </para><para>
/// This function should <b>NEVER</b> delete the file or directory in question. Deletion should /// This function should <b>NEVER</b> delete the file or directory in question. Deletion should
/// happen during Cleanup with the FspCleanupDelete flag set. /// happen during Cleanup with the CleanupDelete flag set.
/// </para><para> /// </para><para>
/// This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. /// This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
/// It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. /// It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE.
@ -624,6 +630,7 @@ namespace Fsp
/// <returns>STATUS_SUCCESS or error code.</returns> /// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="Cleanup"/> /// <seealso cref="Cleanup"/>
/// <seealso cref="SetDelete"/> /// <seealso cref="SetDelete"/>
/// <seealso cref="Delete"/>
public virtual Int32 CanDelete( public virtual Int32 CanDelete(
Object FileNode, Object FileNode,
Object FileDesc, Object FileDesc,
@ -1036,12 +1043,14 @@ namespace Fsp
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// (NOTE: use of this function is not recommended; use Delete instead.)
/// </para><para>
/// This function sets a flag to indicates whether the FSD file should delete a file /// This function sets a flag to indicates whether the FSD file should delete a file
/// when it is closed. This function does not need to perform access checks, but may /// when it is closed. This function does not need to perform access checks, but may
/// performs tasks such as check for empty directories, etc. /// performs tasks such as check for empty directories, etc.
/// </para><para> /// </para><para>
/// This function should <b>NEVER</b> delete the file or directory in question. Deletion should /// This function should <b>NEVER</b> delete the file or directory in question. Deletion should
/// happen during Cleanup with the FspCleanupDelete flag set. /// happen during Cleanup with the CleanupDelete flag set.
/// </para><para> /// </para><para>
/// This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used. /// This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
/// It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE. /// It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE.
@ -1067,6 +1076,7 @@ namespace Fsp
/// <returns>STATUS_SUCCESS or error code.</returns> /// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="Cleanup"/> /// <seealso cref="Cleanup"/>
/// <seealso cref="CanDelete"/> /// <seealso cref="CanDelete"/>
/// <seealso cref="Delete"/>
public virtual Int32 SetDelete( public virtual Int32 SetDelete(
Object FileNode, Object FileNode,
Object FileDesc, Object FileDesc,
@ -1188,6 +1198,85 @@ namespace Fsp
{ {
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
/// <summary>
/// Sets the file delete flag or deletes a file or directory.
/// </summary>
/// <remarks>
/// <para>
/// This function replaces CanDelete, SetDelete and uses of Cleanup with the CleanupDelete flag
/// and is recommended for use in all new code.
/// </para><para>
/// Due to the complexity of file deletion in the Windows file system this function is used
/// in many scenarios. Its usage is controlled by the Flags parameter:
/// <list>
/// <item>FILE_DISPOSITION_DO_NOT_DELETE: Unmark the file for deletion.
/// Do <b>NOT</b> delete the file either now or at Cleanup time.</item>
/// <item>FILE_DISPOSITION_DELETE: Mark the file for deletion,
/// but do <b>NOT</b> delete the file. The file will be deleted at Cleanup time
/// (via a call to Delete with Flags = -1).
/// This function does not need to perform access checks, but may
/// performs tasks such as check for empty directories, etc.</item>
/// <item>FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS: Delete the file
/// <b>NOW</b> using POSIX semantics. Open user mode handles to the file remain valid.
/// This case will be received only when SupportsPosixUnlinkRename is set.</item>
/// <item>-1: Delete the file <b>NOW</b> using regular Windows semantics.
/// Called during Cleanup with no open user mode handles remaining.
/// If a file system implements Delete, Cleanup should <b>NOT</b> be used for deletion anymore.</item>
/// </list>
/// </para><para>
/// This function gets called in all file deletion scenarios:
/// <list>
/// <item>When the DeleteFile or RemoveDirectory API's are used.</item>
/// <item>When the SetInformationByHandle API with FileDispositionInfo or FileDispositionInfoEx is used.</item>
/// <item>When a file is opened using FILE_DELETE_ON_CLOSE.</item>
/// <item>Etc.</item>
/// </list>
/// </para><para>
/// NOTE: Delete takes precedence over CanDelete, SetDelete and Cleanup with the CleanupDelete flag.
/// This means that if Delete is defined, CanDelete and SetDelete will never be called and
/// Cleanup will never be called with the CleanupDelete flag.
/// </para>
/// </remarks>
/// <param name="FileNode">
/// The file node of the file or directory.
/// </param>
/// <param name="FileDesc">
/// The file descriptor of the file or directory.
/// </param>
/// <param name="FileName">
/// The name of the file or directory.
/// </param>
/// <param name="Flags">
/// File disposition flags.
/// </param>
/// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="Cleanup"/>
/// <seealso cref="CanDelete"/>
/// <seealso cref="SetDelete"/>
public virtual Int32 Delete(
Object FileNode,
Object FileDesc,
String FileName,
UInt32 Flags)
{
switch (Flags)
{
case FILE_DISPOSITION_DO_NOT_DELETE:
return SetDelete(FileNode, FileDesc, FileName, false);
case FILE_DISPOSITION_DELETE:
return SetDelete(FileNode, FileDesc, FileName, true);
case FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS:
return STATUS_INVALID_PARAMETER;
case ~(UInt32)0:
return STATUS_NOT_IMPLEMENTED;
default:
return STATUS_INVALID_PARAMETER;
}
}
/* helpers */ /* helpers */
/// <summary> /// <summary>

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemHost.cs * dotnet/FileSystemHost.cs
* *
* Copyright 2015-2020 Bill Zissimopoulos * Copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -312,6 +312,11 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.RejectIrpPriorToTransact0); } get { return 0 != (_VolumeParams.Flags & VolumeParams.RejectIrpPriorToTransact0); }
set { _VolumeParams.Flags |= (value ? VolumeParams.RejectIrpPriorToTransact0 : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.RejectIrpPriorToTransact0 : 0); }
} }
public Boolean SupportsPosixUnlinkRename
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.SupportsPosixUnlinkRename); }
set { _VolumeParams.Flags |= (value ? VolumeParams.SupportsPosixUnlinkRename : 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>
@ -342,7 +347,7 @@ namespace Fsp
public Int32 Preflight(String MountPoint) public Int32 Preflight(String MountPoint)
{ {
return Api.FspFileSystemPreflight( return Api.FspFileSystemPreflight(
_VolumeParams.IsPrefixEmpty() ? "WinFsp.Disk" : "WinFsp.Net", _VolumeParams.IsPrefixEmpty() ? Api.ProductName + ".Disk" : Api.ProductName + ".Net",
MountPoint); MountPoint);
} }
/// <summary> /// <summary>
@ -416,7 +421,7 @@ namespace Fsp
if (0 > Result) if (0 > Result)
return Result; return Result;
Result = Api.FspFileSystemCreate( Result = Api.FspFileSystemCreate(
_VolumeParams.IsPrefixEmpty() ? "WinFsp.Disk" : "WinFsp.Net", _VolumeParams.IsPrefixEmpty() ? Api.ProductName + ".Disk" : Api.ProductName + ".Net",
ref _VolumeParams, _FileSystemInterfacePtr, out _FileSystemPtr); ref _VolumeParams, _FileSystemInterfacePtr, out _FileSystemPtr);
if (0 > Result) if (0 > Result)
return Result; return Result;
@ -1343,28 +1348,6 @@ namespace Fsp
return ExceptionHandler(FileSystem, ex); return ExceptionHandler(FileSystem, ex);
} }
} }
private static Int32 SetDelete(
IntPtr FileSystemPtr,
ref FullContext FullContext,
String FileName,
Boolean DeleteFile)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.SetDelete(
FileNode,
FileDesc,
FileName,
DeleteFile);
}
catch (Exception ex)
{
return ExceptionHandler(FileSystem, ex);
}
}
private static Int32 GetEa( private static Int32 GetEa(
IntPtr FileSystemPtr, IntPtr FileSystemPtr,
ref FullContext FullContext, ref FullContext FullContext,
@ -1415,6 +1398,28 @@ namespace Fsp
return ExceptionHandler(FileSystem, ex); return ExceptionHandler(FileSystem, ex);
} }
} }
private static Int32 Delete(
IntPtr FileSystemPtr,
ref FullContext FullContext,
String FileName,
UInt32 Flags)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.Delete(
FileNode,
FileDesc,
FileName,
Flags);
}
catch (Exception ex)
{
return ExceptionHandler(FileSystem, ex);
}
}
static FileSystemHost() static FileSystemHost()
{ {
@ -1443,11 +1448,14 @@ namespace Fsp
_FileSystemInterface.GetStreamInfo = GetStreamInfo; _FileSystemInterface.GetStreamInfo = GetStreamInfo;
_FileSystemInterface.GetDirInfoByName = GetDirInfoByName; _FileSystemInterface.GetDirInfoByName = GetDirInfoByName;
_FileSystemInterface.Control = Control; _FileSystemInterface.Control = Control;
_FileSystemInterface.SetDelete = SetDelete;
_FileSystemInterface.GetEa = GetEa; _FileSystemInterface.GetEa = GetEa;
_FileSystemInterface.SetEa = SetEa; _FileSystemInterface.SetEa = SetEa;
_FileSystemInterface.Delete = Delete;
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size); _FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
/* Marshal.AllocHGlobal does not zero memory; we must do it ourselves! */
for (int Offset = 0; FileSystemInterface.Size > Offset; Offset += IntPtr.Size)
Marshal.WriteIntPtr(_FileSystemInterfacePtr, Offset, IntPtr.Zero);
Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false); Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false);
} }

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/Interop.cs * dotnet/Interop.cs
* *
* Copyright 2015-2020 Bill Zissimopoulos * Copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -55,6 +55,7 @@ namespace Fsp.Interop
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000; internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
internal const UInt32 WslFeatures = 0x04000000; internal const UInt32 WslFeatures = 0x04000000;
internal const UInt32 RejectIrpPriorToTransact0 = 0x10000000; internal const UInt32 RejectIrpPriorToTransact0 = 0x10000000;
internal const UInt32 SupportsPosixUnlinkRename = 0x20000000;
internal const int PrefixSize = 192; internal const int PrefixSize = 192;
internal const int FileSystemNameSize = 16; internal const int FileSystemNameSize = 16;
@ -315,7 +316,7 @@ namespace Fsp.Interop
{ {
internal const int FileNameBufSize = 1024 * 2/*FSP_FSCTL_TRANSACT_PATH_SIZEMAX*/; internal const int FileNameBufSize = 1024 * 2/*FSP_FSCTL_TRANSACT_PATH_SIZEMAX*/;
internal static int FileNameBufOffset = internal static int FileNameBufOffset =
(int)Marshal.OffsetOf(typeof(DirInfo), "FileNameBuf"); (int)Marshal.OffsetOf(typeof(NotifyInfoInternal), "FileNameBuf");
internal UInt16 Size; internal UInt16 Size;
internal UInt32 Filter; internal UInt32 Filter;
@ -337,6 +338,47 @@ namespace Fsp.Interop
} }
} }
/// <summary>
/// Enumeration of all the possible values for NotifyInfo.Action
/// </summary>
public enum NotifyAction : UInt32
{
Added = 1,
Removed = 2,
Modified = 3,
RenamedOldName = 4,
RenamedNewName = 5,
AddedStream = 6,
RemovedStream = 7,
ModifiedStream = 8,
RemovedByDelete = 9,
IdNotTunnelled = 10,
TunnelledIdCollision = 11,
}
/// <summary>
/// Enumeration of all the possible values for NotifyInfo.Filter
/// </summary>
[Flags]
public enum NotifyFilter : UInt32
{
None = 0x00000,
ChangeFileName = 0x00001,
ChangeDirName = 0x00002,
ChangeName = ChangeFileName | ChangeDirName,
ChangeAttributes = 0x00004,
ChangeSize = 0x00008,
ChangeLastWrite = 0x00010,
ChangeLastAccess = 0x00020,
ChangeCreation = 0x00040,
ChangeEa = 0x00080,
ChangeSecurity = 0x00100,
ChangeStreamName = 0x00200,
ChangeStreamSize = 0x00400,
ChangeStreamWrite = 0x00800,
}
/// <summary> /// <summary>
/// Contains file change notification information. /// Contains file change notification information.
/// </summary> /// </summary>
@ -344,8 +386,8 @@ namespace Fsp.Interop
public struct NotifyInfo public struct NotifyInfo
{ {
public String FileName; public String FileName;
public UInt32 Action; public NotifyAction Action;
public UInt32 Filter; public NotifyFilter Filter;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@ -700,6 +742,12 @@ namespace Fsp.Interop
IntPtr Ea, IntPtr Ea,
UInt32 EaLength, UInt32 EaLength,
out FileInfo FileInfo); out FileInfo FileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 Delete(
IntPtr FileSystem,
ref FullContext FullContext,
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
UInt32 Flags);
} }
internal static int Size = IntPtr.Size * 64; internal static int Size = IntPtr.Size * 64;
@ -735,7 +783,8 @@ namespace Fsp.Interop
internal Proto.OverwriteEx OverwriteEx; internal Proto.OverwriteEx OverwriteEx;
internal Proto.GetEa GetEa; internal Proto.GetEa GetEa;
internal Proto.SetEa SetEa; internal Proto.SetEa SetEa;
/* NTSTATUS (*Reserved[33])(); */ internal Proto.Delete Delete;
/* NTSTATUS (*Reserved[32])(); */
} }
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -1147,10 +1196,11 @@ namespace Fsp.Interop
int Length = 0; int Length = 0;
for (int I = 0; NotifyInfoArray.Length > I; I++) for (int I = 0; NotifyInfoArray.Length > I; I++)
{ {
Length = (Length + 7) & ~7; // align to next qword boundary
Length += NotifyInfoInternal.FileNameBufOffset + Length += NotifyInfoInternal.FileNameBufOffset +
NotifyInfoArray[I].FileName.Length * 2; NotifyInfoArray[I].FileName.Length * 2;
Length = (Length + 7) & ~7; // align to next qword boundary
} }
Byte[] Buffer = new Byte[Length]; Byte[] Buffer = new Byte[Length];
UInt32 BytesTransferred = default(UInt32); UInt32 BytesTransferred = default(UInt32);
fixed (Byte *P = Buffer) fixed (Byte *P = Buffer)
@ -1158,8 +1208,8 @@ namespace Fsp.Interop
for (int I = 0; NotifyInfoArray.Length > I; I++) for (int I = 0; NotifyInfoArray.Length > I; I++)
{ {
NotifyInfoInternal Internal = default(NotifyInfoInternal); NotifyInfoInternal Internal = default(NotifyInfoInternal);
Internal.Action = NotifyInfoArray[I].Action; Internal.Action = (UInt32)NotifyInfoArray[I].Action;
Internal.Filter = NotifyInfoArray[I].Filter; Internal.Filter = (UInt32)NotifyInfoArray[I].Filter;
Internal.SetFileNameBuf(NotifyInfoArray[I].FileName); Internal.SetFileNameBuf(NotifyInfoArray[I].FileName);
FspFileSystemAddNotifyInfo( FspFileSystemAddNotifyInfo(
ref Internal, (IntPtr)P, (UInt32)Length, out BytesTransferred); ref Internal, (IntPtr)P, (UInt32)Length, out BytesTransferred);
@ -1383,13 +1433,17 @@ namespace Fsp.Interop
} }
/* initialization */ /* initialization */
internal static String ProductName = "WinFsp";
internal static String ProductFileName = "winfsp";
private static IntPtr LoadDll() private static IntPtr LoadDll()
{ {
String DllPath = null; String DllPath = null;
String DllName = 8 == IntPtr.Size ? "winfsp-x64.dll" : "winfsp-x86.dll"; String DllName = 8 == IntPtr.Size ?
ProductFileName + "-x64.dll" :
ProductFileName + "-x86.dll";
String KeyName = 8 == IntPtr.Size ? String KeyName = 8 == IntPtr.Size ?
"HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\WinFsp" : "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName :
"HKEY_LOCAL_MACHINE\\Software\\WinFsp"; "HKEY_LOCAL_MACHINE\\Software\\" + ProductName;
IntPtr Module; IntPtr Module;
Module = LoadLibraryW(DllName); Module = LoadLibraryW(DllName);
if (IntPtr.Zero == Module) if (IntPtr.Zero == Module)
@ -1483,6 +1537,15 @@ namespace Fsp.Interop
if (Debugger.IsAttached) if (Debugger.IsAttached)
Debugger.Break(); Debugger.Break();
#endif #endif
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(
typeof(AssemblyProductAttribute), false);
if (null != attributes &&
0 < attributes.Length &&
null != attributes[0] as AssemblyProductAttribute)
{
ProductName = (attributes[0] as AssemblyProductAttribute).Product;
ProductFileName = ProductName.ToLowerInvariant();
}
LoadProto(LoadDll()); LoadProto(LoadDll());
CheckVersion(); CheckVersion();
} }

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/Service.cs * dotnet/Service.cs
* *
* Copyright 2015-2020 Bill Zissimopoulos * Copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file launcher/launchctl.c * @file launcher/launchctl.c
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -25,7 +25,7 @@
#include <sddl.h> #include <sddl.h>
#include <userenv.h> #include <userenv.h>
#define PROGNAME "WinFsp.Launcher" #define PROGNAME FSP_FSCTL_PRODUCT_NAME ".Launcher"
static NTSTATUS (NTAPI *SvcNtOpenSymbolicLinkObject)( static NTSTATUS (NTAPI *SvcNtOpenSymbolicLinkObject)(
PHANDLE LinkHandle, PHANDLE LinkHandle,
@ -1321,7 +1321,7 @@ exit:
SvcInstance->StdioHandles[2] = INVALID_HANDLE_VALUE; SvcInstance->StdioHandles[2] = INVALID_HANDLE_VALUE;
} }
if (NT_SUCCESS(Result)) if (NT_SUCCESS(Result) && STATUS_TIMEOUT != Result)
{ {
SvcInstance->Argc = Argc; SvcInstance->Argc = Argc;
SvcInstance->Argv = Argv; SvcInstance->Argv = Argv;

View File

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

View File

@ -4,7 +4,7 @@
* Shared kernel/user configuration. This file is to be included by the * Shared kernel/user configuration. This file is to be included by the
* FSD and DLL components ONLY! * FSD and DLL components ONLY!
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -1,7 +1,7 @@
/** /**
* @file shared/ku/library.h * @file shared/ku/library.h
* *
* @copyright 2015-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -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-2020 Bill Zissimopoulos * @copyright 2015-2021 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -41,6 +41,10 @@ FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor( FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode, UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor); PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMergePermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR ExistingSecurityDescriptor,
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions( FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode); PUINT32 PUid, PUINT32 PGid, PUINT32 PMode);
@ -59,6 +63,7 @@ FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
#pragma alloc_text(PAGE, FspPosixCreateSid) #pragma alloc_text(PAGE, FspPosixCreateSid)
#pragma alloc_text(PAGE, FspDeleteSid) #pragma alloc_text(PAGE, FspDeleteSid)
#pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor) #pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor)
#pragma alloc_text(PAGE, FspPosixMergePermissionsToSecurityDescriptor)
#pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions) #pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions)
#pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx) #pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx)
#pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx) #pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx)
@ -118,9 +123,12 @@ static struct
PWSTR DnsDomainName; PWSTR DnsDomainName;
ULONG TrustPosixOffset; ULONG TrustPosixOffset;
} *FspTrustedDomains; } *FspTrustedDomains;
ULONG FspTrustedDomainCount; static ULONG FspTrustedDomainCount;
static BOOLEAN FspDistinctPermsForSameOwnerGroup;
static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT; static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
#if !defined(_KERNEL_MODE) #if !defined(_KERNEL_MODE)
static ULONG FspPosixInitializeTrustPosixOffsets(VOID) static ULONG FspPosixInitializeTrustPosixOffsets(VOID)
{ {
PVOID Ldap = 0; PVOID Ldap = 0;
@ -164,6 +172,28 @@ exit:
return LdapResult; return LdapResult;
} }
static VOID FspPosixInitializeFromRegistry(VOID)
{
HKEY RegKey;
LONG Result;
DWORD Size;
DWORD DistinctPermsForSameOwnerGroup;
DistinctPermsForSameOwnerGroup = 0;
Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\" FSP_FSCTL_PRODUCT_NAME,
0, KEY_READ | KEY_WOW64_32KEY, &RegKey);
if (ERROR_SUCCESS == Result)
{
Size = sizeof DistinctPermsForSameOwnerGroup;
Result = RegGetValueW(RegKey, 0, L"DistinctPermsForSameOwnerGroup",
RRF_RT_REG_DWORD, 0, &DistinctPermsForSameOwnerGroup, &Size);
RegCloseKey(RegKey);
}
FspDistinctPermsForSameOwnerGroup = !!DistinctPermsForSameOwnerGroup;
}
static BOOL WINAPI FspPosixInitialize( static BOOL WINAPI FspPosixInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
@ -295,6 +325,8 @@ static BOOL WINAPI FspPosixInitialize(
if (0 < FspTrustedDomainCount) if (0 < FspTrustedDomainCount)
FspPosixInitializeTrustPosixOffsets(); FspPosixInitializeTrustPosixOffsets();
FspPosixInitializeFromRegistry();
exit: exit:
if (0 != TrustedDomains) if (0 != TrustedDomains)
NetApiBufferFree(TrustedDomains); NetApiBufferFree(TrustedDomains);
@ -325,7 +357,9 @@ VOID FspPosixFinalize(BOOLEAN Dynamic)
MemFree(FspPrimaryDomainSid); MemFree(FspPrimaryDomainSid);
} }
} }
#else #else
ULONG NTAPI FspPosixInitialize( ULONG NTAPI FspPosixInitialize(
PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context) PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context)
{ {
@ -371,8 +405,12 @@ ULONG NTAPI FspPosixInitialize(
FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V; FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V;
} }
/* always enable permissive permissions for same owner group in kernel mode */
FspDistinctPermsForSameOwnerGroup = TRUE;
return TRUE; return TRUE;
} }
#endif #endif
static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2) static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2)
@ -773,7 +811,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
* bits are different?. In this case, the most restrictive permissions * bits are different?. In this case, the most restrictive permissions
* are chosen and assigned to both ACEs. * are chosen and assigned to both ACEs.
*/ */
if (EqualSid(OwnerSid, GroupSid)) if (!FspDistinctPermsForSameOwnerGroup && EqualSid(OwnerSid, GroupSid))
OwnerPerm = GroupPerm = OwnerPerm & GroupPerm; OwnerPerm = GroupPerm = OwnerPerm & GroupPerm;
/* [PERMS] /* [PERMS]
@ -898,6 +936,101 @@ lasterror:
goto exit; goto exit;
} }
FSP_API NTSTATUS FspPosixMergePermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR ExistingSecurityDescriptor,
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{
FSP_KU_CODE;
if (0 == ExistingSecurityDescriptor)
return FspPosixMapPermissionsToSecurityDescriptor(Uid, Gid, Mode, PSecurityDescriptor);
PSID ExistingOwnerSid = 0, ExistingGroupSid = 0;
BOOL Defaulted, ExistingDaclPresent;
PACL ExistingAcl = 0;
PSID OwnerSid = 0, GroupSid = 0;
SECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_DESCRIPTOR RelativeSecurityDescriptor = 0;
ULONG Size;
NTSTATUS Result;
*PSecurityDescriptor = 0;
if (!GetSecurityDescriptorOwner(ExistingSecurityDescriptor, &ExistingOwnerSid, &Defaulted))
goto lasterror;
if (!GetSecurityDescriptorGroup(ExistingSecurityDescriptor, &ExistingGroupSid, &Defaulted))
goto lasterror;
if (!GetSecurityDescriptorDacl(ExistingSecurityDescriptor, &ExistingDaclPresent, &ExistingAcl, &Defaulted))
goto lasterror;
if (0 == ExistingOwnerSid)
{
Result = FspPosixMapUidToSid(Uid, &OwnerSid);
if (!NT_SUCCESS(Result))
goto exit;
ExistingOwnerSid = OwnerSid;
}
if (0 == ExistingGroupSid)
{
Result = FspPosixMapUidToSid(Gid, &GroupSid);
if (!NT_SUCCESS(Result))
goto exit;
ExistingGroupSid = GroupSid;
}
if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
goto lasterror;
if (!SetSecurityDescriptorOwner(&SecurityDescriptor, ExistingOwnerSid, FALSE))
goto lasterror;
if (!SetSecurityDescriptorGroup(&SecurityDescriptor, ExistingGroupSid, FALSE))
goto lasterror;
if (0 != ExistingAcl)
{
if (!SetSecurityDescriptorControl(&SecurityDescriptor, SE_DACL_PROTECTED, SE_DACL_PROTECTED))
goto lasterror;
if (!SetSecurityDescriptorDacl(&SecurityDescriptor, TRUE, ExistingAcl, FALSE))
goto lasterror;
}
Size = 0;
if (!MakeSelfRelativeSD(&SecurityDescriptor, 0, &Size) &&
ERROR_INSUFFICIENT_BUFFER != GetLastError())
goto lasterror;
RelativeSecurityDescriptor = MemAlloc(Size);
if (0 == RelativeSecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
if (!MakeSelfRelativeSD(&SecurityDescriptor, RelativeSecurityDescriptor, &Size))
goto lasterror;
*PSecurityDescriptor = RelativeSecurityDescriptor;
Result = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(Result))
MemFree(RelativeSecurityDescriptor);
if (0 != GroupSid)
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
if (0 != OwnerSid)
FspDeleteSid(OwnerSid, FspPosixMapUidToSid);
return Result;
lasterror:
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
static inline ACCESS_MASK FspPosixCanonicalizeAccessMask(ACCESS_MASK AccessMask) static inline ACCESS_MASK FspPosixCanonicalizeAccessMask(ACCESS_MASK AccessMask)
{ {
PGENERIC_MAPPING Mapping = FspGetFileGenericMapping(); PGENERIC_MAPPING Mapping = FspGetFileGenericMapping();

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