Compare commits

..

172 Commits

Author SHA1 Message Date
41f80d9c24 update changelog 2019-02-19 12:02:11 -08:00
b69ed7e2f0 Fix #213 and a typo in macro FSP_FUSE_CTLCODE_FROM_IOCTL 2019-02-18 12:25:34 -08:00
f214561832 update changelog 2019-02-18 12:23:56 -08:00
35c06fe0ba bump version to 2019.2 Gold 2019-02-18 12:20:40 -08:00
0eb84d68e2 update changelog 2018-12-10 10:06:17 -08:00
750e424ac3 bump version to 2019.1 Gold 2018-12-10 10:05:58 -08:00
58162a8d78 update changelog 2018-12-10 10:03:00 -08:00
b323925d94 update changelog 2018-12-10 09:34:17 -08:00
3206e3dd15 change version to 2018.2 B4 2018-12-03 13:31:34 -08:00
0f185587c9 dll: np: implement custom Credential Provider logic 2018-11-29 21:05:57 -08:00
3119922708 np, launcher: allow RunAs=. registry setting 2018-11-26 13:29:34 -08:00
5d90c35e20 sys: FspFsvrtDeviceControl: STATUS_UNRECOGNIZED_VOLUME
This fixes GitHub issue #177. All credit for the investigation and
suggested workaround goes to @thinkport.
2018-11-21 15:32:25 -08:00
a910385cb1 dll: ensure FspFileSystemFinalize is called 2018-11-21 13:46:50 -08:00
17d687fe7e tools: run-tests: disable create_readonlydir_test on compat FUSE tests (no FileAttributes) 2018-11-05 14:14:21 -08:00
4deb7b96a9 tools: run-tests: disable create_readonlydir_test on FUSE3 (no FileAttributes) 2018-11-05 12:39:55 -08:00
36ba4ff402 dll: FspAccessCheckEx: fix #190: add test 2018-11-05 11:08:47 -08:00
55955b8514 dll: FspAccessCheckEx: fix #190: add test 2018-11-05 10:45:11 -08:00
1bebbcf634 dll: FspAccessCheckEx: fix #190 2018-10-19 21:53:44 -07:00
a292cd4d73 dll: FspAccessCheckEx: fix #190 2018-10-19 21:41:52 -07:00
0de00e872f dotnet: ModifySecurityDescriptorEx
Deprecate ModifySecurityDecriptor and introduce
ModifySecurityDescriptorEx. Works around the problem
of clobbering an existing security descriptor when the
native API FspSetSecurityDescriptor fails.
2018-10-08 15:08:07 -07:00
084f0b5b36 update changelog 2018-10-02 11:10:20 -07:00
901ef5e92f update changelog 2018-10-01 17:05:14 -07:00
f09597a519 bump version to 2018.2 Gold 2018-10-01 16:57:49 -07:00
a03b480eeb changelog: add note about drweb fix 2018-09-27 12:27:36 -07:00
c9f1c1c60d sys: FspPropagateTopFlags: only touch TopLevelIrp if it looks like a kernel mode address 2018-09-27 09:31:09 -07:00
f32c914ee8 sys: create: FspFsvolCreate
Only check reparse point ECP if running on OS prior to RS4
2018-09-06 18:03:53 -07:00
681eac9cd8 sys: create: FspFsvolCreate
Only check reparse point ECP if running on OS prior to RS4
2018-09-06 17:52:52 -07:00
52f0d1e1d8 Changelog, FAQ: add info about reparse point and case-sensitivity fix 2018-09-06 17:06:51 -07:00
dcf3d612bc sys: create: FspFsvolCreate
Fix file name case after crossing a reparse point as per
http://online.osr.com/ShowThread.cfm?link=287522
2018-09-06 16:40:27 -07:00
4551766f7a sys: create: FspFsvolCreate
Replace FspMainFileOpenCheck with inline code
2018-09-06 13:26:53 -07:00
a168b96b76 changelog: add SetDelete information 2018-09-05 14:28:26 -07:00
4b3d9951bc changelog: add SetDelete information 2018-09-05 14:26:54 -07:00
79fd87598f dotnet: Interop: fix silly mistake in SetDelete 2018-09-04 15:28:24 -07:00
9851f1b2c8 dotnet: properly handle SetDelete/CanDelete resolution 2018-08-29 20:54:49 -07:00
4725ff41d3 dotnet: FileSystemHost.DeviceControl flag 2018-08-29 17:21:24 -07:00
4756ee2d8a passthrough-dotnet: FlushAndPurgeOnCleanup 2018-08-29 16:45:14 -07:00
25f627f36f passthrough: FlushAndPurgeOnCleanup, SetDelete 2018-08-29 16:44:47 -07:00
24b96e7e1b inc, dll, dotnet: FSP_FILE_SYSTEM_INTERFACE::SetDelete 2018-08-29 15:45:02 -07:00
75ae8daf8f update commercial disclaimer 2018-08-21 18:09:33 -07:00
999847d8db Merge pull request #181 from JohnOberschelp/master
Added DeviceIoControl to Airfs
2018-08-01 19:35:03 -07:00
773bb12146 Update airfs.cpp 2018-08-01 17:34:24 -07:00
bef5ba7f3b dll: fuse: fix daemonization problem on Cygwin
The new FUSE loop use a Windows event (LoopEvent) to signal loop exit.
Prior to this commit the Windows event was created outside the FUSE
loop and potentially before daemonization (on Cygwin). This means that
the event was created in a different process and
WaitForMultipleObjects was failing with ERROR_ACCESS_DENIED.

This commit ensures that the LoopEvent is created inside the FUSE loop
and therefore in the daemonized process.
2018-07-31 21:02:46 -07:00
eecb7e00e2 fix tabs to spaces 2018-07-31 17:21:40 -07:00
9160f1c4ce cygfuse: fix CRLF to LF 2018-07-31 15:34:29 -07:00
796f97f078 cygfuse: remove exec bit from Makefile 2018-07-31 15:20:26 -07:00
5f1c3b7728 build: bump version 2018-07-31 15:12:50 -07:00
f672ae817a Added DeviceIoControl to Airfs
Added DeviceIoControl code à la Memfs, simplified file allocation code, and cleaned up some white space.
2018-07-31 15:04:08 -07:00
04cf0e04ba README: change download badges size 2018-07-29 15:37:23 -07:00
f51af55fb3 doc: update winfsp.h apidoc 2018-07-29 15:27:55 -07:00
f9a2780311 README: multiple improvements 2018-07-29 15:05:53 -07:00
43101dfe06 dll: fuse: improve service start/stop messaging 2018-07-29 10:52:01 -07:00
ac5ed1c238 update FAQ 2018-07-28 20:40:33 -07:00
03f0d2bd1a update FAQ 2018-07-28 20:36:07 -07:00
77c18fc59e cygfuse: update with latest headers 2018-07-28 14:28:40 -07:00
77cf7f7398 dll: fuse3: compatibility functions 2018-07-28 14:08:03 -07:00
c61da81475 changelog: FUSE supports multiple in-process file systems 2018-07-28 13:41:51 -07:00
a1b92d9095 dll: fuse: refactoring
Split dll/fuse.c into dll/fuse.c and dll/fuse_loop.c to accommodate
the complicated loop logic due to the last commit.
2018-07-28 13:38:06 -07:00
ae8e4e61f7 dll: fuse: allow multiple FUSE file systems
Refactoring to allow for multiple FUSE file systems within a single
process. Running FUSE file systems as Windows services is still
supported.
2018-07-28 13:13:27 -07:00
e5c424dba1 dll: service: FspServiceLoop
Do not reset FspServiceConsoleModeEvent on reentry.
It should be noted that reentry is not feasible,
because StartServiceCtrlDispatcherW returns
ERROR_SERVICE_ALREADY_RUNNING on reentry.
2018-07-27 11:09:43 -07:00
554f07a50e dll: fuse3: fsp_fuse3_pkgversion: bug fix 2018-07-26 10:17:38 -07:00
bd53b452b2 opt: cygfuse: fuse3: REQUIRES fuse 2018-07-26 10:03:48 -07:00
82cea37036 installer: add FUSE3 for Cygwin 2018-07-25 21:46:38 -07:00
2fcc065421 README: fix link 2018-07-25 21:34:59 -07:00
bf53c00f38 README: add links for project dirs 2018-07-25 21:32:53 -07:00
ec4197d8b7 opt: cygfuse: fix install scripts 2018-07-25 21:23:29 -07:00
897a08700b opt: cygfuse: fuse3 2018-07-25 21:15:16 -07:00
1ace7ffb41 opt: cygfuse: fuse: rename cygport 2018-07-25 20:23:13 -07:00
d7c0657c3d opt: cygfuse: refactoring 2018-07-25 20:13:53 -07:00
5d73687de8 dll: fuse: refactoring 2018-07-25 13:33:15 -07:00
a5bfdcf416 README: add reference to FUSE3 2018-07-25 13:31:42 -07:00
b609435dad dll: fuse: refactoring 2018-07-25 13:26:36 -07:00
523ccbea02 Merge branch 'pvt-fuse3' 2018-07-25 12:54:54 -07:00
cf699ba441 tools: run-tests: passthrough-fuse3 2018-07-25 11:29:24 -07:00
0d819eb800 dll: fuse3: testing 2018-07-25 10:28:33 -07:00
4a653a8bc0 dll: fuse3: testing 2018-07-25 10:04:23 -07:00
6932d42039 dll: fuse3: testing 2018-07-25 08:54:22 -07:00
77fb2cc1c1 tools: run-tests: enable all winfsp-tests on airfs 2018-07-24 21:54:38 -07:00
500dfe1958 Merge pull request #178 from JohnOberschelp/master
Fixed to pass winfsp-tests and cleanup
2018-07-24 21:52:32 -07:00
1b40d8db80 Fixed to pass winfsp-tests and cleanup
Fixed AIRFS_NAMED_STREAMS bugs that caused stream_create_overwrite_test and stream_getstreaminfo_test to fail.
Also tidied up a few things.
2018-07-24 16:22:41 -07:00
307e18fb0d update changelog 2018-07-20 15:44:10 -07:00
461266382a changelog: add FUSE3 information 2018-07-20 15:35:12 -07:00
a809b0787e changelog: add FUSE3 information 2018-07-20 15:34:31 -07:00
ea5e031af2 changelog: add FUSE3 information 2018-07-20 15:17:47 -07:00
558487cd22 installer: passthrough-fuse3 2018-07-20 15:12:22 -07:00
2ff21529d5 tst: passthrough-fuse3 2018-07-20 14:48:25 -07:00
d43c0c2c85 inc: fuse3: fix warnings 2018-07-20 09:37:59 -07:00
eb0f03b17b build: fuse3: installer and pkg-config 2018-07-20 09:24:22 -07:00
575fe55eb8 dll: fuse3: fsp_fuse3_main_real 2018-07-19 14:24:09 -07:00
b537c61f3b dll: fuse3: checkpoint 2018-07-19 12:53:03 -07:00
5cd40ff7ff dll: fuse3: fsp_fuse3_lib_help 2018-07-19 06:39:18 -07:00
753440e837 dll: fuse3: checkpoint 2018-07-19 06:13:48 -07:00
9b79bb24ca dll: fuse3: checkpoint 2018-07-19 04:27:06 -07:00
931d201527 dll: fuse3: fuse2to3 implementation 2018-07-18 14:48:10 -07:00
ab3f3d2827 dll: fuse3: fuse2to3 implementation 2018-07-18 04:11:20 -07:00
3dc09b2496 dll: fuse: remove dll/fuse/shared.h 2018-07-16 14:21:57 -07:00
27d03d4323 dll: fuse: ENOSYS has different values on Windows vs Cygwin 2018-07-16 09:50:21 -07:00
ad1b53e5a4 dll: fuse: move fsp_fuse_obj_* to sdll/fuse/shared.h 2018-07-16 09:45:38 -07:00
e4077c92e9 dll: fuse: ENOSYS has different values on Windows vs Cygwin 2018-07-16 09:42:15 -07:00
e3290a30bc fuse3: initial commit 2018-07-16 09:31:32 -07:00
09309f858c airfs: testing 2018-07-14 12:07:04 -07:00
12baaa6d50 airfs: testing 2018-07-14 11:15:12 -07:00
c584782bc7 airfs: testing 2018-07-14 11:04:10 -07:00
9c4a361c48 airfs: testing as disk file system 2018-07-14 09:16:14 -07:00
c1f4606683 airfs: FspLoad: dynamic loading of WinFsp DLL 2018-07-14 07:38:30 -07:00
f79db6a3db airfs: installer 2018-07-07 09:38:42 -07:00
9a9a73d4d8 airfs: testing 2018-07-05 23:36:20 +01:00
a56caf3f94 bump version to 2018.2 B2 and update changelog 2018-07-05 15:13:56 -07:00
9b8b3e9cb8 Merge branch 'airfs' 2018-07-05 15:02:15 -07:00
5a8aad60b3 airfs: add notice re: contributions 2018-07-05 14:59:24 -07:00
1906772aa2 airfs: add VS project 2018-07-05 14:45:44 -07:00
ce924d737c dotnet: rename Api.GetFspVersion to Api.GetVersion 2018-07-05 14:11:51 -07:00
aa50d5a8b9 Contributors: sort names 2018-07-05 21:59:38 +01:00
6ffddf36b5 Merge pull request #176 from FrKaram/Issue174
dotnet: add FlushAndPurgeOnCleanup and FspVersion
2018-07-05 21:55:34 +01:00
ee4145e947 Update Contributors.asciidoc 2018-07-03 11:20:44 +02:00
fd817e37c9 Updated Contributor Agreement 2018-07-03 10:01:57 +02:00
2056766b4f Indentation again 2018-07-01 13:52:09 +02:00
c73f7099b7 Indentation again 2018-07-01 13:51:17 +02:00
3513f0da5f Correct VS auto-format 2018-07-01 13:50:02 +02:00
c9c62b1831 Fixed Indentation 2018-07-01 13:48:48 +02:00
8422e8121c Fixed identation 2018-07-01 13:46:20 +02:00
88516f371a Fixed indentation 2018-07-01 13:45:47 +02:00
916b4f5c3d Wrongly remove gitignore 2018-07-01 13:35:25 +02:00
a7424c911b Changes following PR remarks 2018-07-01 13:29:52 +02:00
fb8cb8aca9 Added FpsVersion as a static method in FileSystemHost
Added FlushAndPurgeOnCleanup
2018-06-30 20:20:17 +02:00
d0f5ea69a2 Added FlushAndPurgeOnCleanup property in .NET wrapper 2018-06-28 23:01:26 +02:00
fbb81b0463 Merge pull request #173 from JohnOberschelp/master
Create airfs.cpp
2018-06-23 23:19:04 -07:00
14a2004437 Create airfs.cpp 2018-06-23 16:36:31 -07:00
d491031fda bump version to 2018.2 B1 2018-06-19 14:24:24 -07:00
75a3d97c62 Merge branch 'release/1.3' 2018-05-11 10:18:29 -07:00
5f325304d3 tst: memfs: rewrite MemfsFileNameCompare 2018-05-10 19:53:57 -07:00
8727497662 tst: memfs: remove CompareString usage 2018-05-10 12:31:01 -07:00
a2ed9f2b1a github: update ISSUE_TEMPLATE 2018-05-08 21:44:30 -07:00
fdaf1da778 Merge branch 'pvt-devctl' 2018-05-08 20:49:22 -07:00
1123e7b0ef dll: fuse: optimize symlinks aways when readlink returns -ENOSYS 2018-05-08 10:51:29 -07:00
06ee833740 dll: fuse: enable DeviceControl 2018-05-07 14:13:24 -07:00
fbcefe6339 dll: fuse: ioctl 2018-05-07 14:05:18 -07:00
637a1dac7e dotnet: implement Control operation 2018-05-04 14:51:48 -07:00
05f622f2de inc: winfsp.h: fix Control doc 2018-05-04 14:48:46 -07:00
ef5c947168 update changelog 2018-05-04 14:08:24 -07:00
894ae7b8f3 sys,dll: DeviceControl operation 2018-05-04 13:56:20 -07:00
7aadf259d9 bump version to v1.3 (2018.1) 2018-05-04 05:09:35 +01:00
d54e9a3049 update changelog 2018-05-01 10:38:58 -07:00
7d56b9c23d dll: fuse: GetSecurityByName: correctly handle "not found" paths with symlinks 2018-04-30 14:18:03 -07:00
deb237f7b0 dll: fuse: fsp_fuse_intf_AddDirInfo: avoid deadlock with ReaddirPlus and symlinks 2018-04-30 13:31:06 -07:00
5ae0804bd2 doc: add EncFS to known file systems 2018-04-27 12:12:25 -07:00
382599e38f dll: fuse: add ThreadCount option 2018-04-23 15:35:30 -07:00
498ab91123 dll: fuse: replace -oFlushAndPurgeOnCleanup with -oKeepFileCache option 2018-04-23 15:12:30 -07:00
c2f87029d7 sys: FspFileNodeCleanupFlush:
- CcFlushCache now happens during initial Cleanup call
- avoids recursive call into file system during Cleanup completion
2018-04-23 14:30:38 -07:00
157c4bc09a sys: FspFileNodeCleanupComplete: FlushAndPurgeOnCleanup:
- comment about difference in behavior when DeletePending
2018-04-23 09:57:47 -07:00
4fcaa99d63 sys: FspFileNodeCleanupComplete: FlushAndPurgeOnCleanup:
- handle DeletePending and non-zero PTruncateSize better
2018-04-23 00:33:00 -07:00
d6c3849120 dll: fuse: fix wrong calc of FileInfoTimeout from attr_timeout 2018-04-22 23:42:20 -07:00
ec39d4b888 dll: fuse: DirInfoTimeout, VolumeInfoTimeout options 2018-04-22 23:36:47 -07:00
ebc8c268e5 appveyor: FSP_FSCTL_VOLUME_PARAMS size change compat testing 2018-04-22 11:16:25 -07:00
9501b5771d inc,sys,tst: FSP_FSCTL_VOLUME_PARAMS: fine-grained timeouts 2018-04-21 11:53:14 -07:00
5d34a3bd8c dll: fuse: FlushAndPurgeOnCleanup option 2018-04-19 13:04:34 -07:00
5b72b4ad4a tools: run-tests: FlushAndPurgeOnCleanup 2018-04-19 11:17:41 -07:00
740411d604 tst: FlushAndPurgeOnCleanup: testing 2018-04-19 10:23:15 -07:00
5c3549c6eb sys: file: FspFileNodeCleanupComplete: FlushAndPurgeOnCleanup 2018-04-18 20:58:19 -07:00
9f56a21c7f sys: cleanup: minor change 2018-04-18 20:13:08 -07:00
2e7e95df76 appveyor: troubleshoot create_pid_test, rename_pid_test 2018-04-17 16:34:59 -07:00
b2e6c16ba0 update changelog 2018-04-17 13:47:37 -07:00
bd32f54904 Revert "installer: launch MEMFS as LocalService"
This reverts commit a7febb8265.
2018-04-17 13:24:57 -07:00
7908ba09ac appveyor: troubleshoot rename_pid_test 2018-04-17 13:16:52 -07:00
5713605030 appveyor: troubleshoot create_pid_test 2018-04-17 13:14:34 -07:00
994e232fb3 fuse: add create_umask option 2018-04-17 12:46:13 -07:00
9553bd52c4 update changelog for v1.3B2 (overdue) 2018-04-17 12:26:48 -07:00
1cab0f3975 cygfuse: correctly use cygwin_create_path 2018-03-26 14:11:58 -07:00
499a3d1138 Merge pull request #154 from benrubson/cast
Correct a cast in winfsp_fuse
2018-03-26 13:07:30 -07:00
d29218ba69 Update Contributors.asciidoc 2018-03-26 21:50:37 +02:00
5564a9efae Correct a cast in winfsp_fuse 2018-03-26 10:36:26 +02:00
750e72e601 installer: add launch.h 2018-01-29 09:16:30 -08:00
9f13c6e915 build: update version to 2018.1 B3 2018-01-29 09:04:17 -08:00
182 changed files with 9164 additions and 1125 deletions

View File

@ -1,12 +0,0 @@
(Enter your issue here.)
----
Before submitting this issue please review this checklist. Ideally all checkmarks should be checked upon submitting. (Use an x inside square brackets like so: [x])
- [ ] **Issue type**: Please consider posting only bug reports or enhancement requests. Questions are better in the [WinFsp Google Group](https://groups.google.com/forum/#!forum/winfsp). Please also consult the [WinFsp Frequently Asked Questions](https://github.com/billziss-gh/winfsp/wiki/Frequently-Asked-Questions).
- [ ] **No Duplicate**: Ensure that your issue has not been filed before. (Check open and closed issues.)
- [ ] **Description**: Provide a descriptive title and a detailed explanation of the problem you are experiencing (for a bug report) or you are trying to solve (for an enhancement request).
- [ ] **Reproduce**: For bug reports provide detailed information on how to reproduce the problem. For enhancement requests you do not need to provide this information, unless you find it relevant.
- [ ] **Behaviors**: Provide information on the expected and actual behaviors.
- [ ] **Environment**: For bug reports provide information about your OS version and build (e.g. 10.0.14393) and WinFsp version and build (e.g. 2017.2 or 1.2.17341). For enhancement requests you do not need to provide this information, unless you find it relevant.

21
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

@ -0,0 +1,21 @@
---
name: Bug Report
about: File a bug report.
---
## Bug Report
_Provide a descriptive title and a detailed explanation of the problem you are experiencing. Ensure that your issue has not been filed before._
### How to Reproduce
_Provide detailed information on how to reproduce the problem._
### Behaviors
_Provide information on the expected and actual behaviors._
### Environment
- OS version and build: _e.g. 10.0.14393_
- WinFsp version and build: _e.g. 2017.2 or 1.2.17341_

8
.github/ISSUE_TEMPLATE/enhancement.md vendored Normal file
View File

@ -0,0 +1,8 @@
---
name: Enhancement Request
about: File an enhancement request.
---
## Enhancement Request
_Provide a descriptive title and a detailed explanation of the problem the requested enhancement would solve. Ensure that your issue has not been filed before._

8
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,8 @@
---
name: Question
about: Questions are better asked in the WinFsp Google Group. However you may ask a question here.
---
## Question
_Please consider asking questions in the [WinFsp Google Group](https://groups.google.com/forum/#!forum/winfsp) instead. Before asking a question please also consult the [WinFsp Frequently Asked Questions](https://github.com/billziss-gh/winfsp/wiki/Frequently-Asked-Questions)._

View File

@ -1,6 +1,145 @@
= Changelog = Changelog
v1.4.19049 (2019.2)::
Changes since v1.3:
* FUSE3 API (version 3.2) is now available. The FUSE2 API (version 2.8) also remains supported.
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API. FUSE `ioctl` is also supported.
* New `SetDelete` file system operation can optionally be used instead of `CanDelete`. `SetDelete` or `CanDelete` are used to handle the file "disposition" flag, which determines if a file is marked for deletion. See the relevant documentation for more details.
* `FlushAndPurgeOnCleanup` has now been added to the .NET API. (GitHub PR #176; thanks @FrKaram.)
* The Launcher now supports running file systems under the user account that started them. Use `RunAs="."` in the file system registry entry.
* New sample file system "airfs" contributed by @JohnOberschelp. Airfs is an in-memory file system like Memfs on which it is based on; it has received substantial improvements in how the file name space is maintained and has been modified to use modern C++ techniques by John.
* New sample file system "passthrough-fuse3" passes all operations to an underlying file system. This file system is built using the FUSE3 API. It builds and runs on both Windows and Cygwin.
* The FUSE layer now supports multiple file systems within a single process. This is a long standing problem that has been fixed. (GitHub issue #135.)
* The FSD includes a fix for a Windows problem: that case-sensitive file systems do not work properly when mounted as directories. See FAQ entry #3.
* The FSD includes a fix for a rare but serious problem. (GitHub issue #177. Thanks @thinkport.)
* The FSD includes a fix for an incompatibility with DrWeb Antivirus. (GitHub issue #192)
* The DLL includes a fix for an errorenous `STATUS_ACCESS_DENIED` on read-only directories. (GitHub issue #190. Thanks @alfaunits.)
* The FUSE layer includes a fix for the `ioctl` operation. (GitHub PR #214. Thanks @felfert.)
v1.4 (2019.1)::
Changes since v1.3:
* FUSE3 API (version 3.2) is now available. The FUSE2 API (version 2.8) also remains supported.
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API. FUSE `ioctl` is also supported.
* New `SetDelete` file system operation can optionally be used instead of `CanDelete`. `SetDelete` or `CanDelete` are used to handle the file "disposition" flag, which determines if a file is marked for deletion. See the relevant documentation for more details.
* `FlushAndPurgeOnCleanup` has now been added to the .NET API. (GitHub PR #176; thanks @FrKaram.)
* The Launcher now supports running file systems under the user account that started them. Use `RunAs="."` in the file system registry entry.
* New sample file system "airfs" contributed by @JohnOberschelp. Airfs is an in-memory file system like Memfs on which it is based on; it has received substantial improvements in how the file name space is maintained and has been modified to use modern C++ techniques by John.
* New sample file system "passthrough-fuse3" passes all operations to an underlying file system. This file system is built using the FUSE3 API. It builds and runs on both Windows and Cygwin.
* The FUSE layer now supports multiple file systems within a single process. This is a long standing problem that has been fixed. (GitHub issue #135.)
* The FSD includes a fix for a Windows problem: that case-sensitive file systems do not work properly when mounted as directories. See FAQ entry #3.
* The FSD includes a fix for a rare but serious problem. (GitHub issue #177. Thanks @thinkport.)
* The FSD includes a fix for an incompatibility with DrWeb Antivirus. (GitHub issue #192)
* The DLL includes a fix for an errorenous `STATUS_ACCESS_DENIED` on read-only directories. (GitHub issue #190. Thanks @alfaunits.)
v1.4B4 (2018.2 B4)::
Changes since v1.3:
* FUSE3 API (version 3.2) is now available. The FUSE2 API (version 2.8) also remains supported.
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API. FUSE `ioctl` is also supported.
* New `SetDelete` file system operation can optionally be used instead of `CanDelete`. `SetDelete` or `CanDelete` are used to handle the file "disposition" flag, which determines if a file is marked for deletion. See the relevant documentation for more details.
* `FlushAndPurgeOnCleanup` has now been added to the .NET API. (GitHub PR #176; thanks @FrKaram.)
* The Launcher now supports running file systems under the user account that started them. Use `RunAs="."` in the file system registry entry.
* New sample file system "airfs" contributed by @JohnOberschelp. Airfs is an in-memory file system like Memfs on which it is based on; it has received substantial improvements in how the file name space is maintained and has been modified to use modern C++ techniques by John.
* New sample file system "passthrough-fuse3" passes all operations to an underlying file system. This file system is built using the FUSE3 API. It builds and runs on both Windows and Cygwin.
* The FUSE layer now supports multiple file systems within a single process. This is a long standing problem that has been fixed. (GitHub issue #135.)
* The FSD includes a fix for a Windows problem: that case-sensitive file systems do not work properly when mounted as directories. See FAQ entry #3.
* The FSD includes a fix for a rare but serious problem. (GitHub issue #177. Thanks @thinkport.)
* The FSD includes a fix for an incompatibility with DrWeb Antivirus. (GitHub issue #192)
* The DLL includes a fix for an errorenous `STATUS_ACCESS_DENIED` on read-only directories. (GitHub issue #190. Thanks @alfaunits.)
v1.4B3 (2018.2 B3)::
Changes since v1.3:
* FUSE3 API (version 3.2) is now available. The FUSE2 API (version 2.8) also remains supported.
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API. FUSE `ioctl` is also supported.
* New `SetDelete` file system operation can optionally be used instead of `CanDelete`. `SetDelete` or `CanDelete` are used to handle the file "disposition" flag, which determines if a file is marked for deletion. See the relevant documentation for more details.
* `FlushAndPurgeOnCleanup` has now been added to the .NET API. (GitHub PR #176; thanks @FrKaram.)
* New sample file system "airfs" contributed by @JohnOberschelp. Airfs is an in-memory file system like Memfs on which it is based on; it has received substantial improvements in how the file name space is maintained and has been modified to use modern C++ techniques by John.
* New sample file system "passthrough-fuse3" passes all operations to an underlying file system. This file system is built using the FUSE3 API. It builds and runs on both Windows and Cygwin.
* The FUSE layer now supports multiple file systems within a single process. This is a long standing problem that has been fixed. (GitHub issue #135.)
* The FSD includes an experimental fix for a Windows problem: that case-sensitive file systems do not work properly when mounted as directories. See the relevant FAQ entry.
* The FSD includes a fix for an incompatibility with DrWeb Antivirus. (GitHub issue #192)
v1.4B2 (2018.2 B2)::
Changes since v1.3:
* FUSE3 API (version 3.2) is now available. The FUSE2 API (version 2.8) also remains supported.
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API. FUSE `ioctl` is also supported.
* `FlushAndPurgeOnCleanup` has now been added to the .NET API. (GitHub PR #176; thanks @FrKaram.)
* New sample file system "airfs" contributed by @JohnOberschelp. Airfs is an in-memory file system like Memfs on which it is based on; it has received substantial improvements in how the file name space is maintained and has been modified to use modern C++ techniques by John.
* New sample file system "passthrough-fuse3" passes all operations to an underlying file system. This file system is built using the FUSE3 API. It builds and runs on both Windows and Cygwin.
* The FUSE layer now supports multiple file systems within a single process. This is a long standing problem that has been fixed. (GitHub issue #135.)
v1.4B1 (2018.2 B1)::
Changes since v1.3:
* New `Control` file system operation allows sending custom control codes to the file system using the Windows `DeviceIoControl` API.
v1.3 (2018.1)::
Changes since v1.2POST1:
* Multiple Launcher changes:
** New `FspLaunch` API. File systems can be started, stopped, queried and listed using `FspLaunchStart`, `FspLaunchStop`, `FspLaunchGetInfo` and `FspLaunchGetNameList`. The API is available in <winfsp/launch.h>
** New Launcher registry settings `RunAs` and `WorkDirectory`. `RunAs` allows the laucher to launch a file system process under the service accounts LocalService and NetworkService. `WorkDirectory` can be used to specify the work directory for a newly launched file system process.
* `FSP_FSCTL_VOLUME_PARAMS::FlushAndPurgeOnCleanup` limits the time that Windows keeps files open after an application has closed them. This purges the cache on the last `CloseHandle`, which is a performance drawback.
** This is now the default behavior on FUSE. To revert to the previous behavior of keeping files open indefinitely use `-o KeepFileCache`.
* `FSP_FSCTL_VOLUME_PARAMS` has been extended with fine-grained timeouts: `VolumeInfoTimeout`, `DirInfoTimeout`, `SecurityTimeout`, `StreamInfoTimeout`. Set `FSP_FSCTL_VOLUME_PARAMS::Version == sizeof(FSP_FSCTL_VOLUME_PARAMS)` to access the new fields.
** New FUSE optons `VolumeInfoTimeout`, `DirInfoTimeout` complement the existing `FileInfoTimeout`.
* The FSD (File System Driver) and its interaction with the Windows MUP (Multiple UNC Provider) has been changed. In practice this eliminates the delays experienced when right-clicking on a WinFsp-backed network drive in the Windows Explorer. (GitHub issue #87.)
* The WinFsp network provider is now added first in the provider order list. Previously it was added last. (GitHub PR #131; thanks @felfert.)
* The WinFsp installer now uses the Wix `Provides` dependency extension to provide a `WinFsp` dependency key. (GitHub PR #129; thanks @felfert.)
* New FUSE `create_umask` option. (GitHub issue #138.)
* Fix C++ compilation error for WinFsp-FUSE. (GitHub PR #154; thanks @benrubson.)
v1.3B3 (2018.1 B3)::
Changes since v1.2POST1:
* Multiple Launcher changes:
** New `FspLaunch` API. File systems can be started, stopped, queried and listed using `FspLaunchStart`, `FspLaunchStop`, `FspLaunchGetInfo` and `FspLaunchGetNameList`. The API is available in <winfsp/launch.h>
** New Launcher registry settings `RunAs` and `WorkDirectory`. `RunAs` allows the laucher to launch a file system process under the service accounts LocalService and NetworkService. `WorkDirectory` can be used to specify the work directory for a newly launched file system process.
* `FSP_FSCTL_VOLUME_PARAMS::FlushAndPurgeOnCleanup` limits the time that Windows keeps files open after an application has closed them. This purges the cache on the last `CloseHandle`, which is a performance drawback.
** This is now the default behavior on FUSE. To revert to the previous behavior of keeping files open indefinitely use `-o KeepFileCache`.
* `FSP_FSCTL_VOLUME_PARAMS` has been extended with fine-grained timeouts: `VolumeInfoTimeout`, `DirInfoTimeout`, `SecurityTimeout`, `StreamInfoTimeout`. Set `FSP_FSCTL_VOLUME_PARAMS::Version == sizeof(FSP_FSCTL_VOLUME_PARAMS)` to access the new fields.
** New FUSE optons `VolumeInfoTimeout`, `DirInfoTimeout` complement the existing `FileInfoTimeout`.
* The FSD (File System Driver) and its interaction with the Windows MUP (Multiple UNC Provider) has been changed. In practice this eliminates the delays experienced when right-clicking on a WinFsp-backed network drive in the Windows Explorer. (GitHub issue #87.)
* The WinFsp network provider is now added first in the provider order list. Previously it was added last. (GitHub PR #131; thanks @felfert.)
* The WinFsp installer now uses the Wix `Provides` dependency extension to provide a `WinFsp` dependency key. (GitHub PR #129; thanks @felfert.)
* New FUSE `create_umask` option. (GitHub issue #138.)
* Fix C++ compilation error for WinFsp-FUSE. (GitHub PR #154; thanks @benrubson.)
* *NOTE*: Prior v1.3 betas run the MEMFS sample file systems under the LocalService account. This is no longer the case: going forward the MEMFS file systems will be running under the LocalSystem account (as in v1.2POST1).
v1.3B2 (2018.1 B2)::
Changes since v1.2POST1:
* Multiple Launcher changes:
** New `FspLaunch` API. File systems can be started, stopped, queried and listed using `FspLaunchStart`, `FspLaunchStop`, `FspLaunchGetInfo` and `FspLaunchGetNameList`.
** New Launcher registry settings `RunAs` and `WorkDirectory`. `RunAs` allows the laucher to launch a file system process under the service accounts LocalService and NetworkService. `WorkDirectory` can be used to specify the work directory for a newly launched file system process.
* The MEMFS sample file systems are now launched under the LocalService account.
* The FSD (File System Driver) and its interaction with the Windows MUP (Multiple UNC Provider) has been changed. In practice this eliminates the delays experienced when right-clicking on a WinFsp-backed network drive in the Windows Explorer. (GitHub issue #87.)
* The WinFsp network provider is now added first in the provider order list. Previously it was added last. (GitHub PR #131; thanks @felfert.)
* The WinFsp installer now uses the Wix `Provides` dependency extension to provide a `WinFsp` dependency key. (GitHub PR #129; thanks @felfert.)
v1.3B1 (2018.1 B1):: v1.3B1 (2018.1 B1)::
Changes since v1.2POST1: Changes since v1.2POST1:

View File

@ -54,7 +54,9 @@ This CONTRIBUTOR AGREEMENT applies to any contribution that you make to the WinF
CONTRIBUTOR LIST CONTRIBUTOR LIST
---------------- ----------------
|=== |===
|Ben Rubson |ben.rubson at gmail.com
|Bill Zissimopoulos |billziss at navimatics.com |Bill Zissimopoulos |billziss at navimatics.com
|Francois Karam (KS2, http://www.ks2.fr) |francois.karam at ks2.fr
|Fritz Elfert |fritz-github at fritz-elfert.de |Fritz Elfert |fritz-github at fritz-elfert.de
|John Oberschelp |john at oberschelp.net |John Oberschelp |john at oberschelp.net
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com |Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com

116
README.md
View File

@ -1,24 +1,74 @@
# WinFsp - Windows File System Proxy <h1 align="center">
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>
![WinFsp Demo](http://www.secfs.net/winfsp/files/cap.gif) <p align="center">
<b>Download</b><br>
<a href="https://github.com/billziss-gh/winfsp/releases/latest">
<img src="https://img.shields.io/github/release/billziss-gh/winfsp.svg?label=stable&style=for-the-badge"/>
</a>
<a href="https://github.com/billziss-gh/winfsp/releases">
<img src="https://img.shields.io/github/release/billziss-gh/winfsp/all.svg?label=latest&colorB=e52e4b&style=for-the-badge"/>
</a>
<a href="https://chocolatey.org/packages/winfsp">
<img src="https://img.shields.io/badge/choco-install%20winfsp-black.svg?style=for-the-badge"/>
</a>
<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/>
<a href="https://ci.appveyor.com/project/billziss-gh/winfsp">
<img src="https://img.shields.io/appveyor/ci/billziss-gh/winfsp.svg"/>
</a>
<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.
<br/>
<br/>
<img src="http://www.secfs.net/winfsp/files/cap.gif" height="450"/>
</p>
<a href="https://github.com/billziss-gh/winfsp/releases/latest"><img src="http://www.secfs.net/winfsp/resources/Download-WinFsp.png" alt="Download WinFsp Installer" width="244" height="34"></a> ## Benefits
&emsp;
<a href="https://chocolatey.org/packages/winfsp"><img src="http://www.secfs.net/winfsp/resources/Choco-WinFsp.png" alt="choco install winfsp" width="244" height="34"></a>
### Stability
WinFsp is very stable. There are no known kernel mode crashes and it does not suffer from resource leaks or similar problems. WinFsp owes this stability to its [Design](doc/WinFsp-Design.asciidoc) and its rigorous [Testing Regime](doc/WinFsp-Testing.asciidoc).
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. ### Performance
Some of the benefits of using WinFsp are listed below: WinFsp outperforms its competition and in many scenarios performs as well as NTFS. Read more about its [Performance](doc/WinFsp-Performance-Testing.asciidoc).
<p align="center">
<img src="doc/WinFsp-Performance-Testing/file_tests.png" height="300"/>
<img src="doc/WinFsp-Performance-Testing/rdwr_tests.png" height="300"/>
</p>
### Compatibility
WinFsp strives for compatibility with NTFS and file system correctness. For the full details see the [Compatibility](doc/NTFS-Compatibility.asciidoc) document.
### Easy to Use
WinFsp has an easy to use but comprehensive API.
* This simple [Tutorial](doc/WinFsp-Tutorial.asciidoc) explains how to build a file system.
* Consult the [API Reference](http://www.secfs.net/winfsp/apiref/) for native development.
* Includes .NET layer for managed development. See [src/dotnet](src/dotnet).
* Includes FUSE 2.8 compatibility layer: [fuse/fuse.h](inc/fuse/fuse.h)
* Includes FUSE 3.2 compatibility layer: [fuse3/fuse.h](inc/fuse3/fuse.h)
### Other Benefits
* Very well-tested and stable. Read about its [Testing Strategy](doc/WinFsp-Testing.asciidoc).
* Very fast. Read about its [Performance](doc/WinFsp-Performance-Testing.asciidoc).
* Strives for compatibility with NTFS. Read about its [Compatibility](doc/NTFS-Compatibility.asciidoc ).
* Easy to understand but comprehensive API. Consult the [API Reference](http://www.secfs.net/winfsp/apiref/). There is also a simple [Tutorial](doc/WinFsp-Tutorial.asciidoc).
* FUSE compatibility layer for native Windows and Cygwin. See [fuse.h](inc/fuse/fuse.h).
* .NET layer for managed development. See [src/dotnet](src/dotnet).
* Signed drivers provided on every release. * Signed drivers provided on every release.
* Available under the [GPLv3](License.txt) license with a special exception for Free/Libre and Open Source Software. * Available under the [GPLv3](License.txt) license with a special exception for Free/Libre and Open Source Software.
@ -26,27 +76,29 @@ To learn more about WinFsp, please visit its website: http://www.secfs.net/winfs
## Project Organization ## Project Organization
WinFsp consists of a kernel mode FSD (File System Driver) and a user mode DLL (Dynamic Link Library). The FSD interfaces with NTOS (the Windows kernel) and handles all interactions necessary to present itself as a file system driver to NTOS. The DLL interfaces with the FSD and presents an easy to use API for creating user mode file systems.
The project source code is organized as follows: The project source code is organized as follows:
* `build/VStudio`: WinFsp solution and project files. * :file_folder: [build/VStudio](build/VStudio): WinFsp solution and project files.
* `doc`: The WinFsp design documents and additional documentation can be found here. * :file_folder: [doc](doc): The WinFsp design documents and additional documentation can be found here.
* `ext/tlib`: A small test library originally from the secfs (Secure Cloud File System) project. * :file_folder: [ext](ext): External dependencies.
* `ext/test`: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems. * :file_folder: [ext/tlib](ext/tlib): A small test library originally from the secfs (Secure Cloud File System) project.
* `inc/fuse`: Public headers for the FUSE compatibility layer. * :file_folder: ext/test: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
* `inc/winfsp`: Public headers for the WinFsp API. * :file_folder: [inc](inc): Public headers.
* `src/dll`: Source code to the WinFsp DLL. * :file_folder: [inc/fuse](inc/fuse): Public headers for the FUSE compatibility layer.
* `src/dll/fuse`: Source code to the FUSE compatibility layer. * :file_folder: [inc/fuse3](inc/fuse3): Public headers for the FUSE3 compatibility layer.
* `src/dotnet`: Source code to the .NET layer. * :file_folder: [inc/winfsp](inc/winfsp): Public headers for the WinFsp API.
* `src/fsptool`: Source code to fsptool command line utility. * :file_folder: [src](src): WinFsp source code.
* `src/launcher`: Source code to the launcher service and the launchctl utility. * :file_folder: [src/dll](src/dll): Source code to the WinFsp DLL.
* `src/sys`: Source code to the WinFsp FSD. * :file_folder: [src/dll/fuse](src/dll/fuse): Source code to the FUSE compatibility layer.
* `opt/cygfuse`: Source code for the Cygwin FUSE package. * :file_folder: [src/dll/fuse3](src/dll/fuse3): Source code to the FUSE3 compatibility layer.
* `tst/memfs*`: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet). * :file_folder: [src/dotnet](src/dotnet): Source code to the .NET layer.
* `tst/passthrough*`: Source code to additional example file systems. * :file_folder: [src/fsptool](src/fsptool): Source code to fsptool command line utility.
* `tst/winfsp-tests`: WinFsp test suite. * :file_folder: [src/launcher](src/launcher): Source code to the launcher service and the launchctl utility.
* `tools`: Various tools for building and testing WinFsp. * :file_folder: [src/sys](src/sys): Source code to the WinFsp FSD.
* :file_folder: [opt/cygfuse](opt/cygfuse): Source code to the FUSE for Cygwin package.
* :file_folder: [tst](tst): Source code to example file systems and test suites.
* :file_folder: [tst/winfsp-tests](tst/winfsp-tests): WinFsp test suite.
* :file_folder: [tools](tools): Various tools for building and testing WinFsp.
## Building and Running ## Building and Running

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN

View File

@ -188,10 +188,6 @@
Type="string" Type="string"
Name="CommandLine" Name="CommandLine"
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" /> Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
<RegistryValue
Type="string"
Name="RunAs"
Value="LocalService" />
<RegistryValue <RegistryValue
Type="string" Type="string"
Name="Security" Name="Security"
@ -218,10 +214,6 @@
Type="string" Type="string"
Name="CommandLine" Name="CommandLine"
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" /> Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
<RegistryValue
Type="string"
Name="RunAs"
Value="LocalService" />
<RegistryValue <RegistryValue
Type="string" Type="string"
Name="Security" Name="Security"
@ -248,10 +240,6 @@
Type="string" Type="string"
Name="CommandLine" Name="CommandLine"
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" /> Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
<RegistryValue
Type="string"
Name="RunAs"
Value="LocalService" />
<RegistryValue <RegistryValue
Type="string" Type="string"
Name="Security" Name="Security"
@ -272,6 +260,9 @@
<Component Id="C.winfsp.h"> <Component Id="C.winfsp.h">
<File Name="winfsp.h" KeyPath="yes" /> <File Name="winfsp.h" KeyPath="yes" />
</Component> </Component>
<Component Id="C.launch.h">
<File Name="launch.h" KeyPath="yes" />
</Component>
<!--Component Id="C.winfsp.hpp"> <!--Component Id="C.winfsp.hpp">
<File Name="winfsp.hpp" KeyPath="yes" /> <File Name="winfsp.hpp" KeyPath="yes" />
</Component--> </Component-->
@ -290,6 +281,20 @@
<File Name="winfsp_fuse.h" KeyPath="yes" /> <File Name="winfsp_fuse.h" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="INCDIR.fuse3" Name="fuse3">
<Component Id="C.fuse3.h">
<File Id="fuse3.h" Name="fuse.h" KeyPath="yes" />
</Component>
<Component Id="C.fuse3_common.h">
<File Id="fuse3_common.h" Name="fuse_common.h" KeyPath="yes" />
</Component>
<Component Id="C.fuse3_opt.h">
<File Id="fuse3_opt.h" Name="fuse_opt.h" KeyPath="yes" />
</Component>
<Component Id="C.winfsp_fuse3.h">
<File Id="winfsp_fuse3.h" Name="winfsp_fuse.h" KeyPath="yes" />
</Component>
</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.winfsp_x64.lib">
@ -318,17 +323,43 @@
KeyPath="yes" /> KeyPath="yes" />
<Condition>NOT VersionNT64</Condition> <Condition>NOT VersionNT64</Condition>
</Component> </Component>
<!-- On Win64 copy fuse3-x64.pc -->
<Component Id="C.fuse3_x64.pc" Guid="FE59E3BA-E5EA-4822-80B1-19A1DE6B62C7">
<File
Id="FILE.fuse3_x64.pc"
Name="fuse3.pc"
Source="..\build\$(var.Configuration)\fuse3-x64.pc"
KeyPath="yes" />
<Condition>VersionNT64</Condition>
</Component>
<!-- On Win32 copy fuse3-x86.pc -->
<Component Id="C.fuse3_x86.pc" Guid="176205D0-07EA-4DFC-947F-18E89ABDAFAB">
<File
Id="FILE.fuse3_x86.pc"
Name="fuse3.pc"
Source="..\build\$(var.Configuration)\fuse3-x86.pc"
KeyPath="yes" />
<Condition>NOT VersionNT64</Condition>
</Component>
</DirectoryRef> </DirectoryRef>
<DirectoryRef Id="OPTDIR"> <DirectoryRef Id="OPTDIR">
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist"> <Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
<Directory Id="OPTDIR.cygfuse.x64" Name="x64"> <Directory Id="OPTDIR.cygfuse.x64" Name="x64">
<Component Id="C.fuse.tar.xz.x64"> <Component Id="C.fuse.tar.xz.x64">
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-7.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-9.tar.xz" KeyPath="yes" />
</Component>
<Component Id="C.fuse3.tar.xz.x64">
<File Id="FILE.fuse3.tar.xz.x64" Name="fuse3-3.2-1.tar.xz" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="OPTDIR.cygfuse.x86" Name="x86"> <Directory Id="OPTDIR.cygfuse.x86" Name="x86">
<Component Id="C.fuse.tar.xz.x86"> <Component Id="C.fuse.tar.xz.x86">
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-7.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-9.tar.xz" KeyPath="yes" />
</Component>
<Component Id="C.fuse3.tar.xz.x86">
<File Id="FILE.fuse3.tar.xz.x86" Name="fuse3-3.2-1.tar.xz" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Component Id="C.fuse.install.sh"> <Component Id="C.fuse.install.sh">
@ -356,6 +387,20 @@
<File Id="FILE.memfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" /> <File Id="FILE.memfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="SMPDIR.airfs" Name="airfs">
<Component Id="C.airfs.cpp">
<File Name="airfs.cpp" KeyPath="yes" />
</Component>
<Component Id="C.airfs.sln">
<File Name="airfs.sln" KeyPath="yes" />
</Component>
<Component Id="C.airfs.vcxproj">
<File Name="airfs.vcxproj" KeyPath="yes" />
</Component>
<Component Id="C.airfs.vcxproj.filters">
<File Name="airfs.vcxproj.filters" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="SMPDIR.passthrough" Name="passthrough"> <Directory Id="SMPDIR.passthrough" Name="passthrough">
<Component Id="C.passthrough.c"> <Component Id="C.passthrough.c">
<File Name="passthrough.c" KeyPath="yes" /> <File Name="passthrough.c" KeyPath="yes" />
@ -410,6 +455,32 @@
<File Name="README.md" KeyPath="yes" /> <File Name="README.md" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Directory Id="SMPDIR.passthrough_fuse3" Name="passthrough-fuse3">
<Component Id="C.passthrough_fuse3.c">
<File Name="passthrough-fuse3.c" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.winposix.c">
<File Id="F.passthrough_fuse3.winposix.c" Name="winposix.c" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.winposix.h">
<File Id="F.passthrough_fuse3.winposix.h" Name="winposix.h" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.sln">
<File Name="passthrough-fuse3.sln" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.vcxproj">
<File Name="passthrough-fuse3.vcxproj" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.vcxproj.filters">
<File Name="passthrough-fuse3.vcxproj.filters" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.Makefile">
<File Id="F.passthrough_fuse3.Makefile" Name="Makefile" KeyPath="yes" />
</Component>
<Component Id="C.passthrough_fuse3.README.md">
<File Id="F.passthrough_fuse3.README.md" Name="README.md" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="SMPDIR.passthrough_dotnet" Name="passthrough-dotnet"> <Directory Id="SMPDIR.passthrough_dotnet" Name="passthrough-dotnet">
<Component Id="C.passthrough_dotnet.Program.cs"> <Component Id="C.passthrough_dotnet.Program.cs">
<File Id="FILE.passthrough_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" /> <File Id="FILE.passthrough_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
@ -482,21 +553,30 @@
<ComponentGroup Id="C.WinFsp.inc"> <ComponentGroup Id="C.WinFsp.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.winfsp.hpp" /--> <!--ComponentRef Id="C.winfsp.hpp" /-->
<ComponentRef Id="C.fuse.h" /> <ComponentRef Id="C.fuse.h" />
<ComponentRef Id="C.fuse_common.h" /> <ComponentRef Id="C.fuse_common.h" />
<ComponentRef Id="C.fuse_opt.h" /> <ComponentRef Id="C.fuse_opt.h" />
<ComponentRef Id="C.winfsp_fuse.h" /> <ComponentRef Id="C.winfsp_fuse.h" />
<ComponentRef Id="C.fuse3.h" />
<ComponentRef Id="C.fuse3_common.h" />
<ComponentRef Id="C.fuse3_opt.h" />
<ComponentRef Id="C.winfsp_fuse3.h" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.lib"> <ComponentGroup Id="C.WinFsp.lib">
<ComponentRef Id="C.winfsp_x64.lib" /> <ComponentRef Id="C.winfsp_x64.lib" />
<ComponentRef Id="C.winfsp_x86.lib" /> <ComponentRef Id="C.winfsp_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_x86.pc" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.opt.fuse"> <ComponentGroup Id="C.WinFsp.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.x86" />
<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>
@ -506,6 +586,10 @@
<ComponentRef Id="C.memfs.h" /> <ComponentRef Id="C.memfs.h" />
<ComponentRef Id="C.memfs.cpp" /> <ComponentRef Id="C.memfs.cpp" />
<ComponentRef Id="C.memfs_main.c" /> <ComponentRef Id="C.memfs_main.c" />
<ComponentRef Id="C.airfs.cpp" />
<ComponentRef Id="C.airfs.sln" />
<ComponentRef Id="C.airfs.vcxproj" />
<ComponentRef Id="C.airfs.vcxproj.filters" />
<ComponentRef Id="C.passthrough.c" /> <ComponentRef Id="C.passthrough.c" />
<ComponentRef Id="C.passthrough.sln" /> <ComponentRef Id="C.passthrough.sln" />
<ComponentRef Id="C.passthrough.vcxproj" /> <ComponentRef Id="C.passthrough.vcxproj" />
@ -522,6 +606,14 @@
<ComponentRef Id="C.passthrough_fuse.vcxproj.filters" /> <ComponentRef Id="C.passthrough_fuse.vcxproj.filters" />
<ComponentRef Id="C.passthrough_fuse.Makefile" /> <ComponentRef Id="C.passthrough_fuse.Makefile" />
<ComponentRef Id="C.passthrough_fuse.README.md" /> <ComponentRef Id="C.passthrough_fuse.README.md" />
<ComponentRef Id="C.passthrough_fuse3.c" />
<ComponentRef Id="C.passthrough_fuse3.winposix.c" />
<ComponentRef Id="C.passthrough_fuse3.winposix.h" />
<ComponentRef Id="C.passthrough_fuse3.sln" />
<ComponentRef Id="C.passthrough_fuse3.vcxproj" />
<ComponentRef Id="C.passthrough_fuse3.vcxproj.filters" />
<ComponentRef Id="C.passthrough_fuse3.Makefile" />
<ComponentRef Id="C.passthrough_fuse3.README.md" />
</ComponentGroup> </ComponentGroup>
<ComponentGroup Id="C.WinFsp.sym"> <ComponentGroup Id="C.WinFsp.sym">
<ComponentRef Id="C.winfsp_x64.sys.pdb" /> <ComponentRef Id="C.winfsp_x64.sys.pdb" />

View File

@ -182,12 +182,14 @@
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\tst\memfs\memfs.cpp" /> <ClCompile Include="..\..\..\tst\memfs\memfs.cpp" />
<ClCompile Include="..\..\..\tst\winfsp-tests\create-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\create-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\devctl-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\dirbuf-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\dirbuf-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\dirctl-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\dirctl-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\eventlog-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\eventlog-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\exec-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\exec-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\flush-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\flush-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\fuse-opt-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\fuse-opt-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\fuse-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" />

View File

@ -88,6 +88,12 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c"> <ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\devctl-test.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\fuse-test.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\ext\tlib\testsuite.h"> <ClInclude Include="..\..\..\ext\tlib\testsuite.h">

View File

@ -16,10 +16,10 @@
<MyCompanyName>Navimatics Corporation</MyCompanyName> <MyCompanyName>Navimatics Corporation</MyCompanyName>
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright> <MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
<MyCanonicalVersion>1.3</MyCanonicalVersion> <MyCanonicalVersion>1.4</MyCanonicalVersion>
<MyProductVersion>2018.1 B2</MyProductVersion> <MyProductVersion>2019.2</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Gold</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas> <MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>

View File

@ -20,6 +20,10 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\fuse3\fuse.h" />
<ClInclude Include="..\..\inc\fuse3\fuse_common.h" />
<ClInclude Include="..\..\inc\fuse3\fuse_opt.h" />
<ClInclude Include="..\..\inc\fuse3\winfsp_fuse.h" />
<ClInclude Include="..\..\inc\fuse\fuse.h" /> <ClInclude Include="..\..\inc\fuse\fuse.h" />
<ClInclude Include="..\..\inc\fuse\fuse_common.h" /> <ClInclude Include="..\..\inc\fuse\fuse_common.h" />
<ClInclude Include="..\..\inc\fuse\fuse_opt.h" /> <ClInclude Include="..\..\inc\fuse\fuse_opt.h" />
@ -28,6 +32,7 @@
<ClInclude Include="..\..\inc\winfsp\launch.h" /> <ClInclude Include="..\..\inc\winfsp\launch.h" />
<ClInclude Include="..\..\inc\winfsp\winfsp.h" /> <ClInclude Include="..\..\inc\winfsp\winfsp.h" />
<ClInclude Include="..\..\inc\winfsp\winfsp.hpp" /> <ClInclude Include="..\..\inc\winfsp\winfsp.hpp" />
<ClInclude Include="..\..\src\dll\fuse3\library.h" />
<ClInclude Include="..\..\src\dll\fuse\library.h" /> <ClInclude Include="..\..\src\dll\fuse\library.h" />
<ClInclude Include="..\..\src\dll\library.h" /> <ClInclude Include="..\..\src\dll\library.h" />
<ClInclude Include="..\..\src\shared\minimal.h" /> <ClInclude Include="..\..\src\shared\minimal.h" />
@ -35,9 +40,13 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\dll\dirbuf.c" /> <ClCompile Include="..\..\src\dll\dirbuf.c" />
<ClCompile Include="..\..\src\dll\eventlog.c" /> <ClCompile Include="..\..\src\dll\eventlog.c" />
<ClCompile Include="..\..\src\dll\fuse3\fuse2to3.c" />
<ClCompile Include="..\..\src\dll\fuse3\fuse3.c" />
<ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_compat.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_compat.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_intf.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_intf.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_loop.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_main.c" />
<ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" />
<ClCompile Include="..\..\src\dll\launch.c" /> <ClCompile Include="..\..\src\dll\launch.c" />
@ -79,6 +88,29 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)fuse-$(PlatformTarget).pc</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)fuse-$(PlatformTarget).pc</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects>
</CustomBuild> </CustomBuild>
<CustomBuild Include="..\..\src\dll\fuse3\fuse3.pc.in">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">echo arch=$(PlatformTarget) &gt;$(OutDir)fuse3-$(PlatformTarget).pc
copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(PlatformTarget).pc &gt;nul</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo arch=$(PlatformTarget) &gt;$(OutDir)fuse3-$(PlatformTarget).pc
copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(PlatformTarget).pc &gt;nul</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">echo arch=$(PlatformTarget) &gt;$(OutDir)fuse3-$(PlatformTarget).pc
copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(PlatformTarget).pc &gt;nul</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">echo arch=$(PlatformTarget) &gt;$(OutDir)fuse3-$(PlatformTarget).pc
copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(PlatformTarget).pc &gt;nul</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing fuse3-$(PlatformTarget).pc</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Writing fuse3-$(PlatformTarget).pc</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Writing fuse3-$(PlatformTarget).pc</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Writing fuse3-$(PlatformTarget).pc</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)fuse3-$(PlatformTarget).pc</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)fuse3-$(PlatformTarget).pc</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)fuse3-$(PlatformTarget).pc</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)fuse3-$(PlatformTarget).pc</Outputs>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects>
</CustomBuild>
<None Include="..\..\src\dll\library.def" /> <None Include="..\..\src\dll\library.def" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -190,7 +222,7 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile> <ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;version.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -218,7 +250,7 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile> <ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;version.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -249,7 +281,7 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile> <ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;version.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -280,7 +312,7 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile> <ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;version.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@ -21,6 +21,12 @@
<Filter Include="Source\fuse"> <Filter Include="Source\fuse">
<UniqueIdentifier>{518cce17-85cd-489c-b4be-920a84c1d73c}</UniqueIdentifier> <UniqueIdentifier>{518cce17-85cd-489c-b4be-920a84c1d73c}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Include\fuse3">
<UniqueIdentifier>{12afd2f1-f5ec-4008-b6ef-89cc626019ea}</UniqueIdentifier>
</Filter>
<Filter Include="Source\fuse3">
<UniqueIdentifier>{96091a7b-3923-4a74-9491-3ee230c688f9}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">
@ -56,6 +62,21 @@
<ClInclude Include="..\..\inc\winfsp\launch.h"> <ClInclude Include="..\..\inc\winfsp\launch.h">
<Filter>Include\winfsp</Filter> <Filter>Include\winfsp</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\inc\fuse3\fuse.h">
<Filter>Include\fuse3</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\fuse3\fuse_common.h">
<Filter>Include\fuse3</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\fuse3\fuse_opt.h">
<Filter>Include\fuse3</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\fuse3\winfsp_fuse.h">
<Filter>Include\fuse3</Filter>
</ClInclude>
<ClInclude Include="..\..\src\dll\fuse3\library.h">
<Filter>Source\fuse3</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\dll\library.c"> <ClCompile Include="..\..\src\dll\library.c">
@ -121,6 +142,18 @@
<ClCompile Include="..\..\src\dll\launch.c"> <ClCompile Include="..\..\src\dll\launch.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\fuse3\fuse3.c">
<Filter>Source\fuse3</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\fuse3\fuse2to3.c">
<Filter>Source\fuse3</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\fuse\fuse_loop.c">
<Filter>Source\fuse</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c">
<Filter>Source\fuse3</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\src\dll\library.def"> <None Include="..\..\src\dll\library.def">
@ -139,5 +172,8 @@
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in"> <CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
<Filter>Source\fuse</Filter> <Filter>Source\fuse</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="..\..\src\dll\fuse3\fuse3.pc.in">
<Filter>Source\fuse3</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -6,8 +6,8 @@
I am running Windows 7 and I am finding that the installed driver is not signed.:: I am running Windows 7 and I am finding that the installed driver is not signed.::
Your Windows 7 OS is missing SHA-2 Code Signing Support. You need to install the following security advisory that will rectify the problem: Your Windows 7 OS is missing SHA-2 Code Signing Support. You need to install the following security advisory that will rectify the problem:
https://technet.microsoft.com/en-us/library/security/3033929.aspx https://technet.microsoft.com/en-us/library/security/3033929.aspx
Disconnecting (unmapping) a network drive does not work.:: Disconnecting (unmapping) a network drive does not work.::
@ -17,7 +17,9 @@ Disconnecting (unmapping) a network drive does not work.::
Case-sensitive file systems do not work properly when mounted as a directory.:: Case-sensitive file systems do not work properly when mounted as a directory.::
Windows and WinFsp support case-sensitive file systems. These file systems work properly when mounted as a drive. Unfortunately when a file system is mounted as a directory over NTFS, Windows expects it to be case-insensitive and will UPPERCASE many of the file names sent to the file system. This is fixed as of WinFsp 2018.2 B3.
+
Windows and WinFsp support case-sensitive file systems. These file systems work properly when mounted as a drive. Unfortunately when a file system is mounted as a directory over NTFS, Windows expects it to be case-insensitive and will UPPERCASE many of the file names sent to the file system.
+ +
This is an unfortunate but well understood Windows limitation. Case-sensitive file systems should only be mounted as drives. This is an unfortunate but well understood Windows limitation. Case-sensitive file systems should only be mounted as drives.
@ -47,7 +49,7 @@ As of the commits required to fix issue #55, there is however a hash table insid
Which version of FUSE does WinFsp-FUSE support?:: Which version of FUSE does WinFsp-FUSE support?::
Currently it supports FUSE 2.8. It supports both the FUSE 2.8 and FUSE 3.2 API's. For the FUSE 2.8 API include `<fuse/fuse.h>`. For the FUSE 3.2 API include `<fuse3/fuse.h>`.
FUSE on UNIX systems mounts file systems over an existing directory. When mounting a WinFsp-FUSE file system on a directory, the directory is created and later deleted when the file system goes away. What is the reason for this incompatibility?:: FUSE on UNIX systems mounts file systems over an existing directory. When mounting a WinFsp-FUSE file system on a directory, the directory is created and later deleted when the file system goes away. What is the reason for this incompatibility?::
@ -65,8 +67,6 @@ With this in mind here are the reasons for the current WinFsp-FUSE behavior:
WinFsp-FUSE does not have the ability to support multiple file systems from within the same process. Why?:: WinFsp-FUSE does not have the ability to support multiple file systems from within the same process. Why?::
The core WinFsp layer supports multiple file systems in the same process either simultaneously or one after another. However this is not the case with WinFsp-FUSE (i.e. the FUSE layer of WinFsp). This is supported as of WinFsp 2018.2 B2.
+ +
File systems in Windows often need to be run as services. For this reason the WinFsp-FUSE layer provides both file system and Windows service API functionality. This way a WinFsp-FUSE file system can easily become a Windows service. There is a problem: once a Windows process starts acting as a service and then stops being a service, it cannot become a service again. The core WinFsp layer always supported multiple file systems in the same process either simultaneously or one after another. However this was not the case with WinFsp-FUSE (i.e. the FUSE layer of WinFsp) prior to version 2018.2 B2. This limitation has been rectified as of WinFsp 2018.2 B2.
+
Having FUSE file systems being able to act as Windows services is valuable. Therefore this is not a limitation that can easily be fixed as FUSE file systems would lose the "free" ability to act as Windows services.

View File

@ -4,6 +4,7 @@ This document contains a list of known file systems and file system libraries th
== File Systems == File Systems
- https://github.com/vgough/encfs[EncFS] - an Encrypted Filesystem for FUSE
- https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files - https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files
- https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive - https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows - https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows

View File

@ -178,6 +178,43 @@ VOID ( *Close)(
- _FileContext_ - The file context of the file or directory to be closed. - _FileContext_ - The file context of the file or directory to be closed.
*Control* - Process control code.
[source,c]
----
NTSTATUS ( *Control)(
FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext,
UINT32 ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG PBytesTransferred);
----
*Parameters*
- _FileSystem_ - The file system on which this request is posted.
- _FileContext_ - The file context of the file or directory to be controled.
- _ControlCode_ - The control code for the operation. This code must have a DeviceType with bit
0x8000 set and must have a TransferType of METHOD$$_$$BUFFERED.
- _InputBuffer_ - Pointer to a buffer that contains the input data.
- _InputBufferLength_ - Input data length.
- _OutputBuffer_ - Pointer to a buffer that will receive the output data.
- _OutputBufferLength_ - Output data length.
- _PBytesTransferred_ - [out]
Pointer to a memory location that will receive the actual number of bytes transferred.
*Return Value*
STATUS$$_$$SUCCESS or error code.
*Discussion*
This function is called when a program uses the DeviceIoControl API.
*Create* - Create new file or directory. *Create* - Create new file or directory.
[source,c] [source,c]

View File

@ -1,2 +1,2 @@
Taken from secfs.core/src/tlib codebase: Taken from secfs.core/src/tlib codebase:
commit 16296d2ac64a7d532b1c486dd3c44af5865d4851 commit 16296d2ac64a7d532b1c486dd3c44af5865d4851

View File

@ -15,9 +15,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef FUSE_H_ #ifndef FUSE_H_
@ -87,7 +91,7 @@ struct fuse_operations
/* _ */ unsigned int flag_nopath:1; /* _ */ unsigned int flag_nopath:1;
/* _ */ unsigned int flag_utime_omit_ok:1; /* _ */ unsigned int flag_utime_omit_ok:1;
/* _ */ unsigned int flag_reserved:29; /* _ */ unsigned int flag_reserved:29;
/* _ */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi, /* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
unsigned int flags, void *data); unsigned int flags, void *data);
/* _ */ int (*poll)(const char *path, struct fuse_file_info *fi, /* _ */ int (*poll)(const char *path, struct fuse_file_info *fi,
struct fuse_pollhandle *ph, unsigned *reventsp); struct fuse_pollhandle *ph, unsigned *reventsp);

View File

@ -15,9 +15,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef FUSE_COMMON_H_ #ifndef FUSE_COMMON_H_

View File

@ -15,9 +15,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef FUSE_OPT_H_ #ifndef FUSE_OPT_H_
@ -41,16 +45,16 @@ extern "C" {
struct fuse_opt struct fuse_opt
{ {
const char *templ; const char *templ;
unsigned int offset; unsigned int offset;
int value; int value;
}; };
struct fuse_args struct fuse_args
{ {
int argc; int argc;
char **argv; char **argv;
int allocated; int allocated;
}; };
typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key, typedef int (*fuse_opt_proc_t)(void *data, const char *arg, int key,

View File

@ -11,9 +11,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef FUSE_WINFSP_FUSE_H_INCLUDED #ifndef FUSE_WINFSP_FUSE_H_INCLUDED
@ -53,6 +57,17 @@ extern "C" {
#endif #endif
#endif #endif
#define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */
#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\
(FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2)
#define FSP_FUSE_IOCTL(cmd, isiz, osiz) \
( \
(((osiz) != 0) << 31) | \
(((isiz) != 0) << 30) | \
(((isiz) | (osiz)) << 16) | \
(cmd) \
)
/* /*
* FUSE uses a number of types (notably: struct stat) that are OS specific. * FUSE uses a number of types (notably: struct stat) that are OS specific.
* Furthermore there are sometimes multiple definitions of the same type even * Furthermore there are sometimes multiple definitions of the same type even
@ -389,7 +404,7 @@ static inline int fsp_fuse_set_signal_handlers(void *se)
static inline char *fsp_fuse_conv_to_win_path(const char *path) static inline char *fsp_fuse_conv_to_win_path(const char *path)
{ {
void *cygwin_create_path(unsigned, const void *); void *cygwin_create_path(unsigned, const void *);
return cygwin_create_path( return (char *)cygwin_create_path(
0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/, 0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/,
path); path);
} }

338
inc/fuse3/fuse.h Normal file
View File

@ -0,0 +1,338 @@
/**
* @file fuse3/fuse.h
* WinFsp FUSE3 compatible API.
*
* This file is derived from libfuse/include/fuse.h:
* FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef FUSE_H_
#define FUSE_H_
#include "fuse_common.h"
#ifdef __cplusplus
extern "C" {
#endif
struct fuse3;
enum fuse3_readdir_flags
{
FUSE_READDIR_PLUS = (1 << 0),
};
enum fuse3_fill_dir_flags
{
FUSE_FILL_DIR_PLUS = (1 << 1),
};
typedef int (*fuse3_fill_dir_t)(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off,
enum fuse3_fill_dir_flags flags);
struct fuse3_config
{
int set_gid;
unsigned int gid;
int set_uid;
unsigned int uid;
int set_mode;
unsigned int umask;
double entry_timeout;
double negative_timeout;
double attr_timeout;
int intr;
int intr_signal;
int remember;
int hard_remove;
int use_ino;
int readdir_ino;
int direct_io;
int kernel_cache;
int auto_cache;
int ac_attr_timeout_set;
double ac_attr_timeout;
int nullpath_ok;
/* private */
int show_help;
char *modules;
int debug;
};
struct fuse3_operations
{
/* S - supported by WinFsp */
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf,
struct fuse3_file_info *fi);
/* S */ int (*readlink)(const char *path, char *buf, size_t size);
/* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
/* S */ int (*mkdir)(const char *path, fuse_mode_t mode);
/* S */ int (*unlink)(const char *path);
/* S */ int (*rmdir)(const char *path);
/* S */ int (*symlink)(const char *dstpath, const char *srcpath);
/* S */ int (*rename)(const char *oldpath, const char *newpath, unsigned int flags);
/* _ */ int (*link)(const char *srcpath, const char *dstpath);
/* S */ int (*chmod)(const char *path, fuse_mode_t mode,
struct fuse3_file_info *fi);
/* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid,
struct fuse3_file_info *fi);
/* S */ int (*truncate)(const char *path, fuse_off_t size,
struct fuse3_file_info *fi);
/* S */ int (*open)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
struct fuse3_file_info *fi);
/* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
struct fuse3_file_info *fi);
/* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
/* S */ int (*flush)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*release)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*fsync)(const char *path, int datasync, struct fuse3_file_info *fi);
/* _ */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
int flags);
/* _ */ int (*getxattr)(const char *path, const char *name, char *value, size_t size);
/* _ */ int (*listxattr)(const char *path, char *namebuf, size_t size);
/* _ */ int (*removexattr)(const char *path, const char *name);
/* S */ int (*opendir)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*readdir)(const char *path, void *buf, fuse3_fill_dir_t filler, fuse_off_t off,
struct fuse3_file_info *fi, enum fuse3_readdir_flags);
/* S */ int (*releasedir)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse3_file_info *fi);
/* S */ void *(*init)(struct fuse3_conn_info *conn,
struct fuse3_config *conf);
/* S */ void (*destroy)(void *data);
/* _ */ int (*access)(const char *path, int mask);
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse3_file_info *fi);
/* _ */ int (*lock)(const char *path,
struct fuse3_file_info *fi, int cmd, struct fuse_flock *lock);
/* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2],
struct fuse3_file_info *fi);
/* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
/* S */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse3_file_info *fi,
unsigned int flags, void *data);
/* _ */ int (*poll)(const char *path, struct fuse3_file_info *fi,
struct fuse3_pollhandle *ph, unsigned *reventsp);
/* _ */ int (*write_buf)(const char *path,
struct fuse3_bufvec *buf, fuse_off_t off, struct fuse3_file_info *fi);
/* _ */ int (*read_buf)(const char *path,
struct fuse3_bufvec **bufp, size_t size, fuse_off_t off, struct fuse3_file_info *fi);
/* _ */ int (*flock)(const char *path, struct fuse3_file_info *, int op);
/* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len,
struct fuse3_file_info *fi);
};
struct fuse3_context
{
struct fuse3 *fuse;
fuse_uid_t uid;
fuse_gid_t gid;
fuse_pid_t pid;
void *private_data;
fuse_mode_t umask;
};
#define fuse_main(argc, argv, ops, data)\
fuse3_main_real(argc, argv, ops, sizeof *(ops), data)
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_main_real)(struct fsp_fuse_env *env,
int argc, char *argv[],
const struct fuse3_operations *ops, size_t opsize, void *data);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_lib_help)(struct fsp_fuse_env *env,
struct fuse_args *args);
FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new_30)(struct fsp_fuse_env *env,
struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data);
FSP_FUSE_API struct fuse3 *FSP_FUSE_API_NAME(fsp_fuse3_new)(struct fsp_fuse_env *env,
struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_destroy)(struct fsp_fuse_env *env,
struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_mount)(struct fsp_fuse_env *env,
struct fuse3 *f, const char *mountpoint);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_unmount)(struct fsp_fuse_env *env,
struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop)(struct fsp_fuse_env *env,
struct fuse3 *f);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt_31)(struct fsp_fuse_env *env,
struct fuse3 *f, int clone_fd);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_loop_mt)(struct fsp_fuse_env *env,
struct fuse3 *f, struct fuse3_loop_config *config);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_exit)(struct fsp_fuse_env *env,
struct fuse3 *f);
FSP_FUSE_API struct fuse3_context *FSP_FUSE_API_NAME(fsp_fuse3_get_context)(struct fsp_fuse_env *env);
FSP_FUSE_SYM(
int fuse3_main_real(int argc, char *argv[],
const struct fuse3_operations *ops, size_t opsize, void *data),
{
return FSP_FUSE_API_CALL(fsp_fuse3_main_real)
(fsp_fuse_env(), argc, argv, ops, opsize, data);
})
FSP_FUSE_SYM(
void fuse3_lib_help(struct fuse_args *args),
{
FSP_FUSE_API_CALL(fsp_fuse3_lib_help)
(fsp_fuse_env(), args);
})
#if FUSE_USE_VERSION == 30
FSP_FUSE_SYM(
struct fuse3 *fuse3_new_30(struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data),
{
return FSP_FUSE_API_CALL(fsp_fuse3_new_30)
(fsp_fuse_env(), args, ops, opsize, data);
})
#define fuse_new(args, op, size, data)\
fuse3_new_30(args, op, size, data)
#else
FSP_FUSE_SYM(
struct fuse3 *fuse3_new(struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data),
{
return FSP_FUSE_API_CALL(fsp_fuse3_new)
(fsp_fuse_env(), args, ops, opsize, data);
})
#endif
FSP_FUSE_SYM(
void fuse3_destroy(struct fuse3 *f),
{
FSP_FUSE_API_CALL(fsp_fuse3_destroy)
(fsp_fuse_env(), f);
})
FSP_FUSE_SYM(
int fuse3_mount(struct fuse3 *f, const char *mountpoint),
{
return FSP_FUSE_API_CALL(fsp_fuse3_mount)
(fsp_fuse_env(), f, mountpoint);
})
FSP_FUSE_SYM(
void fuse3_unmount(struct fuse3 *f),
{
FSP_FUSE_API_CALL(fsp_fuse3_unmount)
(fsp_fuse_env(), f);
})
FSP_FUSE_SYM(
int fuse3_loop(struct fuse3 *f),
{
return FSP_FUSE_API_CALL(fsp_fuse3_loop)
(fsp_fuse_env(), f);
})
#if FUSE_USE_VERSION < 32
FSP_FUSE_SYM(
int fuse3_loop_mt_31(struct fuse3 *f, int clone_fd),
{
return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt_31)
(fsp_fuse_env(), f, clone_fd);
})
#define fuse_loop_mt(f, clone_fd)\
fuse3_loop_mt_31(f, clone_fd)
#else
FSP_FUSE_SYM(
int fuse3_loop_mt(struct fuse3 *f, struct fuse3_loop_config *config),
{
return FSP_FUSE_API_CALL(fsp_fuse3_loop_mt)
(fsp_fuse_env(), f, config);
})
#endif
FSP_FUSE_SYM(
void fuse3_exit(struct fuse3 *f),
{
FSP_FUSE_API_CALL(fsp_fuse3_exit)
(fsp_fuse_env(), f);
})
FSP_FUSE_SYM(
struct fuse3_context *fuse3_get_context(void),
{
return FSP_FUSE_API_CALL(fsp_fuse3_get_context)
(fsp_fuse_env());
})
FSP_FUSE_SYM(
int fuse3_getgroups(int size, fuse_gid_t list[]),
{
(void)size;
(void)list;
return -ENOSYS;
})
FSP_FUSE_SYM(
int fuse3_interrupted(void),
{
return 0;
})
FSP_FUSE_SYM(
int fuse3_invalidate_path(struct fuse3 *f, const char *path),
{
(void)f;
(void)path;
return -ENOENT;
})
FSP_FUSE_SYM(
int fuse3_notify_poll(struct fuse3_pollhandle *ph),
{
(void)ph;
return 0;
})
FSP_FUSE_SYM(
int fuse3_start_cleanup_thread(struct fuse3 *f),
{
(void)f;
return 0;
})
FSP_FUSE_SYM(
void fuse3_stop_cleanup_thread(struct fuse3 *f),
{
(void)f;
})
FSP_FUSE_SYM(
int fuse3_clean_cache(struct fuse3 *f),
{
(void)f;
return 600;
})
FSP_FUSE_SYM(
struct fuse3_session *fuse3_get_session(struct fuse3 *f),
{
return (struct fuse3_session *)f;
})
#ifdef __cplusplus
}
#endif
#endif

238
inc/fuse3/fuse_common.h Normal file
View File

@ -0,0 +1,238 @@
/**
* @file fuse3/fuse_common.h
* WinFsp FUSE3 compatible API.
*
* This file is derived from libfuse/include/fuse_common.h:
* FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef FUSE_COMMON_H_
#define FUSE_COMMON_H_
#include "winfsp_fuse.h"
#if !defined(WINFSP_DLL_INTERNAL)
#include "fuse_opt.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define FUSE_MAJOR_VERSION 3
#define FUSE_MINOR_VERSION 2
#define FUSE_MAKE_VERSION(maj, min) ((maj) * 10 + (min))
#define FUSE_VERSION FUSE_MAKE_VERSION(FUSE_MAJOR_VERSION, FUSE_MINOR_VERSION)
#define FUSE_CAP_ASYNC_READ (1 << 0)
#define FUSE_CAP_POSIX_LOCKS (1 << 1)
#define FUSE_CAP_ATOMIC_O_TRUNC (1 << 3)
#define FUSE_CAP_EXPORT_SUPPORT (1 << 4)
#define FUSE_CAP_DONT_MASK (1 << 6)
#define FUSE_CAP_SPLICE_WRITE (1 << 7)
#define FUSE_CAP_SPLICE_MOVE (1 << 8)
#define FUSE_CAP_SPLICE_READ (1 << 9)
#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
#define FUSE_CAP_IOCTL_DIR (1 << 11)
#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
#define FUSE_CAP_READDIRPLUS (1 << 13)
#define FUSE_CAP_READDIRPLUS_AUTO (1 << 14)
#define FUSE_CAP_ASYNC_DIO (1 << 15)
#define FUSE_CAP_WRITEBACK_CACHE (1 << 16)
#define FUSE_CAP_NO_OPEN_SUPPORT (1 << 17)
#define FUSE_CAP_PARALLEL_DIROPS (1 << 18)
#define FUSE_CAP_POSIX_ACL (1 << 19)
#define FUSE_CAP_HANDLE_KILLPRIV (1 << 20)
#define FUSE_CAP_ALLOCATE (1 << 27) /* reserved (OSXFUSE) */
#define FUSE_CAP_EXCHANGE_DATA (1 << 28) /* reserved (OSXFUSE) */
#define FUSE_CAP_CASE_INSENSITIVE (1 << 29) /* file system is case insensitive */
#define FUSE_CAP_VOL_RENAME (1 << 30) /* reserved (OSXFUSE) */
#define FUSE_CAP_XTIMES (1 << 31) /* reserved (OSXFUSE) */
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
#define FUSE_IOCTL_COMPAT (1 << 0)
#define FUSE_IOCTL_UNRESTRICTED (1 << 1)
#define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_DIR (1 << 4)
#define FUSE_IOCTL_MAX_IOV 256
#define FUSE_BUFVEC_INIT(s) \
((struct fuse3_bufvec){ 1, 0, 0, { {s, (enum fuse3_buf_flags)0, 0, -1, 0} } })
struct fuse3_file_info
{
int flags;
unsigned int writepage:1;
unsigned int direct_io:1;
unsigned int keep_cache:1;
unsigned int flush:1;
unsigned int nonseekable:1;
unsigned int flock_release:1;
unsigned int padding:27;
uint64_t fh;
uint64_t lock_owner;
uint32_t poll_events;
};
struct fuse3_loop_config
{
int clone_fd;
unsigned int max_idle_threads;
};
struct fuse3_conn_info
{
unsigned proto_major;
unsigned proto_minor;
unsigned max_write;
unsigned max_read;
unsigned max_readahead;
unsigned capable;
unsigned want;
unsigned max_background;
unsigned congestion_threshold;
unsigned time_gran;
unsigned reserved[22];
};
enum fuse3_buf_flags
{
FUSE_BUF_IS_FD = (1 << 1),
FUSE_BUF_FD_SEEK = (1 << 2),
FUSE_BUF_FD_RETRY = (1 << 3),
};
enum fuse3_buf_copy_flags
{
FUSE_BUF_NO_SPLICE = (1 << 1),
FUSE_BUF_FORCE_SPLICE = (1 << 2),
FUSE_BUF_SPLICE_MOVE = (1 << 3),
FUSE_BUF_SPLICE_NONBLOCK = (1 << 4),
};
struct fuse3_buf
{
size_t size;
enum fuse3_buf_flags flags;
void *mem;
int fd;
fuse_off_t pos;
};
struct fuse3_bufvec
{
size_t count;
size_t idx;
size_t off;
struct fuse3_buf buf[1];
};
struct fuse3_session;
struct fuse3_pollhandle;
struct fuse3_conn_info_opts;
FSP_FUSE_API struct fuse3_conn_info_opts *FSP_FUSE_API_NAME(fsp_fuse3_parse_conn_info_opts)(
struct fsp_fuse_env *env,
struct fuse_args *args);
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse3_apply_conn_info_opts)(struct fsp_fuse_env *env,
struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn);
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse3_version)(struct fsp_fuse_env *env);
FSP_FUSE_API const char *FSP_FUSE_API_NAME(fsp_fuse3_pkgversion)(struct fsp_fuse_env *env);
FSP_FUSE_API int32_t FSP_FUSE_API_NAME(fsp_fuse_ntstatus_from_errno)(struct fsp_fuse_env *env,
int err);
FSP_FUSE_SYM(
struct fuse3_conn_info_opts* fuse3_parse_conn_info_opts(
struct fuse_args *args),
{
return FSP_FUSE_API_CALL(fsp_fuse3_parse_conn_info_opts)
(fsp_fuse_env(), args);
})
FSP_FUSE_SYM(
void fuse3_apply_conn_info_opts(
struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn),
{
FSP_FUSE_API_CALL(fsp_fuse3_apply_conn_info_opts)
(fsp_fuse_env(), opts, conn);
})
FSP_FUSE_SYM(
int fuse3_version(void),
{
return FSP_FUSE_API_CALL(fsp_fuse3_version)
(fsp_fuse_env());
})
FSP_FUSE_SYM(
const char *fuse3_pkgversion(void),
{
return FSP_FUSE_API_CALL(fsp_fuse3_pkgversion)
(fsp_fuse_env());
})
FSP_FUSE_SYM(
void fuse3_pollhandle_destroy(struct fuse3_pollhandle *ph),
{
(void)ph;
})
FSP_FUSE_SYM(
size_t fuse3_buf_size(const struct fuse3_bufvec *bufv),
{
(void)bufv;
return 0;
})
FSP_FUSE_SYM(
ssize_t fuse3_buf_copy(struct fuse3_bufvec *dst, struct fuse3_bufvec *src,
enum fuse3_buf_copy_flags flags),
{
(void)dst;
(void)src;
(void)flags;
return 0;
})
FSP_FUSE_SYM(
int fuse3_daemonize(int foreground),
{
return fsp_fuse_daemonize(foreground);
})
FSP_FUSE_SYM(
int fuse3_set_signal_handlers(struct fuse3_session *se),
{
return fsp_fuse_set_signal_handlers(se);
})
FSP_FUSE_SYM(
void fuse3_remove_signal_handlers(struct fuse3_session *se),
{
(void)se;
fsp_fuse_set_signal_handlers(0);
})
#ifdef __cplusplus
}
#endif
#endif

23
inc/fuse3/fuse_opt.h Normal file
View File

@ -0,0 +1,23 @@
/**
* @file fuse3/fuse_opt.h
* WinFsp FUSE3 compatible API.
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include "../fuse/fuse_opt.h"

82
inc/fuse3/winfsp_fuse.h Normal file
View File

@ -0,0 +1,82 @@
/**
* @file fuse3/winfsp_fuse.h
* WinFsp FUSE3 compatible API.
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef FUSE3_WINFSP_FUSE_H_INCLUDED
#define FUSE3_WINFSP_FUSE_H_INCLUDED
#include "../fuse/winfsp_fuse.h"
#if defined(_WIN64) || defined(_WIN32)
typedef intptr_t ssize_t;
#endif
#if !defined(WINFSP_DLL_INTERNAL)
#define fuse3 fuse
#define fuse3_apply_conn_info_opts fuse_apply_conn_info_opts
#define fuse3_buf fuse_buf
#define fuse3_buf_copy fuse_buf_copy
#define fuse3_buf_copy_flags fuse_buf_copy_flags
#define fuse3_buf_flags fuse_buf_flags
#define fuse3_buf_size fuse_buf_size
#define fuse3_bufvec fuse_bufvec
#define fuse3_clean_cache fuse_clean_cache
#define fuse3_config fuse_config
#define fuse3_conn_info fuse_conn_info
#define fuse3_conn_info_opts fuse_conn_info_opts
#define fuse3_context fuse_context
#define fuse3_daemonize fuse_daemonize
#define fuse3_destroy fuse_destroy
#define fuse3_exit fuse_exit
#define fuse3_file_info fuse_file_info
#define fuse3_fill_dir_flags fuse_fill_dir_flags
#define fuse3_fill_dir_t fuse_fill_dir_t
#define fuse3_get_context fuse_get_context
#define fuse3_get_session fuse_get_session
#define fuse3_getgroups fuse_getgroups
#define fuse3_interrupted fuse_interrupted
#define fuse3_invalidate_path fuse_invalidate_path
#define fuse3_lib_help fuse_lib_help
#define fuse3_loop fuse_loop
#define fuse3_loop_config fuse_loop_config
#define fuse3_loop_mt fuse_loop_mt
#define fuse3_loop_mt_31 fuse_loop_mt_31
#define fuse3_main_real fuse_main_real
#define fuse3_mount fuse_mount
#define fuse3_new fuse_new
#define fuse3_new_30 fuse_new_30
#define fuse3_notify_poll fuse_notify_poll
#define fuse3_operations fuse_operations
#define fuse3_parse_conn_info_opts fuse_parse_conn_info_opts
#define fuse3_pkgversion fuse_pkgversion
#define fuse3_pollhandle fuse_pollhandle
#define fuse3_pollhandle_destroy fuse_pollhandle_destroy
#define fuse3_readdir_flags fuse_readdir_flags
#define fuse3_remove_signal_handlers fuse_remove_signal_handlers
#define fuse3_session fuse_session
#define fuse3_set_signal_handlers fuse_set_signal_handlers
#define fuse3_start_cleanup_thread fuse_start_cleanup_thread
#define fuse3_stop_cleanup_thread fuse_stop_cleanup_thread
#define fuse3_unmount fuse_unmount
#define fuse3_version fuse_version
#endif
#endif

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_FSCTL_H_INCLUDED #ifndef WINFSP_FSCTL_H_INCLUDED
@ -82,6 +86,8 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR),
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((T) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((T) & 0xffffffff))
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff))
#define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */
/* marshalling */ /* marshalling */
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4200) /* zero-sized array in struct/union */ #pragma warning(disable:4200) /* zero-sized array in struct/union */
@ -124,43 +130,66 @@ enum
FspFsctlIrpCapacityMaximum = 1000, FspFsctlIrpCapacityMaximum = 1000,
FspFsctlIrpCapacityDefault = 1000, FspFsctlIrpCapacityDefault = 1000,
}; };
#define FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN\
UINT16 Version; /* set to 0 or sizeof(FSP_FSCTL_VOLUME_PARAMS) */\
/* volume information */\
UINT16 SectorSize;\
UINT16 SectorsPerAllocationUnit;\
UINT16 MaxComponentLength; /* maximum file name component length (bytes) */\
UINT64 VolumeCreationTime;\
UINT32 VolumeSerialNumber;\
/* I/O timeouts, capacity, etc. */\
UINT32 TransactTimeout; /* FSP_FSCTL_TRANSACT timeout (millis; 1 sec - 10 sec) */\
UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\
UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\
UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\
/* FILE_FS_ATTRIBUTE_INFORMATION::FileSystemAttributes */\
UINT32 CaseSensitiveSearch:1; /* file system supports case-sensitive file names */\
UINT32 CasePreservedNames:1; /* file system preserves the case of file names */\
UINT32 UnicodeOnDisk:1; /* file system supports Unicode in file names */\
UINT32 PersistentAcls:1; /* file system preserves and enforces access control lists */\
UINT32 ReparsePoints:1; /* file system supports reparse points */\
UINT32 ReparsePointsAccessCheck:1; /* file system performs reparse point access checks */\
UINT32 NamedStreams:1; /* file system supports named streams */\
UINT32 HardLinks:1; /* unimplemented; set to 0 */\
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */\
UINT32 ReadOnlyVolume:1;\
/* kernel-mode flags */\
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */\
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */\
UINT32 AlwaysUseDoubleBuffering:1;\
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */\
UINT32 FlushAndPurgeOnCleanup:1; /* keeps file off "standby" list */\
UINT32 DeviceControl:1; /* support user-mode ioctl handling */\
/* user-mode flags */\
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */\
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */\
UINT32 UmReservedFlags:6;\
/* additional kernel-mode flags */\
UINT32 KmReservedFlags:8;\
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
/* additional fields; specify .Version == sizeof(FSP_FSCTL_VOLUME_PARAMS) */\
UINT32 VolumeInfoTimeoutValid:1; /* VolumeInfoTimeout field is valid */\
UINT32 DirInfoTimeoutValid:1; /* DirInfoTimeout field is valid */\
UINT32 SecurityTimeoutValid:1; /* SecurityTimeout field is valid*/\
UINT32 StreamInfoTimeoutValid:1; /* StreamInfoTimeout field is valid */\
UINT32 KmAdditionalReservedFlags:28;\
UINT32 VolumeInfoTimeout; /* volume info timeout (millis); overrides FileInfoTimeout */\
UINT32 DirInfoTimeout; /* dir info timeout (millis); overrides FileInfoTimeout */\
UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\
UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\
UINT32 Reserved32[3];\
UINT64 Reserved64[2];
typedef struct typedef struct
{ {
UINT16 Version; /* set to 0 */ FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN
/* volume information */ } FSP_FSCTL_VOLUME_PARAMS_V0;
UINT16 SectorSize; typedef struct
UINT16 SectorsPerAllocationUnit; {
UINT16 MaxComponentLength; /* maximum file name component length (bytes) */ FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN
UINT64 VolumeCreationTime; FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN
UINT32 VolumeSerialNumber;
/* I/O timeouts, capacity, etc. */
UINT32 TransactTimeout; /* FSP_FSCTL_TRANSACT timeout (millis; 1 sec - 10 sec) */
UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */
UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/
UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */
/* FILE_FS_ATTRIBUTE_INFORMATION::FileSystemAttributes */
UINT32 CaseSensitiveSearch:1; /* file system supports case-sensitive file names */
UINT32 CasePreservedNames:1; /* file system preserves the case of file names */
UINT32 UnicodeOnDisk:1; /* file system supports Unicode in file names */
UINT32 PersistentAcls:1; /* file system preserves and enforces access control lists */
UINT32 ReparsePoints:1; /* file system supports reparse points */
UINT32 ReparsePointsAccessCheck:1; /* file system performs reparse point access checks */
UINT32 NamedStreams:1; /* file system supports named streams */
UINT32 HardLinks:1; /* unimplemented; set to 0 */
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */
UINT32 ReadOnlyVolume:1;
/* kernel-mode flags */
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
UINT32 AlwaysUseDoubleBuffering:1;
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */
UINT32 KmReservedFlags:2;
/* user-mode flags */
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
UINT32 UmReservedFlags:14;
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
} FSP_FSCTL_VOLUME_PARAMS; } FSP_FSCTL_VOLUME_PARAMS;
typedef struct typedef struct
{ {
@ -360,6 +389,14 @@ typedef struct
UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */ UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */
} FileSystemControl; } FileSystemControl;
struct struct
{
UINT64 UserContext;
UINT64 UserContext2;
UINT32 IoControlCode;
FSP_FSCTL_TRANSACT_BUF Buffer;
UINT32 OutputLength;
} DeviceControl;
struct
{ {
UINT64 UserContext; UINT64 UserContext;
UINT64 UserContext2; UINT64 UserContext2;
@ -445,6 +482,10 @@ typedef struct
FSP_FSCTL_TRANSACT_BUF Buffer; FSP_FSCTL_TRANSACT_BUF Buffer;
} FileSystemControl; } FileSystemControl;
struct struct
{
FSP_FSCTL_TRANSACT_BUF Buffer;
} DeviceControl;
struct
{ {
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
} QuerySecurity; } QuerySecurity;

View File

@ -14,9 +14,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_LAUNCH_H_INCLUDED #ifndef WINFSP_LAUNCH_H_INCLUDED
@ -107,7 +111,43 @@ enum
*/ */
FSP_API NTSTATUS FspLaunchCallLauncherPipe( FSP_API NTSTATUS FspLaunchCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PULONG PLauncherError); PWSTR Buffer, PULONG PSize,
PULONG PLauncherError);
/**
* Call launcher pipe.
*
* This function is used to send a command to the launcher and receive a response.
*
* @param Command
* Launcher command to send. For example, the 'L' launcher command instructs
* the launcher to list all running service instances.
* @param Argc
* Command argument count. May be 0.
* @param Argv
* Command argument array. May be NULL.
* @param Argl
* Command argument length array. May be NULL. If this is NULL all command arguments
* are assumed to be NULL-terminated strings. It is also possible for specific arguments
* to be NULL-terminated; in this case pass -1 in the corresponding Argl position.
* @param Buffer
* Buffer that receives the command response. May be NULL.
* @param PSize
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it
* contains the number of bytes transferred. May be NULL.
* @param AllowImpersonation
* Allow caller to be impersonated by launcher.
* @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
* returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError.
*/
FSP_API NTSTATUS FspLaunchCallLauncherPipeEx(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation,
PULONG PLauncherError);
/** /**
* Start a service instance. * Start a service instance.
* *
@ -134,6 +174,35 @@ FSP_API NTSTATUS FspLaunchStart(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret, BOOLEAN HasSecret,
PULONG PLauncherError); PULONG PLauncherError);
/**
* Start a service instance.
*
* @param ClassName
* Class name of the service instance to start.
* @param InstanceName
* Instance name of the service instance to start.
* @param Argc
* Service instance argument count. May be 0.
* @param Argv
* Service instance argument array. May be NULL.
* @param HasSecret
* Whether the last argument in Argv is assumed to be a secret (e.g. password) or not.
* Secrets are passed to service instances through standard input rather than the command
* line.
* @param AllowImpersonation
* Allow caller to be impersonated by launcher.
* @param PLauncherError
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
* @return
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
* returns an error. Other status codes indicate a communication error. Launcher errors are
* reported through PLauncherError.
*/
FSP_API NTSTATUS FspLaunchStartEx(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret,
BOOLEAN AllowImpersonation,
PULONG PLauncherError);
/** /**
* Stop a service instance. * Stop a service instance.
* *
@ -217,10 +286,12 @@ typedef struct _FSP_LAUNCH_REG_RECORD
PWSTR WorkDirectory; PWSTR WorkDirectory;
PWSTR RunAs; PWSTR RunAs;
PWSTR Security; PWSTR Security;
PVOID Reserved0[6]; PWSTR AuthPackage;
PVOID Reserved0[5];
ULONG JobControl; ULONG JobControl;
ULONG Credentials; ULONG Credentials;
ULONG Reserved1[6]; ULONG AuthPackageId;
ULONG Reserved1[5];
UINT8 Buffer[]; UINT8 Buffer[];
} FSP_LAUNCH_REG_RECORD; } FSP_LAUNCH_REG_RECORD;
#pragma warning(pop) #pragma warning(pop)

View File

@ -14,9 +14,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_WINFSP_H_INCLUDED #ifndef WINFSP_WINFSP_H_INCLUDED
@ -380,6 +384,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* @see * @see
* Close * Close
* CanDelete * CanDelete
* SetDelete
*/ */
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem, VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, ULONG Flags); PVOID FileContext, PWSTR FileName, ULONG Flags);
@ -563,6 +568,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* 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.
* *
* NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However
* most file systems need only implement the CanDelete operation.
*
* @param FileSystem * @param FileSystem
* The file system on which this request is posted. * The file system on which this request is posted.
* @param FileContext * @param FileContext
@ -573,6 +581,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* STATUS_SUCCESS or error code. * STATUS_SUCCESS or error code.
* @see * @see
* Cleanup * Cleanup
* SetDelete
*/ */
NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName); PVOID FileContext, PWSTR FileName);
@ -822,12 +831,75 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, PVOID FileContext, PWSTR FileName,
FSP_FSCTL_DIR_INFO *DirInfo); FSP_FSCTL_DIR_INFO *DirInfo);
/**
* Process control code.
*
* This function is called when a program uses the DeviceIoControl API.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the file or directory to be controled.
* @param ControlCode
* The control code for the operation. This code must have a DeviceType with bit
* 0x8000 set and must have a TransferType of METHOD_BUFFERED.
* @param InputBuffer
* Pointer to a buffer that contains the input data.
* @param InputBufferLength
* Input data length.
* @param OutputBuffer
* Pointer to a buffer that will receive the output data.
* @param OutputBufferLength
* Output data length.
* @param PBytesTransferred [out]
* Pointer to a memory location that will receive the actual number of bytes transferred.
* @return
* STATUS_SUCCESS or error code.
*/
NTSTATUS (*Control)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, UINT32 ControlCode,
PVOID InputBuffer, ULONG InputBufferLength,
PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred);
/**
* Set the file delete flag.
*
* 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
* performs tasks such as check for empty directories, etc.
*
* This function should <b>NEVER</b> delete the file or directory in question. Deletion should
* happen during Cleanup with the FspCleanupDelete flag set.
*
* 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.
*
* NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However
* most file systems need only implement the CanDelete operation.
*
* @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 DeleteFile
* If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise
* it will not be deleted. It is legal to receive multiple SetDelete calls for the same
* file with different DeleteFile parameters.
* @return
* STATUS_SUCCESS or error code.
* @see
* Cleanup
* CanDelete
*/
NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile);
/* /*
* 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[39])(); NTSTATUS (*Reserved[37])();
} 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.");
@ -1141,6 +1213,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpDeviceControl(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
@ -1721,6 +1795,10 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, PULONG PBytesTransferred, ULONG Timeout,
PSID Sid); PSID Sid);
FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
PSID Sid);
FSP_API NTSTATUS FspVersion(PUINT32 PVersion); FSP_API NTSTATUS FspVersion(PUINT32 PVersion);
/* /*

View File

@ -11,9 +11,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_WINFSP_HPP_INCLUDED #ifndef WINFSP_WINFSP_HPP_INCLUDED

1
opt/cygfuse/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

View File

@ -1,30 +1,59 @@
Version = $(shell sed -n '/^VERSION=/s/VERSION=\(.*\)/\1/p' fuse.cygport) Arch = $(shell uname -m)
#Debug = -g Build = build
cygfuse-$(Version).dll libfuse-$(Version).dll.a fuse.pc: cygfuse.c fuse.pc.in .PHONY: usage
gcc $(Debug) -shared -o cygfuse-$(Version).dll -Wl,--out-implib=libfuse-$(Version).dll.a -I../../inc/fuse cygfuse.c usage:
[ -n "$(Debug)" ] || strip cygfuse-$(Version).dll @echo "make cygport|dist" 1>&2
sed "s/@Version@/$(Version)/g" fuse.pc.in > fuse.pc @exit 2
cygfuse-test.exe: cygfuse-test.c cygfuse-$(Version).dll libfuse-$(Version).dll.a .PHONY: cygport dist clean
gcc $(Debug) -o cygfuse-test.exe -I../../inc/fuse -DCYGFUSE cygfuse-test.c -L$(PWD) -lfuse-$(Version) cygport: clean cygport2 cygport3
dist: cygport dist2 dist3
clean:
rm -rf $(Build)
cygport: .PHONY: cygport2
git clean -dfx cygport2: $(Build)/winfsp-work-$(Arch).tar.gz
(\ cp fuse/fuse.cygport $(Build)/fuse.cygport
cd `git rev-parse --show-toplevel` &&\ CYGPORT_SRC_URI=winfsp-work-$(Arch).tar.gz CYGPORT_SRC_DIR=winfsp-work-$(Arch) \
Stash=`git stash create` &&\ cygport $(Build)/fuse.cygport download prep compile install package
git archive --prefix=winfsp-work/ --format=tar.gz $${Stash:-HEAD}\
> opt/cygfuse/winfsp-work.tar.gz\
)
CYGPORT_SRC_URI=winfsp-work.tar.gz CYGPORT_SRC_DIR=winfsp-work cygport fuse.cygport download prep compile install package
dist: cygport .PHONY: cygport3
case $(shell uname -m) in \ cygport3: $(Build)/winfsp-work-$(Arch).tar.gz
x86_64)\ cp fuse3/fuse3.cygport $(Build)/fuse3.cygport
CYGPORT_SRC_URI=winfsp-work-$(Arch).tar.gz CYGPORT_SRC_DIR=winfsp-work-$(Arch) \
cygport $(Build)/fuse3.cygport download prep compile install package
$(Build)/winfsp-work-$(Arch).tar.gz:
mkdir -p $(Build)
( \
cd `git rev-parse --show-toplevel` && \
Stash=`git stash create` && \
git archive --prefix=winfsp-work-$(Arch)/ --format=tar.gz $${Stash:-HEAD} \
) > $(Build)/winfsp-work-$(Arch).tar.gz
.PHONY: dist2
dist2: cygport2
case $(Arch) in \
x86_64) \
mkdir -p dist/x64 && \ mkdir -p dist/x64 && \
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\ rm -f dist/x64/fuse-*[0-9].tar.xz && \
*)\ cp build/fuse-*[0-9].$(Arch)/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;; \
i686) \
mkdir -p dist/x86 && \ mkdir -p dist/x86 && \
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\ rm -f dist/x86/fuse-*[0-9].tar.xz && \
cp build/fuse-*[0-9].$(Arch)/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;; \
esac
.PHONY: dist3
dist3: cygport3
case $(Arch) in \
x86_64) \
mkdir -p dist/x64 && \
rm -f dist/x64/fuse3-*[0-9].tar.xz && \
cp build/fuse3-*[0-9].$(Arch)/dist/fuse3/fuse3-*[0-9].tar.xz dist/x64 ;; \
i686) \
mkdir -p dist/x86 && \
rm -f dist/x86/fuse3-*[0-9].tar.xz && \
cp build/fuse3-*[0-9].$(Arch)/dist/fuse3/fuse3-*[0-9].tar.xz dist/x86 ;; \
esac esac

View File

@ -1,8 +1,16 @@
cd "$(dirname "$0")" cd "$(dirname "$0")"
case $(uname -m) in case $(uname -m) in
x86_64) x86_64)
tar -C/ -xaf x64/fuse-2.8-*.tar.xz ;; tar -C/ -xaf x64/fuse-*.tar.xz
tar -C/ -xaf x64/fuse3-*.tar.xz
;;
i686)
tar -C/ -xaf x86/fuse-*.tar.xz
tar -C/ -xaf x86/fuse3-*.tar.xz
;;
*) *)
tar -C/ -xaf x86/fuse-2.8-*.tar.xz ;; echo unsupported architecture 1>&2
exit 1
;;
esac esac
echo FUSE for Cygwin installed. echo FUSE for Cygwin installed.

View File

@ -1,8 +1,16 @@
cd "$(dirname "$0")" cd "$(dirname "$0")"
case $(uname -m) in case $(uname -m) in
x86_64) x86_64)
tar -taf x64/fuse-2.8-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f ;; tar -taf x64/fuse-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f
tar -taf x64/fuse3-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f
;;
i686)
tar -taf x86/fuse-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f
tar -taf x86/fuse3-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f
;;
*) *)
tar -taf x86/fuse-2.8-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f ;; echo unsupported architecture 1>&2
exit 1
;;
esac esac
echo FUSE for Cygwin uninstalled. echo FUSE for Cygwin uninstalled.

Binary file not shown.

BIN
opt/cygfuse/dist/x64/fuse-2.8-9.tar.xz vendored Normal file

Binary file not shown.

BIN
opt/cygfuse/dist/x64/fuse3-3.2-1.tar.xz vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
opt/cygfuse/dist/x86/fuse-2.8-9.tar.xz vendored Normal file

Binary file not shown.

BIN
opt/cygfuse/dist/x86/fuse3-3.2-1.tar.xz vendored Normal file

Binary file not shown.

29
opt/cygfuse/fuse/Makefile Normal file
View File

@ -0,0 +1,29 @@
Version = $(shell sed -n '/^VERSION=/s/VERSION=\(.*\)/\1/p' fuse.cygport)
Arch = $(shell uname -m)
Build = build/$(Arch)
#Debug = -g
.PHONY: build test
build: $(Build)/cygfuse-$(Version).dll $(Build)/fuse.pc
test: $(Build)/cygfuse-test.exe
$(Build)/cygfuse-$(Version).dll: cygfuse.c fuse.cygport
@mkdir -p $(Build)
gcc $(Debug) \
-shared -o $(Build)/cygfuse-$(Version).dll \
-Wl,--out-implib=$(Build)/libfuse-$(Version).dll.a \
-I../../../inc/fuse \
cygfuse.c
[ -n "$(Debug)" ] || strip $(Build)/cygfuse-$(Version).dll
$(Build)/fuse.pc: fuse.pc.in fuse.cygport
@mkdir -p $(Build)
sed "s/@Version@/$(Version)/g" fuse.pc.in > $(Build)/fuse.pc
$(Build)/cygfuse-test.exe: cygfuse-test.c $(Build)/cygfuse-$(Version).dll
@mkdir -p $(Build)
gcc $(Debug) \
-o $(Build)/cygfuse-test.exe \
-I../../../inc/fuse -DCYGFUSE \
cygfuse-test.c \
-L$(PWD)/$(Build) -lfuse-$(Version)

View File

@ -1,6 +1,6 @@
#include <fuse.h> #include <fuse.h>
int main() int main()
{ {
return !(FUSE_VERSION == fuse_version()); return !(FUSE_VERSION == fuse_version());
} }

View File

@ -1,5 +1,5 @@
/** /**
* @file cygfuse/cygfuse.c * @file fuse/cygfuse.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2018 Bill Zissimopoulos
*/ */
@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dlfcn.h> #include <dlfcn.h>

View File

@ -1,9 +1,9 @@
NAME="fuse" NAME="fuse"
VERSION=2.8 VERSION=2.8
RELEASE=7 RELEASE=9
CATEGORY="Utils" CATEGORY="Utils"
SUMMARY="WinFsp-FUSE compatibility layer" SUMMARY="WinFsp FUSE compatibility layer"
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin." DESCRIPTION="Enables FUSE file systems to be run on Cygwin."
HOMEPAGE="http://www.secfs.net/winfsp/" HOMEPAGE="http://www.secfs.net/winfsp/"
SRC_URI=${CYGPORT_SRC_URI:-"https://github.com/billziss-gh/winfsp/archive/master.tar.gz"} SRC_URI=${CYGPORT_SRC_URI:-"https://github.com/billziss-gh/winfsp/archive/master.tar.gz"}
@ -12,7 +12,7 @@ SRC_DIR=${CYGPORT_SRC_DIR:-winfsp-master}
src_compile() src_compile()
{ {
lndirs lndirs
cd ${B}/opt/cygfuse cd ${B}/opt/cygfuse/fuse
make make
} }
@ -25,7 +25,7 @@ src_install()
doinclude fuse_opt.h doinclude fuse_opt.h
doinclude winfsp_fuse.h doinclude winfsp_fuse.h
cd ${B}/opt/cygfuse cd ${B}/opt/cygfuse/fuse/build/$(ARCH)
dobin cygfuse-${VERSION}.dll dobin cygfuse-${VERSION}.dll
dolib libfuse-${VERSION}.dll.a dolib libfuse-${VERSION}.dll.a
dosym libfuse-${VERSION}.dll.a /usr/lib/libfuse.dll.a dosym libfuse-${VERSION}.dll.a /usr/lib/libfuse.dll.a

View File

@ -0,0 +1,29 @@
Version = $(shell sed -n '/^VERSION=/s/VERSION=\(.*\)/\1/p' fuse3.cygport)
Arch = $(shell uname -m)
Build = build/$(Arch)
#Debug = -g
.PHONY: build test
build: $(Build)/cygfuse-$(Version).dll $(Build)/fuse3.pc
test: $(Build)/cygfuse-test.exe
$(Build)/cygfuse-$(Version).dll: cygfuse.c fuse3.cygport
@mkdir -p $(Build)
gcc $(Debug) \
-shared -o $(Build)/cygfuse-$(Version).dll \
-Wl,--out-implib=$(Build)/libfuse-$(Version).dll.a \
-I../../../inc/fuse3 \
cygfuse.c
[ -n "$(Debug)" ] || strip $(Build)/cygfuse-$(Version).dll
$(Build)/fuse3.pc: fuse3.pc.in fuse3.cygport
@mkdir -p $(Build)
sed "s/@Version@/$(Version)/g" fuse3.pc.in > $(Build)/fuse3.pc
$(Build)/cygfuse-test.exe: cygfuse-test.c $(Build)/cygfuse-$(Version).dll
@mkdir -p $(Build)
gcc $(Debug) \
-o $(Build)/cygfuse-test.exe \
-I../../../inc/fuse3 -DCYGFUSE \
cygfuse-test.c \
-L$(PWD)/$(Build) -lfuse-$(Version)

View File

@ -0,0 +1,6 @@
#include <fuse.h>
int main()
{
return !(FUSE_VERSION == fuse_version());
}

173
opt/cygfuse/fuse3/cygfuse.c Normal file
View File

@ -0,0 +1,173 @@
/**
* @file fuse3/cygfuse.c
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dlfcn.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/cygwin.h>
static void *cygfuse_init_slow(int force);
static void *cygfuse_init_winfsp();
static pthread_mutex_t cygfuse_mutex = PTHREAD_MUTEX_INITIALIZER;
static void *cygfuse_handle = 0;
static inline void *cygfuse_init_fast(void)
{
void *handle = cygfuse_handle;
__sync_synchronize(); /* memory barrier */
if (0 == handle)
handle = cygfuse_init_slow(0);
return handle;
}
static void *cygfuse_init_slow(int force)
{
void *handle;
pthread_mutex_lock(&cygfuse_mutex);
handle = cygfuse_handle;
if (force || 0 == handle)
{
handle = cygfuse_init_winfsp();
__sync_synchronize(); /* memory barrier */
cygfuse_handle = handle;
}
pthread_mutex_unlock(&cygfuse_mutex);
return handle;
}
/*
* Unfortunately Cygwin fork is very fragile and cannot even correctly
* handle dlopen'ed DLL's if they are native (rather than Cygwin ones).
*
* So we have this very nasty hack where we reset the dlopen'ed handle
* immediately after daemonization. This will force cygfuse_init() to
* reload the WinFsp DLL and reset all API pointers in the daemonized
* process.
*/
static inline int cygfuse_daemon(int nochdir, int noclose)
{
if (-1 == daemon(nochdir, noclose))
return -1;
/* force reload of WinFsp DLL to workaround fork() problems */
cygfuse_init_slow(1);
return 0;
}
#define daemon cygfuse_daemon
#define FSP_FUSE_API static
#define FSP_FUSE_API_NAME(api) (* pfn_ ## api)
#define FSP_FUSE_API_CALL(api) (cygfuse_init_fast(), pfn_ ## api)
#define FSP_FUSE_SYM(proto, ...) __attribute__ ((visibility("default"))) proto { __VA_ARGS__ }
#include <fuse_common.h>
#include <fuse.h>
#include <fuse_opt.h>
#if defined(__LP64__)
#define CYGFUSE_WINFSP_NAME "winfsp-x64.dll"
#else
#define CYGFUSE_WINFSP_NAME "winfsp-x86.dll"
#endif
#define CYGFUSE_WINFSP_PATH "bin\\" CYGFUSE_WINFSP_NAME
#define CYGFUSE_GET_API(h, n) \
if (0 == (*(void **)&(pfn_ ## n) = dlsym(h, #n)))\
return cygfuse_init_fail();
static void *cygfuse_init_fail();
static void *cygfuse_init_winfsp()
{
void *h;
h = dlopen(CYGFUSE_WINFSP_NAME, RTLD_NOW);
if (0 == h)
{
char winpath[260], *psxpath;
int regfd, bytes;
regfd = open("/proc/registry32/HKEY_LOCAL_MACHINE/Software/WinFsp/InstallDir", O_RDONLY);
if (-1 == regfd)
return cygfuse_init_fail();
bytes = read(regfd, winpath, sizeof winpath - sizeof CYGFUSE_WINFSP_PATH);
close(regfd);
if (-1 == bytes || 0 == bytes)
return cygfuse_init_fail();
if ('\0' == winpath[bytes - 1])
bytes--;
memcpy(winpath + bytes, CYGFUSE_WINFSP_PATH, sizeof CYGFUSE_WINFSP_PATH);
psxpath = (char *)cygwin_create_path(CCP_WIN_A_TO_POSIX | CCP_PROC_CYGDRIVE, winpath);
if (0 == psxpath)
return cygfuse_init_fail();
h = dlopen(psxpath, RTLD_NOW);
free(psxpath);
if (0 == h)
return cygfuse_init_fail();
}
/* winfsp_fuse.h */
CYGFUSE_GET_API(h, fsp_fuse_signal_handler);
/* fuse_common.h */
CYGFUSE_GET_API(h, fsp_fuse3_parse_conn_info_opts);
CYGFUSE_GET_API(h, fsp_fuse3_apply_conn_info_opts);
CYGFUSE_GET_API(h, fsp_fuse3_version);
CYGFUSE_GET_API(h, fsp_fuse3_pkgversion);
CYGFUSE_GET_API(h, fsp_fuse_ntstatus_from_errno);
/* fuse.h */
CYGFUSE_GET_API(h, fsp_fuse3_main_real);
CYGFUSE_GET_API(h, fsp_fuse3_lib_help);
CYGFUSE_GET_API(h, fsp_fuse3_new_30);
CYGFUSE_GET_API(h, fsp_fuse3_new);
CYGFUSE_GET_API(h, fsp_fuse3_destroy);
CYGFUSE_GET_API(h, fsp_fuse3_mount);
CYGFUSE_GET_API(h, fsp_fuse3_unmount);
CYGFUSE_GET_API(h, fsp_fuse3_loop);
CYGFUSE_GET_API(h, fsp_fuse3_loop_mt_31);
CYGFUSE_GET_API(h, fsp_fuse3_loop_mt);
CYGFUSE_GET_API(h, fsp_fuse3_exit);
CYGFUSE_GET_API(h, fsp_fuse3_get_context);
/* fuse_opt.h */
CYGFUSE_GET_API(h, fsp_fuse_opt_parse);
CYGFUSE_GET_API(h, fsp_fuse_opt_add_arg);
CYGFUSE_GET_API(h, fsp_fuse_opt_insert_arg);
CYGFUSE_GET_API(h, fsp_fuse_opt_free_args);
CYGFUSE_GET_API(h, fsp_fuse_opt_add_opt);
CYGFUSE_GET_API(h, fsp_fuse_opt_add_opt_escaped);
CYGFUSE_GET_API(h, fsp_fuse_opt_match);
return h;
}
static void *cygfuse_init_fail()
{
fprintf(stderr, "cygfuse: initialization failed: " CYGFUSE_WINFSP_NAME " not found\n");
exit(1);
return 0;
}

View File

@ -0,0 +1,37 @@
NAME="fuse3"
VERSION=3.2
RELEASE=1
CATEGORY="Utils"
SUMMARY="WinFsp FUSE3 compatibility layer"
DESCRIPTION="Enables FUSE3 file systems to be run on Cygwin."
HOMEPAGE="http://www.secfs.net/winfsp/"
SRC_URI=${CYGPORT_SRC_URI:-"https://github.com/billziss-gh/winfsp/archive/master.tar.gz"}
SRC_DIR=${CYGPORT_SRC_DIR:-winfsp-master}
REQUIRES="fuse"
src_compile()
{
lndirs
cd ${B}/opt/cygfuse/fuse3
make
}
src_install()
{
cd ${B}/inc/fuse3
includeinto fuse3
doinclude fuse.h
doinclude fuse_common.h
doinclude fuse_opt.h
doinclude winfsp_fuse.h
cd ${B}/opt/cygfuse/fuse3/build/$(ARCH)
dobin cygfuse-${VERSION}.dll
dolib libfuse-${VERSION}.dll.a
dosym libfuse-${VERSION}.dll.a /usr/lib/libfuse3.dll.a
dopkgconfig fuse3.pc
}
RESTRICT="strip postinst-doc"

View File

@ -0,0 +1,9 @@
prefix=/usr
incdir=${prefix}/include/fuse3
Name: fuse
Description: WinFsp FUSE3 compatible API
Version: @Version@
URL: http://www.secfs.net/winfsp/
Libs: -lfuse-@Version@
Cflags: -I"${incdir}" -DCYGFUSE

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -162,6 +166,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation; FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory; FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory;
FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl; FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl;
FileSystem->Operations[FspFsctlTransactDeviceControlKind] = FspFileSystemOpDeviceControl;
FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity; FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity;
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity; FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation; FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -31,7 +35,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
{ {
NTSTATUS Result; NTSTATUS Result;
PWSTR DeviceRoot; PWSTR DeviceRoot;
SIZE_T DeviceRootSize, DevicePathSize; SIZE_T DeviceRootSize, DevicePathSize, VolumeParamsSize;
WCHAR DevicePathBuf[MAX_PATH + sizeof *VolumeParams], *DevicePathPtr, *DevicePathEnd; WCHAR DevicePathBuf[MAX_PATH + sizeof *VolumeParams], *DevicePathPtr, *DevicePathEnd;
HANDLE VolumeHandle = INVALID_HANDLE_VALUE; HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
DWORD Bytes; DWORD Bytes;
@ -55,8 +59,11 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
memcpy(DevicePathPtr, DevicePath, DevicePathSize); memcpy(DevicePathPtr, DevicePath, DevicePathSize);
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DevicePathSize); DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DevicePathSize);
memcpy(DevicePathPtr, PREFIXW, PREFIXW_SIZE); memcpy(DevicePathPtr, PREFIXW, PREFIXW_SIZE);
VolumeParamsSize = 0 == VolumeParams->Version ?
sizeof(FSP_FSCTL_VOLUME_PARAMS_V0) :
VolumeParams->Version;
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + PREFIXW_SIZE); DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + PREFIXW_SIZE);
DevicePathEnd = (PVOID)((PUINT8)DevicePathPtr + sizeof *VolumeParams * sizeof(WCHAR)); DevicePathEnd = (PVOID)((PUINT8)DevicePathPtr + VolumeParamsSize * sizeof(WCHAR));
for (PUINT8 VolumeParamsPtr = (PVOID)VolumeParams; for (PUINT8 VolumeParamsPtr = (PVOID)VolumeParams;
DevicePathEnd > DevicePathPtr; DevicePathPtr++, VolumeParamsPtr++) DevicePathEnd > DevicePathPtr; DevicePathPtr++, VolumeParamsPtr++)
{ {

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -1043,13 +1047,22 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
break; break;
} }
} }
if (0 != FileSystem->Interface->CanDelete) if (0 != FileSystem->Interface->SetDelete)
{
Result = FileSystem->Interface->SetDelete(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetInformation),
(PWSTR)Request->Buffer,
Request->Req.SetInformation.Info.Disposition.Delete);
}
else if (0 != FileSystem->Interface->CanDelete)
{
if (Request->Req.SetInformation.Info.Disposition.Delete) if (Request->Req.SetInformation.Info.Disposition.Delete)
Result = FileSystem->Interface->CanDelete(FileSystem, Result = FileSystem->Interface->CanDelete(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetInformation), (PVOID)ValOfFileContext(Request->Req.SetInformation),
(PWSTR)Request->Buffer); (PWSTR)Request->Buffer);
else else
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
}
break; break;
case 10/*FileRenameInformation*/: case 10/*FileRenameInformation*/:
if (0 != FileSystem->Interface->Rename) if (0 != FileSystem->Interface->Rename)
@ -1247,6 +1260,30 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
FSP_API NTSTATUS FspFileSystemOpDeviceControl(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
NTSTATUS Result;
ULONG BytesTransferred;
if (0 == FileSystem->Interface->Control)
return STATUS_INVALID_DEVICE_REQUEST;
Result = FileSystem->Interface->Control(FileSystem,
(PVOID)ValOfFileContext(Request->Req.DeviceControl),
Request->Req.DeviceControl.IoControlCode,
Request->Buffer, Request->Req.DeviceControl.Buffer.Size,
Response->Buffer, Request->Req.DeviceControl.OutputLength/* FSD guarantees correct size! */,
&BytesTransferred);
if (!NT_SUCCESS(Result))
return STATUS_BUFFER_OVERFLOW != Result ? Result : STATUS_BUFFER_TOO_SMALL;
Response->Size = (UINT16)(sizeof *Response + BytesTransferred);
Response->Rsp.DeviceControl.Buffer.Offset = 0;
Response->Rsp.DeviceControl.Buffer.Size = (UINT16)BytesTransferred;
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {

View File

@ -10,16 +10,17 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/fuse/library.h> #include <dll/fuse/library.h>
#define FSP_FUSE_SECTORSIZE_MIN 512
#define FSP_FUSE_SECTORSIZE_MAX 4096
struct fuse_chan struct fuse_chan
{ {
PWSTR MountPoint; PWSTR MountPoint;
@ -27,25 +28,7 @@ struct fuse_chan
}; };
#define FSP_FUSE_CORE_OPT(n, f, v) { n, offsetof(struct fsp_fuse_core_opt_data, f), v } #define FSP_FUSE_CORE_OPT(n, f, v) { n, offsetof(struct fsp_fuse_core_opt_data, f), v }
#define FSP_FUSE_CORE_OPT_NOHELP_IDX 4
struct fsp_fuse_core_opt_data
{
struct fsp_fuse_env *env;
int help, debug;
HANDLE DebugLogHandle;
int set_umask, umask,
set_uid, uid,
set_gid, gid,
set_attr_timeout, attr_timeout,
rellinks;
int set_FileInfoTimeout;
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
UINT16 VolumeLabelLength;
WCHAR VolumeLabel[sizeof ((FSP_FSCTL_VOLUME_INFO *)0)->VolumeLabel / sizeof(WCHAR)];
};
FSP_FSCTL_STATIC_ASSERT(
sizeof ((struct fuse *)0)->VolumeLabel == sizeof ((struct fsp_fuse_core_opt_data *)0)->VolumeLabel,
"fuse::VolumeLabel and fsp_fuse_core_opt_data::VolumeLabel: sizeof must be same.");
static struct fuse_opt fsp_fuse_core_opts[] = static struct fuse_opt fsp_fuse_core_opts[] =
{ {
@ -69,6 +52,8 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FUSE_OPT_KEY("noauto_cache", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("noauto_cache", FUSE_OPT_KEY_DISCARD),
FSP_FUSE_CORE_OPT("umask=", set_umask, 1), FSP_FUSE_CORE_OPT("umask=", set_umask, 1),
FSP_FUSE_CORE_OPT("umask=%o", umask, 0), FSP_FUSE_CORE_OPT("umask=%o", umask, 0),
FSP_FUSE_CORE_OPT("create_umask=", set_create_umask, 1),
FSP_FUSE_CORE_OPT("create_umask=%o", create_umask, 0),
FSP_FUSE_CORE_OPT("uid=", set_uid, 1), FSP_FUSE_CORE_OPT("uid=", set_uid, 1),
FSP_FUSE_CORE_OPT("uid=%d", uid, 0), FSP_FUSE_CORE_OPT("uid=%d", uid, 0),
FSP_FUSE_CORE_OPT("gid=", set_gid, 1), FSP_FUSE_CORE_OPT("gid=", set_gid, 1),
@ -96,6 +81,12 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("VolumeSerialNumber=%lx", VolumeParams.VolumeSerialNumber, 0), FSP_FUSE_CORE_OPT("VolumeSerialNumber=%lx", VolumeParams.VolumeSerialNumber, 0),
FSP_FUSE_CORE_OPT("FileInfoTimeout=", set_FileInfoTimeout, 1), FSP_FUSE_CORE_OPT("FileInfoTimeout=", set_FileInfoTimeout, 1),
FSP_FUSE_CORE_OPT("FileInfoTimeout=%d", VolumeParams.FileInfoTimeout, 0), FSP_FUSE_CORE_OPT("FileInfoTimeout=%d", VolumeParams.FileInfoTimeout, 0),
FSP_FUSE_CORE_OPT("DirInfoTimeout=", set_DirInfoTimeout, 1),
FSP_FUSE_CORE_OPT("DirInfoTimeout=%d", VolumeParams.DirInfoTimeout, 0),
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1),
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0),
FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1),
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'),
FUSE_OPT_KEY("VolumePrefix=", 'U'), FUSE_OPT_KEY("VolumePrefix=", 'U'),
@ -107,36 +98,7 @@ static struct fuse_opt fsp_fuse_core_opts[] =
}; };
static INIT_ONCE fsp_fuse_initonce = INIT_ONCE_STATIC_INIT; static INIT_ONCE fsp_fuse_initonce = INIT_ONCE_STATIC_INIT;
static DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES; DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES;
struct fsp_fuse_obj_hdr
{
void (*dtor)(void *);
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ObjectBuf[];
};
static inline void *fsp_fuse_obj_alloc(struct fsp_fuse_env *env, size_t size)
{
struct fsp_fuse_obj_hdr *hdr;
hdr = env->memalloc(sizeof(struct fsp_fuse_obj_hdr) + size);
if (0 == hdr)
return 0;
hdr->dtor = env->memfree;
memset(hdr->ObjectBuf, 0, size);
return hdr->ObjectBuf;
}
static inline void fsp_fuse_obj_free(void *obj)
{
if (0 == obj)
return;
struct fsp_fuse_obj_hdr *hdr = (PVOID)((PUINT8)obj - sizeof(struct fsp_fuse_obj_hdr));
hdr->dtor(hdr);
}
static BOOL WINAPI fsp_fuse_initialize( static BOOL WINAPI fsp_fuse_initialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
@ -262,202 +224,6 @@ 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 void fsp_fuse_cleanup(struct fuse *f);
static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
{
struct fuse *f = Service->UserContext;
struct fuse_context *context;
struct fuse_conn_info conn;
NTSTATUS Result;
f->Service = Service;
context = fsp_fuse_get_context(f->env);
if (0 == context)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
context->fuse = f;
context->private_data = f->data;
context->uid = -1;
context->gid = -1;
context->pid = -1;
memset(&conn, 0, sizeof conn);
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
conn.proto_minor = 12; /* which was current at the time of FUSE 2.8 */
conn.async_read = 1;
conn.max_write = UINT_MAX;
conn.capable =
FUSE_CAP_ASYNC_READ |
//FUSE_CAP_POSIX_LOCKS | /* WinFsp handles locking in the FSD currently */
//FUSE_CAP_ATOMIC_O_TRUNC | /* due to Windows/WinFsp design, no support */
//FUSE_CAP_EXPORT_SUPPORT | /* not needed in Windows/WinFsp */
FUSE_CAP_BIG_WRITES |
FUSE_CAP_DONT_MASK |
FSP_FUSE_CAP_READDIR_PLUS |
FSP_FUSE_CAP_READ_ONLY |
FSP_FUSE_CAP_STAT_EX |
FSP_FUSE_CAP_CASE_INSENSITIVE;
if (0 != f->ops.init)
{
context->private_data = f->data = f->ops.init(&conn);
f->VolumeParams.ReadOnlyVolume = 0 != (conn.want & FSP_FUSE_CAP_READ_ONLY);
f->VolumeParams.CaseSensitiveSearch = 0 == (conn.want & FSP_FUSE_CAP_CASE_INSENSITIVE);
if (!f->VolumeParams.CaseSensitiveSearch)
/*
* Disable GetDirInfoByName when file system is case-insensitive.
* The reason is that Windows always sends us queries with uppercase
* file names in GetDirInfoByName and we have no way in FUSE to normalize
* those file names when embedding them in FSP_FSCTL_DIR_INFO.
*/
f->VolumeParams.PassQueryDirectoryFileName = FALSE;
f->conn_want = conn.want;
}
f->fsinit = TRUE;
if (0 != f->ops.statfs)
{
struct fuse_statvfs stbuf;
int err;
memset(&stbuf, 0, sizeof stbuf);
err = f->ops.statfs("/", &stbuf);
if (0 != err)
{
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
goto fail;
}
if (0 == f->VolumeParams.SectorSize && 0 != stbuf.f_frsize)
f->VolumeParams.SectorSize = (UINT16)stbuf.f_frsize;
#if 0
if (0 == f->VolumeParams.SectorsPerAllocationUnit && 0 != stbuf.f_frsize)
f->VolumeParams.SectorsPerAllocationUnit = (UINT16)(stbuf.f_bsize / stbuf.f_frsize);
#endif
if (0 == f->VolumeParams.MaxComponentLength)
f->VolumeParams.MaxComponentLength = (UINT16)stbuf.f_namemax;
}
if (0 != f->ops.getattr)
{
struct fuse_stat_ex stbuf;
int err;
memset(&stbuf, 0, sizeof stbuf);
err = f->ops.getattr("/", (void *)&stbuf);
if (0 != err)
{
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
goto fail;
}
if (0 == f->VolumeParams.VolumeCreationTime)
{
if (0 != stbuf.st_birthtim.tv_sec)
FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim,
&f->VolumeParams.VolumeCreationTime);
else
if (0 != stbuf.st_ctim.tv_sec)
FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim,
&f->VolumeParams.VolumeCreationTime);
}
}
/* the FSD does not currently limit these VolumeParams fields; do so here! */
if (f->VolumeParams.SectorSize < FSP_FUSE_SECTORSIZE_MIN ||
f->VolumeParams.SectorSize > FSP_FUSE_SECTORSIZE_MAX)
f->VolumeParams.SectorSize = FSP_FUSE_SECTORSIZE_MAX;
if (f->VolumeParams.SectorsPerAllocationUnit == 0)
f->VolumeParams.SectorsPerAllocationUnit = 1;
if (f->VolumeParams.MaxComponentLength > 255)
f->VolumeParams.MaxComponentLength = 255;
if (0 == f->VolumeParams.VolumeCreationTime)
{
FILETIME FileTime;
GetSystemTimeAsFileTime(&FileTime);
f->VolumeParams.VolumeCreationTime = *(PUINT64)&FileTime;
}
if (0 == f->VolumeParams.VolumeSerialNumber)
f->VolumeParams.VolumeSerialNumber =
((PLARGE_INTEGER)&f->VolumeParams.VolumeCreationTime)->HighPart ^
((PLARGE_INTEGER)&f->VolumeParams.VolumeCreationTime)->LowPart;
Result = FspFileSystemCreate(
f->VolumeParams.Prefix[0] ?
L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME,
&f->VolumeParams, &fsp_fuse_intf,
&f->FileSystem);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot create " FSP_FUSE_LIBRARY_NAME " file system.");
goto fail;
}
f->FileSystem->UserContext = f;
FspFileSystemSetOperationGuard(f->FileSystem, fsp_fuse_op_enter, fsp_fuse_op_leave);
FspFileSystemSetOperationGuardStrategy(f->FileSystem, f->OpGuardStrategy);
FspFileSystemSetDebugLog(f->FileSystem, f->DebugLog);
if (0 != f->MountPoint)
{
Result = FspFileSystemSetMountPoint(f->FileSystem,
L'*' == f->MountPoint[0] && L'\0' == f->MountPoint[1] ? 0 : f->MountPoint);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot set " FSP_FUSE_LIBRARY_NAME " file system mount point.");
goto fail;
}
}
Result = FspFileSystemStartDispatcher(f->FileSystem, 0);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot start " FSP_FUSE_LIBRARY_NAME " file system dispatcher.");
goto fail;
}
return STATUS_SUCCESS;
fail:
fsp_fuse_cleanup(f);
return Result;
}
static NTSTATUS fsp_fuse_svcstop(FSP_SERVICE *Service)
{
struct fuse *f = Service->UserContext;
FspFileSystemStopDispatcher(f->FileSystem);
fsp_fuse_cleanup(f);
return STATUS_SUCCESS;
}
static void fsp_fuse_cleanup(struct fuse *f)
{
if (0 != f->FileSystem)
{
FspFileSystemDelete(f->FileSystem);
f->FileSystem = 0;
}
if (f->fsinit)
{
if (f->ops.destroy)
f->ops.destroy(f->data);
f->fsinit = FALSE;
}
f->Service = 0;
}
static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key, static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
struct fuse_args *outargs) struct fuse_args *outargs)
{ {
@ -468,10 +234,11 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
default: default:
return 1; return 1;
case 'h': case 'h':
/* Note: The limit on FspServiceLog messages is 1024 bytes. This is getting close. */ /* Note: The limit on FspServiceLog messages is 1024 bytes. */
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 create_umask=MASK set newly created file permissions (octal)\n"
" -o uid=N set file owner (-1 for mounting user id)\n" " -o uid=N set file owner (-1 for mounting user id)\n"
" -o gid=N set file group (-1 for mounting user group)\n" " -o gid=N set file group (-1 for mounting user group)\n"
" -o rellinks interpret absolute symlinks as volume relative\n" " -o rellinks interpret absolute symlinks as volume relative\n"
@ -480,14 +247,14 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
" --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n" " --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n"
" -o FileSystemName=NAME set file system name\n" " -o FileSystemName=NAME set file system name\n"
" -o DebugLog=FILE debug log file (requires -d)\n" " -o DebugLog=FILE debug log file (requires -d)\n"
"\n" );
FspServiceLog(EVENTLOG_ERROR_TYPE, L""
FSP_FUSE_LIBRARY_NAME " advanced options:\n" FSP_FUSE_LIBRARY_NAME " advanced options:\n"
" -o FileInfoTimeout=N metadata timeout (millis, -1 for data caching)\n" " -o FileInfoTimeout=N metadata timeout (millis, -1 for data caching)\n"
" -o SectorSize=N (512-4096, deflt: 4096)\n" " -o DirInfoTimeout=N directory info timeout (millis)\n"
" -o SectorsPerAllocationUnit=N (deflt: 1)\n" " -o VolumeInfoTimeout=N volume info timeout (millis)\n"
" -o MaxComponentLength=N (deflt: 255)\n" " -o KeepFileCache do not discard cache when files are closed\n"
" -o VolumeCreationTime=T (FILETIME hex format)\n" " -o ThreadCount number of file system dispatcher threads\n"
" -o VolumeSerialNumber=N (32-bit wide)\n"
); );
opt_data->help = 1; opt_data->help = 1;
return 1; return 1;
@ -552,6 +319,18 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
} }
} }
int fsp_fuse_core_opt_parse(struct fsp_fuse_env *env,
struct fuse_args *args, struct fsp_fuse_core_opt_data *opt_data,
int help)
{
if (help)
return fsp_fuse_opt_parse(env, args, opt_data,
fsp_fuse_core_opts, fsp_fuse_core_opt_proc);
else
return fsp_fuse_opt_parse(env, args, opt_data,
fsp_fuse_core_opts + FSP_FUSE_CORE_OPT_NOHELP_IDX, fsp_fuse_core_opt_proc);
}
FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env, FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
struct fuse_chan *ch, struct fuse_args *args, struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *ops, size_t opsize, void *data) const struct fuse_operations *ops, size_t opsize, void *data)
@ -568,9 +347,11 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
memset(&opt_data, 0, sizeof opt_data); memset(&opt_data, 0, sizeof opt_data);
opt_data.env = env; opt_data.env = env;
opt_data.DebugLogHandle = GetStdHandle(STD_ERROR_HANDLE); opt_data.DebugLogHandle = GetStdHandle(STD_ERROR_HANDLE);
opt_data.VolumeParams.FileInfoTimeout = 1000; /* default FileInfoTimeout for FUSE file systems */ opt_data.VolumeParams.Version = sizeof(FSP_FSCTL_VOLUME_PARAMS);
opt_data.VolumeParams.FileInfoTimeout = 1000;
opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE;
if (-1 == fsp_fuse_opt_parse(env, args, &opt_data, fsp_fuse_core_opts, fsp_fuse_core_opt_proc)) if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1))
return 0; return 0;
if (opt_data.help) if (opt_data.help)
return 0; return 0;
@ -608,7 +389,13 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
} }
if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout) if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout)
opt_data.VolumeParams.FileInfoTimeout = opt_data.set_attr_timeout * 1000; opt_data.VolumeParams.FileInfoTimeout = opt_data.attr_timeout * 1000;
if (opt_data.set_DirInfoTimeout)
opt_data.VolumeParams.DirInfoTimeoutValid = 1;
if (opt_data.set_VolumeInfoTimeout)
opt_data.VolumeParams.VolumeInfoTimeoutValid = 1;
if (opt_data.set_KeepFileCache)
opt_data.VolumeParams.FlushAndPurgeOnCleanup = 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;
@ -618,6 +405,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.ReadOnlyVolume = FALSE; opt_data.VolumeParams.ReadOnlyVolume = FALSE;
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE; opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE; opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE;
opt_data.VolumeParams.DeviceControl = TRUE;
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE; opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
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));
@ -628,9 +416,11 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
f->env = env; f->env = env;
f->set_umask = opt_data.set_umask; f->umask = opt_data.umask; f->set_umask = opt_data.set_umask; f->umask = opt_data.umask;
f->set_create_umask = opt_data.set_create_umask; f->create_umask = opt_data.create_umask;
f->set_uid = opt_data.set_uid; f->uid = opt_data.uid; f->set_uid = opt_data.set_uid; f->uid = opt_data.uid;
f->set_gid = opt_data.set_gid; f->gid = opt_data.gid; f->set_gid = opt_data.set_gid; f->gid = opt_data.gid;
f->rellinks = opt_data.rellinks; f->rellinks = opt_data.rellinks;
f->ThreadCount = opt_data.ThreadCount;
memcpy(&f->ops, ops, opsize); memcpy(&f->ops, ops, opsize);
f->data = data; f->data = data;
f->DebugLog = opt_data.debug ? -1 : 0; f->DebugLog = opt_data.debug ? -1 : 0;
@ -691,34 +481,16 @@ fail:
FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env, FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
struct fuse *f) struct fuse *f)
{ {
fsp_fuse_cleanup(f);
fsp_fuse_obj_free(f->MountPoint); fsp_fuse_obj_free(f->MountPoint);
fsp_fuse_obj_free(f); fsp_fuse_obj_free(f);
} }
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
struct fuse *f)
{
f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE;
return 0 == FspServiceRunEx(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0, f) ?
0 : -1;
}
FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env,
struct fuse *f)
{
f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE;
return 0 == FspServiceRunEx(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0, f) ?
0 : -1;
}
FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env, FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env,
struct fuse *f) struct fuse *f)
{ {
if (0 != f->Service) if (0 != f->LoopEvent)
FspServiceStop(f->Service); SetEvent(f->LoopEvent);
f->exited = 1; f->exited = 1;
} }
@ -779,10 +551,3 @@ FSP_FUSE_API int32_t fsp_fuse_ntstatus_from_errno(struct fsp_fuse_env *env,
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
} }
} }
/* Cygwin signal support */
FSP_FUSE_API void fsp_fuse_signal_handler(int sig)
{
FspServiceConsoleCtrlHandler(CTRL_BREAK_EVENT);
}

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/fuse/library.h> #include <dll/fuse/library.h>
@ -266,7 +270,7 @@ loopend:;
if (0 != f->ops.getattr) if (0 != f->ops.getattr)
err = f->ops.getattr(PosixHiddenPath, (void *)&stbuf); err = f->ops.getattr(PosixHiddenPath, (void *)&stbuf);
else else
err = -ENOSYS; err = -ENOSYS_(f->env);
} while (0 == err && 0 < --maxtries); } while (0 == err && 0 < --maxtries);
if (0 == err) if (0 == err)
@ -308,7 +312,7 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
if (0 != f->ops.getattr) if (0 != f->ops.getattr)
err = f->ops.getattr(PosixDotPath, (void *)&stbuf); err = f->ops.getattr(PosixDotPath, (void *)&stbuf);
else else
err = -ENOSYS; err = -ENOSYS_(f->env);
MemFree(PosixDotPath); MemFree(PosixDotPath);
@ -711,14 +715,16 @@ static NTSTATUS fsp_fuse_intf_GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
Result = fsp_fuse_intf_GetSecurityEx(FileSystem, PosixPath, 0, Result = fsp_fuse_intf_GetSecurityEx(FileSystem, PosixPath, 0,
PFileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize); PFileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result) &&
STATUS_OBJECT_NAME_NOT_FOUND != Result &&
STATUS_OBJECT_PATH_NOT_FOUND != Result)
goto exit; goto exit;
if (FSP_FUSE_HAS_SYMLINKS(f) && if (FSP_FUSE_HAS_SYMLINKS(f) &&
FspFileSystemFindReparsePoint(FileSystem, fsp_fuse_intf_GetReparsePointByName, 0, FspFileSystemFindReparsePoint(FileSystem, fsp_fuse_intf_GetReparsePointByName, 0,
FileName, PFileAttributes)) FileName, PFileAttributes))
Result = STATUS_REPARSE; Result = STATUS_REPARSE;
else else if (NT_SUCCESS(Result))
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
exit: exit:
@ -731,7 +737,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fuse_context *context = fsp_fuse_get_context(f->env); struct fuse_context *context = fsp_fuse_get_context(f->env);
@ -762,6 +768,8 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
Mode &= ~context->umask; Mode &= ~context->umask;
if (f->set_create_umask)
Mode = 0777 & ~f->create_umask;
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
if ('C' == f->env->environment) /* Cygwin */ if ('C' == f->env->environment) /* Cygwin */
@ -854,7 +862,7 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
*PFileNode = filedesc; *PFileDesc = filedesc;
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf); memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
filedesc->PosixPath = contexthdr->PosixPath; filedesc->PosixPath = contexthdr->PosixPath;
@ -892,7 +900,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fuse_context *context = fsp_fuse_get_context(f->env); struct fuse_context *context = fsp_fuse_get_context(f->env);
@ -971,7 +979,7 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
* Ignore fuse_file_info::nonseekable. * Ignore fuse_file_info::nonseekable.
*/ */
*PFileNode = filedesc; *PFileDesc = filedesc;
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf); memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
filedesc->PosixPath = contexthdr->PosixPath; filedesc->PosixPath = contexthdr->PosixPath;
@ -992,11 +1000,11 @@ exit:
} }
static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, PVOID FileDesc, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
int err; int err;
@ -1045,10 +1053,10 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
} }
static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem, static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PWSTR FileName, ULONG Flags) PVOID FileDesc, PWSTR FileName, ULONG Flags)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
/* /*
* In Windows a DeleteFile/RemoveDirectory is the sequence of the following: * In Windows a DeleteFile/RemoveDirectory is the sequence of the following:
@ -1081,10 +1089,10 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
} }
static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem, static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode) PVOID FileDesc)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
@ -1114,11 +1122,11 @@ static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_Read(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Read(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length, PVOID FileDesc, PVOID Buffer, UINT64 Offset, ULONG Length,
PULONG PBytesTransferred) PULONG PBytesTransferred)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
int bytes; int bytes;
NTSTATUS Result; NTSTATUS Result;
@ -1148,12 +1156,12 @@ static NTSTATUS fsp_fuse_intf_Read(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length, PVOID FileDesc, PVOID Buffer, UINT64 Offset, ULONG Length,
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo) PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
@ -1211,11 +1219,11 @@ success:
} }
static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
@ -1262,11 +1270,11 @@ static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
@ -1279,12 +1287,12 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, UINT32 FileAttributes, PVOID FileDesc, UINT32 FileAttributes,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
@ -1364,11 +1372,11 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, UINT64 NewSize, BOOLEAN SetAllocationSize, PVOID FileDesc, UINT64 NewSize, BOOLEAN SetAllocationSize,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
struct fuse_file_info fi; struct fuse_file_info fi;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
@ -1423,7 +1431,8 @@ static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static int fsp_fuse_intf_CanDeleteAddDirInfo(void *buf, const char *name, /* !static: used by fuse2to3 */
int fsp_fuse_intf_CanDeleteAddDirInfo(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off) const struct fuse_stat *stbuf, fuse_off_t off)
{ {
struct fuse_dirhandle *dh = buf; struct fuse_dirhandle *dh = buf;
@ -1447,10 +1456,10 @@ static int fsp_fuse_intf_CanDeleteAddDirInfoOld(fuse_dirh_t dh, const char *name
} }
static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PWSTR FileName) PVOID FileDesc, PWSTR FileName)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
struct fuse_dirhandle dh; struct fuse_dirhandle dh;
int err; int err;
@ -1486,7 +1495,7 @@ static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
@ -1494,7 +1503,7 @@ static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
struct fsp_fuse_context_header *contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context); struct fsp_fuse_context_header *contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
int err; int err;
NTSTATUS Result; NTSTATUS Result;
@ -1520,11 +1529,11 @@ static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
PSECURITY_DESCRIPTOR SecurityDescriptorBuf, SIZE_T *PSecurityDescriptorSize) PSECURITY_DESCRIPTOR SecurityDescriptorBuf, SIZE_T *PSecurityDescriptorSize)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
UINT32 FileAttributes; UINT32 FileAttributes;
@ -1537,11 +1546,11 @@ static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
UINT32 Uid, Gid, Mode, NewUid, NewGid, NewMode; UINT32 Uid, Gid, Mode, NewUid, NewGid, NewMode;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
@ -1613,7 +1622,8 @@ exit:
return Result; return Result;
} }
static int fsp_fuse_intf_AddDirInfo(void *buf, const char *name, /* !static: used by fuse2to3 */
int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off) const struct fuse_stat *stbuf, fuse_off_t off)
{ {
struct fuse_dirhandle *dh = buf; struct fuse_dirhandle *dh = buf;
@ -1648,7 +1658,8 @@ static int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
memset(DirInfo, 0, sizeof *DirInfo); memset(DirInfo, 0, sizeof *DirInfo);
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + SizeW * sizeof(WCHAR)); DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + SizeW * sizeof(WCHAR));
if (dh->ReaddirPlus && 0 != stbuf) if (dh->ReaddirPlus && 0 != stbuf &&
0120000/* S_IFLNK */ != (stbuf->st_mode & 0170000))
{ {
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
NTSTATUS Result0; NTSTATUS Result0;
@ -1761,11 +1772,11 @@ exit:
} }
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PWSTR Pattern, PWSTR Marker, PVOID FileDesc, PWSTR Pattern, PWSTR Marker,
PVOID Buffer, ULONG Length, PULONG PBytesTransferred) PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_dirhandle dh; struct fuse_dirhandle dh;
struct fuse_file_info fi; struct fuse_file_info fi;
int err; int err;
@ -1816,11 +1827,11 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PWSTR FileName, PVOID FileDesc, PWSTR FileName,
FSP_FSCTL_DIR_INFO *DirInfo) FSP_FSCTL_DIR_INFO *DirInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
char *PosixName = 0; char *PosixName = 0;
char PosixPath[FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)]; char PosixPath[FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)];
int ParentLength, FSlashLength, PosixNameLength; int ParentLength, FSlashLength, PosixNameLength;
@ -1903,10 +1914,10 @@ exit:
} }
static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
PWSTR FileName, PVOID Buffer, PSIZE_T PSize) PWSTR FileName, PVOID Buffer, PSIZE_T PSize)
{ {
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
@ -1917,12 +1928,12 @@ static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
} }
static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
PWSTR FileName, PVOID Buffer, SIZE_T Size) PWSTR FileName, PVOID Buffer, SIZE_T Size)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fuse_context *context = fsp_fuse_get_context(f->env); struct fuse_context *context = fsp_fuse_get_context(f->env);
struct fsp_fuse_file_desc *filedesc = FileNode; struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi; struct fuse_file_info fi;
UINT32 Uid, Gid, Mode, Dev; UINT32 Uid, Gid, Mode, Dev;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
@ -2113,13 +2124,55 @@ exit:
} }
static NTSTATUS fsp_fuse_intf_DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem,
PVOID FileNode, PVOID FileDesc,
PWSTR FileName, PVOID Buffer, SIZE_T Size) PWSTR FileName, PVOID Buffer, SIZE_T Size)
{ {
/* we were asked to delete the reparse point? no can do! */ /* we were asked to delete the reparse point? no can do! */
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
} }
static NTSTATUS fsp_fuse_intf_Control(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, UINT32 ControlCode,
PVOID InputBuffer, ULONG InputBufferLength,
PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
struct fuse_file_info fi;
int cmd;
int err;
if (0 == f->ops.ioctl)
return STATUS_INVALID_DEVICE_REQUEST;
if (FSP_FUSE_DEVICE_TYPE != DEVICE_TYPE_FROM_CTL_CODE(ControlCode))
return STATUS_INVALID_DEVICE_REQUEST;
if (0 != InputBufferLength && 0 != OutputBufferLength &&
InputBufferLength != OutputBufferLength)
return STATUS_INVALID_DEVICE_REQUEST;
memset(&fi, 0, sizeof fi);
fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle;
/* construct a Linux compatible ioctl code */
cmd = FSP_FUSE_IOCTL((ControlCode >> 2) & 0xfff, InputBufferLength, OutputBufferLength);
if (0 == OutputBufferLength)
err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, InputBuffer);
else
{
if (0 != InputBufferLength)
// OutputBuffer points to Response->Buffer which is FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX long
memcpy(OutputBuffer, InputBuffer, InputBufferLength);
err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, OutputBuffer);
}
*PBytesTransferred = OutputBufferLength;
return fsp_fuse_ntstatus_from_errno(f->env, err);
}
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf = FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
{ {
fsp_fuse_intf_GetVolumeInfo, fsp_fuse_intf_GetVolumeInfo,
@ -2147,6 +2200,7 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
fsp_fuse_intf_DeleteReparsePoint, fsp_fuse_intf_DeleteReparsePoint,
0, 0,
fsp_fuse_intf_GetDirInfoByName, fsp_fuse_intf_GetDirInfoByName,
fsp_fuse_intf_Control,
}; };
/* /*

315
src/dll/fuse/fuse_loop.c Normal file
View File

@ -0,0 +1,315 @@
/**
* @file dll/fuse/fuse_loop.c
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dll/fuse/library.h>
#define FSP_FUSE_SECTORSIZE_MIN 512
#define FSP_FUSE_SECTORSIZE_MAX 4096
static INIT_ONCE fsp_fuse_svconce = INIT_ONCE_STATIC_INIT;
static HANDLE fsp_fuse_svcthread;
static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
{
return STATUS_SUCCESS;
}
static NTSTATUS fsp_fuse_svcstop(FSP_SERVICE *Service)
{
return STATUS_SUCCESS;
}
static DWORD WINAPI fsp_fuse_svcmain(PVOID Context)
{
return FspServiceRun(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0);
}
static BOOL WINAPI fsp_fuse_svcinit(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{
fsp_fuse_svcthread = CreateThread(0, 0, fsp_fuse_svcmain, 0, 0, 0);
return TRUE;
}
static void fsp_fuse_loop_cleanup(struct fuse *f);
static NTSTATUS fsp_fuse_loop_start(struct fuse *f)
{
struct fuse_context *context;
struct fuse_conn_info conn;
NTSTATUS Result;
f->LoopEvent = CreateEventW(0, TRUE, FALSE, 0);
if (0 == f->LoopEvent)
goto fail;
context = fsp_fuse_get_context(f->env);
if (0 == context)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto fail;
}
context->fuse = f;
context->private_data = f->data;
context->uid = -1;
context->gid = -1;
context->pid = -1;
memset(&conn, 0, sizeof conn);
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
conn.proto_minor = 12; /* which was current at the time of FUSE 2.8 */
conn.async_read = 1;
conn.max_write = UINT_MAX;
conn.capable =
FUSE_CAP_ASYNC_READ |
//FUSE_CAP_POSIX_LOCKS | /* WinFsp handles locking in the FSD currently */
//FUSE_CAP_ATOMIC_O_TRUNC | /* due to Windows/WinFsp design, no support */
//FUSE_CAP_EXPORT_SUPPORT | /* not needed in Windows/WinFsp */
FUSE_CAP_BIG_WRITES |
FUSE_CAP_DONT_MASK |
FSP_FUSE_CAP_READDIR_PLUS |
FSP_FUSE_CAP_READ_ONLY |
FSP_FUSE_CAP_STAT_EX |
FSP_FUSE_CAP_CASE_INSENSITIVE;
if (0 != f->ops.init)
{
context->private_data = f->data = f->ops.init(&conn);
f->VolumeParams.ReadOnlyVolume = 0 != (conn.want & FSP_FUSE_CAP_READ_ONLY);
f->VolumeParams.CaseSensitiveSearch = 0 == (conn.want & FSP_FUSE_CAP_CASE_INSENSITIVE);
if (!f->VolumeParams.CaseSensitiveSearch)
/*
* Disable GetDirInfoByName when file system is case-insensitive.
* The reason is that Windows always sends us queries with uppercase
* file names in GetDirInfoByName and we have no way in FUSE to normalize
* those file names when embedding them in FSP_FSCTL_DIR_INFO.
*/
f->VolumeParams.PassQueryDirectoryFileName = FALSE;
f->conn_want = conn.want;
}
f->fsinit = TRUE;
if (0 != f->ops.statfs)
{
struct fuse_statvfs stbuf;
int err;
memset(&stbuf, 0, sizeof stbuf);
err = f->ops.statfs("/", &stbuf);
if (0 != err)
{
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
goto fail;
}
if (0 == f->VolumeParams.SectorSize && 0 != stbuf.f_frsize)
f->VolumeParams.SectorSize = (UINT16)stbuf.f_frsize;
#if 0
if (0 == f->VolumeParams.SectorsPerAllocationUnit && 0 != stbuf.f_frsize)
f->VolumeParams.SectorsPerAllocationUnit = (UINT16)(stbuf.f_bsize / stbuf.f_frsize);
#endif
if (0 == f->VolumeParams.MaxComponentLength)
f->VolumeParams.MaxComponentLength = (UINT16)stbuf.f_namemax;
}
if (0 != f->ops.getattr)
{
struct fuse_stat_ex stbuf;
int err;
memset(&stbuf, 0, sizeof stbuf);
err = f->ops.getattr("/", (void *)&stbuf);
if (0 != err)
{
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
goto fail;
}
if (0 == f->VolumeParams.VolumeCreationTime)
{
if (0 != stbuf.st_birthtim.tv_sec)
FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim,
&f->VolumeParams.VolumeCreationTime);
else
if (0 != stbuf.st_ctim.tv_sec)
FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim,
&f->VolumeParams.VolumeCreationTime);
}
}
if (0 != f->ops.readlink)
{
char buf[FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)];
int err;
/* this should always fail with ENOSYS or EINVAL */
err = f->ops.readlink("/", buf, sizeof buf);
f->has_symlinks = -ENOSYS_(f->env) != err;
}
/* the FSD does not currently limit these VolumeParams fields; do so here! */
if (f->VolumeParams.SectorSize < FSP_FUSE_SECTORSIZE_MIN ||
f->VolumeParams.SectorSize > FSP_FUSE_SECTORSIZE_MAX)
f->VolumeParams.SectorSize = FSP_FUSE_SECTORSIZE_MAX;
if (f->VolumeParams.SectorsPerAllocationUnit == 0)
f->VolumeParams.SectorsPerAllocationUnit = 1;
if (f->VolumeParams.MaxComponentLength > 255)
f->VolumeParams.MaxComponentLength = 255;
if (0 == f->VolumeParams.VolumeCreationTime)
{
FILETIME FileTime;
GetSystemTimeAsFileTime(&FileTime);
f->VolumeParams.VolumeCreationTime = *(PUINT64)&FileTime;
}
if (0 == f->VolumeParams.VolumeSerialNumber)
f->VolumeParams.VolumeSerialNumber =
((PLARGE_INTEGER)&f->VolumeParams.VolumeCreationTime)->HighPart ^
((PLARGE_INTEGER)&f->VolumeParams.VolumeCreationTime)->LowPart;
Result = FspFileSystemCreate(
f->VolumeParams.Prefix[0] ?
L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME,
&f->VolumeParams, &fsp_fuse_intf,
&f->FileSystem);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot create " FSP_FUSE_LIBRARY_NAME " file system.");
goto fail;
}
f->FileSystem->UserContext = f;
FspFileSystemSetOperationGuard(f->FileSystem, fsp_fuse_op_enter, fsp_fuse_op_leave);
FspFileSystemSetOperationGuardStrategy(f->FileSystem, f->OpGuardStrategy);
FspFileSystemSetDebugLog(f->FileSystem, f->DebugLog);
if (0 != f->MountPoint)
{
Result = FspFileSystemSetMountPoint(f->FileSystem,
L'*' == f->MountPoint[0] && L'\0' == f->MountPoint[1] ? 0 : f->MountPoint);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot set " FSP_FUSE_LIBRARY_NAME " file system mount point.");
goto fail;
}
}
Result = FspFileSystemStartDispatcher(f->FileSystem, f->ThreadCount);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"Cannot start " FSP_FUSE_LIBRARY_NAME " file system dispatcher.");
goto fail;
}
return STATUS_SUCCESS;
fail:
fsp_fuse_loop_cleanup(f);
return Result;
}
static void fsp_fuse_loop_stop(struct fuse *f)
{
FspFileSystemStopDispatcher(f->FileSystem);
fsp_fuse_loop_cleanup(f);
}
static void fsp_fuse_loop_cleanup(struct fuse *f)
{
if (0 != f->FileSystem)
{
FspFileSystemDelete(f->FileSystem);
f->FileSystem = 0;
}
if (f->fsinit)
{
if (f->ops.destroy)
f->ops.destroy(f->data);
f->fsinit = FALSE;
}
if (0 != f->LoopEvent)
{
CloseHandle(f->LoopEvent);
f->LoopEvent = 0;
}
}
static NTSTATUS fsp_fuse_loop_internal(struct fuse *f)
{
HANDLE WaitObjects[2];
DWORD WaitResult;
NTSTATUS Result;
Result = fsp_fuse_loop_start(f);
if (!NT_SUCCESS(Result))
{
/* emulate WinFsp-FUSE v1.3 behavior! */
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"The service %s has failed to start (Status=%lx).", FspDiagIdent(), Result);
return Result;
}
InitOnceExecuteOnce(&fsp_fuse_svconce, fsp_fuse_svcinit, 0, 0);
if (0 == fsp_fuse_svcthread)
{
fsp_fuse_loop_stop(f);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* if either the service thread dies or our event gets signaled, stop the loop */
Result = STATUS_SUCCESS;
if (!f->exited)
{
WaitObjects[0] = fsp_fuse_svcthread;
WaitObjects[1] = f->LoopEvent;
WaitResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE);
if (WAIT_OBJECT_0 != WaitResult && WAIT_OBJECT_0 + 1 != WaitResult)
Result = FspNtStatusFromWin32(GetLastError());
}
fsp_fuse_loop_stop(f);
return Result;
}
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
struct fuse *f)
{
f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE;
return NT_SUCCESS(fsp_fuse_loop_internal(f)) ? 0 : -1;
}
FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env,
struct fuse *f)
{
f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE;
return NT_SUCCESS(fsp_fuse_loop_internal(f)) ? 0 : -1;
}
/* Cygwin signal support */
FSP_FUSE_API void fsp_fuse_signal_handler(int sig)
{
FspServiceConsoleCtrlHandler(CTRL_BREAK_EVENT);
}

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/fuse/library.h> #include <dll/fuse/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/fuse/library.h> #include <dll/fuse/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_DLL_FUSE_LIBRARY_H_INCLUDED #ifndef WINFSP_DLL_FUSE_LIBRARY_H_INCLUDED
@ -25,40 +29,52 @@
#define FSP_FUSE_LIBRARY_NAME LIBRARY_NAME "-FUSE" #define FSP_FUSE_LIBRARY_NAME LIBRARY_NAME "-FUSE"
#define FSP_FUSE_HDR_FROM_CONTEXT(c) \ #define FSP_FUSE_HDR_FROM_CONTEXT(c) \
(struct fsp_fuse_context_header *)((PUINT8)(c) - sizeof(struct fsp_fuse_context_header)) ((struct fsp_fuse_context_header *)((PUINT8)(c) - sizeof(struct fsp_fuse_context_header)))
#define FSP_FUSE_CONTEXT_FROM_HDR(h) \ #define FSP_FUSE_CONTEXT_FROM_HDR(h) \
(struct fuse_context *)((PUINT8)(h) + sizeof(struct fsp_fuse_context_header)) ((struct fuse_context *)((PUINT8)(h) + sizeof(struct fsp_fuse_context_header)))
#define FSP_FUSE_HAS_SYMLINKS(f) (0 != (f)->ops.readlink) #define FSP_FUSE_HAS_SYMLINKS(f) ((f)->has_symlinks)
#define ENOSYS_(env) ('C' == (env)->environment ? 88 : 40)
/* NFS reparse points */
#define NFS_SPECFILE_FIFO 0x000000004F464946
#define NFS_SPECFILE_CHR 0x0000000000524843
#define NFS_SPECFILE_BLK 0x00000000004b4c42
#define NFS_SPECFILE_LNK 0x00000000014b4e4c
#define NFS_SPECFILE_SOCK 0x000000004B434F53
/* FUSE internal struct's */
struct fuse struct fuse
{ {
struct fsp_fuse_env *env; struct fsp_fuse_env *env;
int set_umask, umask; int set_umask, umask;
int set_create_umask, create_umask;
int set_uid, uid; int set_uid, uid;
int set_gid, gid; int set_gid, gid;
int rellinks; int rellinks;
unsigned ThreadCount;
struct fuse_operations ops; struct fuse_operations ops;
void *data; void *data;
unsigned conn_want; unsigned conn_want;
BOOLEAN fsinit; BOOLEAN fsinit;
BOOLEAN has_symlinks;
UINT32 DebugLog; UINT32 DebugLog;
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
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)];
PWSTR MountPoint; PWSTR MountPoint;
HANDLE LoopEvent;
FSP_FILE_SYSTEM *FileSystem; FSP_FILE_SYSTEM *FileSystem;
FSP_SERVICE *Service; /* weak */
volatile int exited; volatile int exited;
struct fuse3 *fuse3;
}; };
struct fsp_fuse_context_header struct fsp_fuse_context_header
{ {
char *PosixPath; char *PosixPath;
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ContextBuf[]; __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ContextBuf[];
}; };
struct fsp_fuse_file_desc struct fsp_fuse_file_desc
{ {
char *PosixPath; char *PosixPath;
@ -67,7 +83,6 @@ struct fsp_fuse_file_desc
UINT64 FileHandle; UINT64 FileHandle;
PVOID DirBuffer; PVOID DirBuffer;
}; };
struct fuse_dirhandle struct fuse_dirhandle
{ {
/* ReadDirectory */ /* ReadDirectory */
@ -79,24 +94,82 @@ struct fuse_dirhandle
BOOLEAN DotFiles, HasChild; BOOLEAN DotFiles, HasChild;
}; };
/* FUSE obj alloc/free */
struct fsp_fuse_obj_hdr
{
void (*dtor)(void *);
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ObjectBuf[];
};
static inline void *fsp_fuse_obj_alloc(struct fsp_fuse_env *env, size_t size)
{
struct fsp_fuse_obj_hdr *hdr;
hdr = env->memalloc(sizeof(struct fsp_fuse_obj_hdr) + size);
if (0 == hdr)
return 0;
hdr->dtor = env->memfree;
memset(hdr->ObjectBuf, 0, size);
return hdr->ObjectBuf;
}
static inline void fsp_fuse_obj_free(void *obj)
{
if (0 == obj)
return;
struct fsp_fuse_obj_hdr *hdr = (PVOID)((PUINT8)obj - sizeof(struct fsp_fuse_obj_hdr));
hdr->dtor(hdr);
}
/* fsp_fuse_get_context_internal */
extern DWORD fsp_fuse_tlskey;
static inline struct fuse_context *fsp_fuse_get_context_internal(void)
{
return TlsGetValue(fsp_fuse_tlskey);
}
/* fsp_fuse_core_opt_parse */
struct fsp_fuse_core_opt_data
{
struct fsp_fuse_env *env;
int help, debug;
HANDLE DebugLogHandle;
int set_umask, umask,
set_create_umask, create_umask,
set_uid, uid,
set_gid, gid,
set_attr_timeout, attr_timeout,
rellinks;
int set_FileInfoTimeout,
set_DirInfoTimeout,
set_VolumeInfoTimeout,
set_KeepFileCache;
unsigned ThreadCount;
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
UINT16 VolumeLabelLength;
WCHAR VolumeLabel[sizeof ((FSP_FSCTL_VOLUME_INFO *)0)->VolumeLabel / sizeof(WCHAR)];
};
FSP_FSCTL_STATIC_ASSERT(
sizeof ((struct fuse *)0)->VolumeLabel == sizeof ((struct fsp_fuse_core_opt_data *)0)->VolumeLabel,
"fuse::VolumeLabel and fsp_fuse_core_opt_data::VolumeLabel: sizeof must be same.");
int fsp_fuse_core_opt_parse(struct fsp_fuse_env *env,
struct fuse_args *args, struct fsp_fuse_core_opt_data *opt_data,
int help);
/* misc public symbols */
NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
int fsp_fuse_intf_CanDeleteAddDirInfo(void *buf, const char *name,
extern FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf; const struct fuse_stat *stbuf, fuse_off_t off);
int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off);
NTSTATUS fsp_fuse_get_token_uidgid( NTSTATUS fsp_fuse_get_token_uidgid(
HANDLE Token, HANDLE Token,
TOKEN_INFORMATION_CLASS UserOrOwnerClass, /* TokenUser|TokenOwner */ TOKEN_INFORMATION_CLASS UserOrOwnerClass, /* TokenUser|TokenOwner */
PUINT32 PUid, PUINT32 PGid); PUINT32 PUid, PUINT32 PGid);
extern FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf;
/* NFS reparse points */
#define NFS_SPECFILE_FIFO 0x000000004F464946
#define NFS_SPECFILE_CHR 0x0000000000524843
#define NFS_SPECFILE_BLK 0x00000000004b4c42
#define NFS_SPECFILE_LNK 0x00000000014b4e4c
#define NFS_SPECFILE_SOCK 0x000000004B434F53
#endif #endif

660
src/dll/fuse3/fuse2to3.c Normal file
View File

@ -0,0 +1,660 @@
/**
* @file dll/fuse3/fuse2to3.c
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dll/fuse3/library.h>
static inline struct fuse3 *fuse2to3_getfuse3(void)
{
return fsp_fuse_get_context_internal()->fuse->fuse3;
}
static inline void fuse2to3_fi2from3(struct fuse_file_info *fi, struct fuse3_file_info *fi3)
{
memset(fi, 0, sizeof *fi);
fi->flags = fi3->flags;
fi->writepage = fi3->writepage;
fi->direct_io = fi3->direct_io;
fi->keep_cache = fi3->keep_cache;
fi->flush = fi3->flush;
fi->nonseekable = fi3->nonseekable;
fi->fh = fi3->fh;
fi->lock_owner = fi3->lock_owner;
}
static inline void fuse2to3_fi3from2(struct fuse3_file_info *fi3, struct fuse_file_info *fi)
{
memset(fi3, 0, sizeof *fi3);
fi3->flags = fi->flags;
fi3->writepage = fi->writepage;
fi3->direct_io = fi->direct_io;
fi3->keep_cache = fi->keep_cache;
fi3->flush = fi->flush;
fi3->nonseekable = fi->nonseekable;
fi3->fh = fi->fh;
fi3->lock_owner = fi->lock_owner;
}
static inline void fuse2to3_conn3from2(struct fuse3_conn_info *conn3, struct fuse_conn_info *conn)
{
memset(conn3, 0, sizeof *conn3);
conn3->proto_major = 7; /* pretend that we are FUSE kernel protocol 7.26 */
conn3->proto_minor = 26; /* which was current at the time of FUSE 3.2 */
conn3->max_write = conn->max_write;
conn3->max_read = conn->max_write;
conn3->max_readahead = conn->max_readahead;
conn3->capable = (conn->capable & ~FSP_FUSE_CAP_READDIR_PLUS) | FUSE_CAP_READDIRPLUS;
conn3->want = conn->want;
}
static int fuse2to3_getattr(const char *path, struct fuse_stat *stbuf)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.getattr(path, stbuf, 0);
}
static int fuse2to3_readlink(const char *path, char *buf, size_t size)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.readlink(path, buf, size);
}
static int fuse2to3_mknod(const char *path, fuse_mode_t mode, fuse_dev_t dev)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.mknod(path, mode, dev);
}
static int fuse2to3_mkdir(const char *path, fuse_mode_t mode)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.mkdir(path, mode);
}
static int fuse2to3_unlink(const char *path)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.unlink(path);
}
static int fuse2to3_rmdir(const char *path)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.rmdir(path);
}
static int fuse2to3_symlink(const char *dstpath, const char *srcpath)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.symlink(dstpath, srcpath);
}
static int fuse2to3_rename(const char *oldpath, const char *newpath)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.rename(oldpath, newpath, 0);
}
static int fuse2to3_link(const char *srcpath, const char *dstpath)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.link(srcpath, dstpath);
}
static int fuse2to3_chmod(const char *path, fuse_mode_t mode)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.chmod(path, mode, 0);
}
static int fuse2to3_chown(const char *path, fuse_uid_t uid, fuse_gid_t gid)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.chown(path, uid, gid, 0);
}
static int fuse2to3_truncate(const char *path, fuse_off_t size)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.truncate(path, size, 0);
}
static int fuse2to3_open(const char *path, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.open(path, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_read(const char *path, char *buf, size_t size, fuse_off_t off,
struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.read(path, buf, size, off, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_write(const char *path, const char *buf, size_t size, fuse_off_t off,
struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.write(path, buf, size, off, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_statfs(const char *path, struct fuse_statvfs *stbuf)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.statfs(path, stbuf);
}
static int fuse2to3_flush(const char *path, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.flush(path, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_release(const char *path, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.release(path, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_fsync(const char *path, int datasync, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.fsync(path, datasync, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_setxattr(const char *path, const char *name, const char *value, size_t size,
int flags)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.setxattr(path, name, value, size, flags);
}
static int fuse2to3_getxattr(const char *path, const char *name, char *value, size_t size)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.getxattr(path, name, value, size);
}
static int fuse2to3_listxattr(const char *path, char *namebuf, size_t size)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.listxattr(path, namebuf, size);
}
static int fuse2to3_removexattr(const char *path, const char *name)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.removexattr(path, name);
}
static int fuse2to3_opendir(const char *path, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.opendir(path, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_candel_filldir(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off,
enum fuse3_fill_dir_flags flags)
{
return fsp_fuse_intf_CanDeleteAddDirInfo(buf, name, 0, off);
}
static int fuse2to3_filldir(void *buf, const char *name,
const struct fuse_stat *stbuf, fuse_off_t off,
enum fuse3_fill_dir_flags flags)
{
return 0 != (flags & FUSE_FILL_DIR_PLUS) ?
fsp_fuse_intf_AddDirInfo(buf, name, stbuf, off) :
fsp_fuse_intf_AddDirInfo(buf, name, 0, off);
}
static int fuse2to3_readdir(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse_dirhandle *dh = buf;
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res;
if (fsp_fuse_intf_CanDeleteAddDirInfo == filler)
res = f3->ops.readdir(path, buf, &fuse2to3_candel_filldir, off, &fi3, 0);
else if (fsp_fuse_intf_AddDirInfo == filler)
res = f3->ops.readdir(path, buf, &fuse2to3_filldir, off, &fi3,
dh->ReaddirPlus ? FUSE_READDIR_PLUS : 0);
else
{
FspDebugLog("fuse2to3_readdir = -ENOSYS (internal error: unknown filler)\n");
res = -ENOSYS_(f3->fuse->env);
}
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_releasedir(const char *path, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.releasedir(path, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_fsyncdir(const char *path, int datasync, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.fsyncdir(path, datasync, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static void *fuse2to3_init(struct fuse_conn_info *conn)
{
struct fuse_context *context = fsp_fuse_get_context_internal();
struct fuse *f = context->fuse;
struct fuse3 *f3 = f->fuse3;
struct fuse3_conn_info conn3;
fuse2to3_conn3from2(&conn3, conn);
struct fuse3_config conf3;
memset(&conf3, 0, sizeof conf3);
conf3.set_gid = f->set_gid;
conf3.gid = f->gid;
conf3.set_uid = f->set_uid;
conf3.uid = f->uid;
conf3.set_mode = f->set_umask;
conf3.umask = f->umask;
#if 0
/*
* Cannot set timeouts because of lack of floating point support.
*
* FUSE uses the `double` type for timeouts. This DLL does not use the standard library
* for a variety of reasons. This means that we cannot easily perform the computations
* below.
*
* If this becomes important (double) floating point values could perhaps be calculated
* using bit tricks. See below:
* - http://locklessinc.com/articles/i2f/
* - https://stackoverflow.com/a/20308114
*/
conf3.entry_timeout = f->VolumeParams.DirInfoTimeoutValid ?
f->VolumeParams.DirInfoTimeout / 1000 : f->VolumeParams.FileInfoTimeout / 1000;
conf3.negative_timeout = 0;
conf3.attr_timeout = f->VolumeParams.FileInfoTimeout / 1000;
conf3.ac_attr_timeout = conf3.attr_timeout;
#endif
void *res = f3->ops.init(&conn3, &conf3);
conn->max_write = conn3.max_write;
conn->max_readahead = conn3.max_readahead;
conn->want = 0 != (conn3.want & FUSE_CAP_READDIRPLUS) ? FSP_FUSE_CAP_READDIR_PLUS : 0;
conn->want |= conn3.want & ~FUSE_CAP_READDIRPLUS;
return res;
}
static void fuse2to3_destroy(void *data)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
f3->ops.destroy(data);
}
static int fuse2to3_access(const char *path, int mask)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.access(path, mask);
}
static int fuse2to3_create(const char *path, fuse_mode_t mode, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.create(path, mode, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_ftruncate(const char *path, fuse_off_t off, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.truncate(path, off, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_fgetattr(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.getattr(path, stbuf, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_lock(const char *path,
struct fuse_file_info *fi, int cmd, struct fuse_flock *lock)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.lock(path, &fi3, cmd, lock);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_utimens(const char *path, const struct fuse_timespec tv[2])
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.utimens(path, tv, 0);
}
static int fuse2to3_bmap(const char *path, size_t blocksize, uint64_t *idx)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
return f3->ops.bmap(path, blocksize, idx);
}
static int fuse2to3_ioctl(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
unsigned int flags, void *data)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.ioctl(path, cmd, arg, &fi3, flags, data);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_poll(const char *path, struct fuse_file_info *fi,
struct fuse_pollhandle *ph, unsigned *reventsp)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.poll(path, &fi3, (struct fuse3_pollhandle *)ph, reventsp);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_write_buf(const char *path,
struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.write_buf(path,
(struct fuse3_bufvec *)buf, /* revisit if we implement bufvec's */
off, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_read_buf(const char *path,
struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.read_buf(path,
(struct fuse3_bufvec **)bufp, /* revisit if we implement bufvec's */
size, off, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_flock(const char *path, struct fuse_file_info *fi, int op)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.flock(path, &fi3, op);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fuse2to3_fallocate(const char *path, int mode, fuse_off_t off, fuse_off_t len,
struct fuse_file_info *fi)
{
struct fuse3 *f3 = fuse2to3_getfuse3();
struct fuse3_file_info fi3;
fuse2to3_fi3from2(&fi3, fi);
int res = f3->ops.fallocate(path, mode, off, len, &fi3);
fuse2to3_fi2from3(fi, &fi3);
return res;
}
static int fsp_fuse3_copy_args(struct fsp_fuse_env *env,
const struct fuse_args *args,
struct fuse_args *outargs)
{
outargs->argc = 0;
outargs->argv = 0;
outargs->allocated = 0;
for (int argi = 0; args->argc > argi; argi++)
if (-1 == fsp_fuse_opt_add_arg(env, outargs, args->argv[argi]))
goto fail;
return 0;
fail:
fsp_fuse_opt_free_args(env, outargs);
return -1;
}
static struct fuse3 *fsp_fuse3_new_common(struct fsp_fuse_env *env,
struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data,
int help)
{
/* preflight args */
struct fsp_fuse_core_opt_data opt_data;
struct fuse_args pfargs;
memset(&opt_data, 0, sizeof opt_data);
if (-1 == fsp_fuse3_copy_args(env, args, &pfargs))
return 0;
int optres = fsp_fuse_core_opt_parse(env, &pfargs, &opt_data, /*help=*/1);
fsp_fuse_opt_free_args(env, &pfargs);
if (-1 == optres)
return 0;
if (opt_data.help)
return 0;
struct fuse3 *f3 = 0;
if (opsize > sizeof(struct fuse3_operations))
opsize = sizeof(struct fuse3_operations);
f3 = fsp_fuse_obj_alloc(env, sizeof *f3);
if (0 == f3)
goto fail;
if (-1 == fsp_fuse3_copy_args(env, args, &f3->args))
goto fail;
memcpy(&f3->ops, ops, opsize);
f3->data = data;
return f3;
fail:
if (0 != f3)
fsp_fuse3_destroy(env, f3);
return 0;
}
FSP_FUSE_API struct fuse3 *fsp_fuse3_new_30(struct fsp_fuse_env *env,
struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data)
{
return fsp_fuse3_new_common(env, args, ops, opsize, data, /*help=*/1);
}
FSP_FUSE_API struct fuse3 *fsp_fuse3_new(struct fsp_fuse_env *env,
struct fuse_args *args,
const struct fuse3_operations *ops, size_t opsize, void *data)
{
return fsp_fuse3_new_common(env, args, ops, opsize, data, /*help=*/0);
}
FSP_FUSE_API void fsp_fuse3_destroy(struct fsp_fuse_env *env,
struct fuse3 *f3)
{
if (0 != f3->fuse)
fsp_fuse_destroy(env, f3->fuse);
fsp_fuse_opt_free_args(env, &f3->args);
fsp_fuse_obj_free(f3);
}
FSP_FUSE_API int fsp_fuse3_mount(struct fsp_fuse_env *env,
struct fuse3 *f3, const char *mountpoint)
{
struct fuse_chan *ch = 0;
struct fuse *f = 0;
struct fuse_operations fuse2to3_ops =
{
.getattr = 0 != f3->ops.getattr ? fuse2to3_getattr : 0,
.readlink = 0 != f3->ops.readlink ? fuse2to3_readlink : 0,
.mknod = 0 != f3->ops.mknod ? fuse2to3_mknod : 0,
.mkdir = 0 != f3->ops.mkdir ? fuse2to3_mkdir : 0,
.unlink = 0 != f3->ops.unlink ? fuse2to3_unlink : 0,
.rmdir = 0 != f3->ops.rmdir ? fuse2to3_rmdir : 0,
.symlink = 0 != f3->ops.symlink ? fuse2to3_symlink : 0,
.rename = 0 != f3->ops.rename ? fuse2to3_rename : 0,
.link = 0 != f3->ops.link ? fuse2to3_link : 0,
.chmod = 0 != f3->ops.chmod ? fuse2to3_chmod : 0,
.chown = 0 != f3->ops.chown ? fuse2to3_chown : 0,
.truncate = 0 != f3->ops.truncate ? fuse2to3_truncate : 0,
.open = 0 != f3->ops.open ? fuse2to3_open : 0,
.read = 0 != f3->ops.read ? fuse2to3_read : 0,
.write = 0 != f3->ops.write ? fuse2to3_write : 0,
.statfs = 0 != f3->ops.statfs ? fuse2to3_statfs : 0,
.flush = 0 != f3->ops.flush ? fuse2to3_flush : 0,
.release = 0 != f3->ops.release ? fuse2to3_release : 0,
.fsync = 0 != f3->ops.fsync ? fuse2to3_fsync : 0,
.setxattr = 0 != f3->ops.setxattr ? fuse2to3_setxattr : 0,
.getxattr = 0 != f3->ops.getxattr ? fuse2to3_getxattr : 0,
.listxattr = 0 != f3->ops.listxattr ? fuse2to3_listxattr : 0,
.removexattr = 0 != f3->ops.removexattr ? fuse2to3_removexattr : 0,
.opendir = 0 != f3->ops.opendir ? fuse2to3_opendir : 0,
.readdir = 0 != f3->ops.readdir ? fuse2to3_readdir : 0,
.releasedir = 0 != f3->ops.releasedir ? fuse2to3_releasedir : 0,
.fsyncdir = 0 != f3->ops.fsyncdir ? fuse2to3_fsyncdir : 0,
.init = 0 != f3->ops.init ? fuse2to3_init : 0,
.destroy = 0 != f3->ops.destroy ? fuse2to3_destroy : 0,
.access = 0 != f3->ops.access ? fuse2to3_access : 0,
.create = 0 != f3->ops.create ? fuse2to3_create : 0,
.ftruncate = 0 != f3->ops.truncate ? fuse2to3_ftruncate : 0,
.fgetattr = 0 != f3->ops.getattr ? fuse2to3_fgetattr : 0,
.lock = 0 != f3->ops.lock ? fuse2to3_lock : 0,
.utimens = 0 != f3->ops.utimens ? fuse2to3_utimens : 0,
.bmap = 0 != f3->ops.bmap ? fuse2to3_bmap : 0,
.ioctl = 0 != f3->ops.ioctl ? fuse2to3_ioctl : 0,
.poll = 0 != f3->ops.poll ? fuse2to3_poll : 0,
.write_buf = 0 != f3->ops.write_buf ? fuse2to3_write_buf : 0,
.read_buf = 0 != f3->ops.read_buf ? fuse2to3_read_buf : 0,
.flock = 0 != f3->ops.flock ? fuse2to3_flock : 0,
.fallocate = 0 != f3->ops.fallocate ? fuse2to3_fallocate : 0,
};
ch = fsp_fuse_mount(env, mountpoint, &f3->args);
if (0 == ch)
goto fail;
f = fsp_fuse_new(env, ch, &f3->args, &fuse2to3_ops, sizeof fuse2to3_ops, f3->data);
if (0 == f)
goto fail;
/*
* Free the fuse_chan which is no longer needed. Note that this behavior is WinFsp-FUSE
* specific, because WinFsp-FUSE only allocates/frees fuse_chan memory during fuse_mount/
* fuse_unmount and does not perform any actual mounting/unmounting. This would not work
* on a different FUSE implementation.
*
* (Store mountpoint and ch inside struct fuse3 so that they can be freed during fuse_destroy
* in that case.)
*/
fsp_fuse_unmount(env, mountpoint, ch);
/* Free the args which are no longer needed. */
fsp_fuse_opt_free_args(env, &f3->args);
f->fuse3 = f3;
f3->fuse = f;
return 0;
fail:
if (0 != f)
fsp_fuse_destroy(env, f);
if (0 != ch)
fsp_fuse_unmount(env, mountpoint, ch);
return -1;
}
FSP_FUSE_API void fsp_fuse3_unmount(struct fsp_fuse_env *env,
struct fuse3 *f3)
{
fsp_fuse_destroy(env, f3->fuse);
f3->fuse = 0;
}

158
src/dll/fuse3/fuse3.c Normal file
View File

@ -0,0 +1,158 @@
/**
* @file dll/fuse3/fuse3.c
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dll/fuse3/library.h>
FSP_FUSE_API int fsp_fuse3_main_real(struct fsp_fuse_env *env,
int argc, char *argv[],
const struct fuse3_operations *ops, size_t opsize, void *data)
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
char *mountpoint = 0;
int multithreaded = 0;
int foreground = 0;
struct fuse3 *f3 = 0;
int mounted = 0;
int signal_handlers = 0;
int result;
result = fsp_fuse_parse_cmdline(env, &args, &mountpoint, &multithreaded, &foreground);
if (-1 == result)
goto exit;
f3 = fsp_fuse3_new_30(env, &args, ops, opsize, data);
if (0 == f3)
{
result = -1;
goto exit;
}
result = fsp_fuse3_mount(env, f3, mountpoint);
if (-1 == result)
goto exit;
mounted = 1;
result = env->daemonize(foreground);
if (-1 == result)
goto exit;
result = env->set_signal_handlers(f3);
if (-1 == result)
goto exit;
signal_handlers = 1;
result = multithreaded ? fsp_fuse3_loop_mt(env, f3, 0) : fsp_fuse3_loop(env, f3);
exit:
if (signal_handlers)
env->set_signal_handlers(0);
if (mounted)
fsp_fuse3_unmount(env, f3);
if (0 != f3)
fsp_fuse3_destroy(env, f3);
env->memfree(mountpoint);
fsp_fuse_opt_free_args(env, &args);
/* main() style return: 0 success, 1 error */
return !!result;
}
FSP_FUSE_API void fsp_fuse3_lib_help(struct fsp_fuse_env *env,
struct fuse_args *args)
{
char *helpargv[] =
{
"UNKNOWN",
"-h",
0
};
struct fuse_args helpargs = FUSE_ARGS_INIT(2, helpargv);
struct fsp_fuse_core_opt_data opt_data;
memset(&opt_data, 0, sizeof opt_data);
fsp_fuse_core_opt_parse(env, &helpargs, &opt_data, /*help=*/1);
}
FSP_FUSE_API int fsp_fuse3_loop(struct fsp_fuse_env *env,
struct fuse3 *f3)
{
return 0 == fsp_fuse_loop(env, f3->fuse) ? 0 : -EINVAL/* same on MSVC and Cygwin */;
}
FSP_FUSE_API int fsp_fuse3_loop_mt_31(struct fsp_fuse_env *env,
struct fuse3 *f3, int clone_fd)
{
return 0 == fsp_fuse_loop_mt(env, f3->fuse) ? 0 : -EINVAL/* same on MSVC and Cygwin */;
}
FSP_FUSE_API int fsp_fuse3_loop_mt(struct fsp_fuse_env *env,
struct fuse3 *f3, struct fuse3_loop_config *config)
{
return 0 == fsp_fuse_loop_mt(env, f3->fuse) ? 0 : -EINVAL/* same on MSVC and Cygwin */;
}
FSP_FUSE_API void fsp_fuse3_exit(struct fsp_fuse_env *env,
struct fuse3 *f3)
{
fsp_fuse_exit(env, f3->fuse);
}
FSP_FUSE_API struct fuse3_context *fsp_fuse3_get_context(struct fsp_fuse_env *env)
{
FSP_FSCTL_STATIC_ASSERT(
sizeof(struct fuse_context) == sizeof(struct fuse3_context),
"incompatible structs fuse_context and fuse3_context");
FSP_FSCTL_STATIC_ASSERT(FIELD_OFFSET(
struct fuse_context, private_data) == FIELD_OFFSET(struct fuse3_context, private_data),
"incompatible structs fuse_context and fuse3_context");
return (struct fuse3_context *)fsp_fuse_get_context(env);
}
FSP_FUSE_API struct fuse3_conn_info_opts *fsp_fuse3_parse_conn_info_opts(
struct fsp_fuse_env *env,
struct fuse_args *args)
{
static int dummy;
return (struct fuse3_conn_info_opts *)&dummy;
}
FSP_FUSE_API void fsp_fuse3_apply_conn_info_opts(struct fsp_fuse_env *env,
struct fuse3_conn_info_opts *opts, struct fuse3_conn_info *conn)
{
}
FSP_FUSE_API int fsp_fuse3_version(struct fsp_fuse_env *env)
{
return FUSE_VERSION;
}
FSP_FUSE_API const char *fsp_fuse3_pkgversion(struct fsp_fuse_env *env)
{
#define STR(x) STR_(x)
#define STR_(x) #x
return STR(FUSE_MAJOR_VERSION) "." STR(FUSE_MINOR_VERSION);
#undef STR_
#undef STR
}

10
src/dll/fuse3/fuse3.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=${pcfiledir}/..
incdir=${prefix}/inc/fuse3
implib=${prefix}/bin/winfsp-${arch}.dll
Name: fuse3
Description: WinFsp FUSE3 compatible API
Version: 3.2
URL: http://www.secfs.net/winfsp/
Libs: "${implib}"
Cflags: -I"${incdir}"

View File

@ -0,0 +1,38 @@
/**
* @file dll/fuse/fuse3_compat.c
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <dll/library.h>
/*
* This file provides an implementation of the `fuse3_*` symbols. This
* implementation is a simple shim that forwards `fuse3_*` calls to the
* equivalent `fsp_fuse3_*` ones using a default `fsp_fuse_env`.
*
* These symbols should *not* be used by C/C++ programs. For this reason
* the `fuse.h` headers only expose the `fsp_fuse3_*` symbols, wrapped
* with macros. These symbols are for use only from programs using FFI
* technology to access FUSE symbols (e.g. fusepy, jnr-fuse).
*/
#define FSP_FUSE_API
#define FSP_FUSE_SYM(proto, ...) __declspec(dllexport) proto { __VA_ARGS__ }
#include <fuse3/fuse_common.h>
#include <fuse3/fuse.h>

41
src/dll/fuse3/library.h Normal file
View File

@ -0,0 +1,41 @@
/**
* @file dll/fuse3/library.h
*
* @copyright 2015-2018 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef WINFSP_DLL_FUSE3_LIBRARY_H_INCLUDED
#define WINFSP_DLL_FUSE3_LIBRARY_H_INCLUDED
#include <dll/fuse/library.h>
#undef FUSE_H_
#undef FUSE_COMMON_H_
#undef FUSE_MAJOR_VERSION
#undef FUSE_MINOR_VERSION
#undef fuse_main
#include <fuse3/fuse.h>
struct fuse3
{
struct fuse_args args;
struct fuse3_operations ops;
void *data;
struct fuse *fuse;
};
#endif

View File

@ -10,16 +10,31 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
FSP_API NTSTATUS FspLaunchCallLauncherPipe( FSP_API NTSTATUS FspLaunchCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize, PULONG PLauncherError) PWSTR Buffer, PULONG PSize,
PULONG PLauncherError)
{
return FspLaunchCallLauncherPipeEx(
Command, Argc, Argv, Argl, Buffer, PSize, FALSE, PLauncherError);
}
FSP_API NTSTATUS FspLaunchCallLauncherPipeEx(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation,
PULONG PLauncherError)
{ {
PWSTR PipeBuf = 0, P; PWSTR PipeBuf = 0, P;
ULONG Length, BytesTransferred; ULONG Length, BytesTransferred;
@ -49,9 +64,9 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe(
memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0'; memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0';
} }
Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, Result = FspCallNamedPipeSecurelyEx(L"" FSP_LAUNCH_PIPE_NAME,
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE,
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, AllowImpersonation, FSP_LAUNCH_PIPE_OWNER);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -98,8 +113,17 @@ exit:
} }
FSP_API NTSTATUS FspLaunchStart( FSP_API NTSTATUS FspLaunchStart(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv,
BOOLEAN HasSecret,
PULONG PLauncherError)
{
return FspLaunchStartEx(ClassName, InstanceName, Argc, Argv, HasSecret, FALSE, PLauncherError);
}
FSP_API NTSTATUS FspLaunchStartEx(
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0, PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0,
BOOLEAN HasSecret, BOOLEAN HasSecret,
BOOLEAN AllowImpersonation,
PULONG PLauncherError) PULONG PLauncherError)
{ {
PWSTR Argv[9 + 2]; PWSTR Argv[9 + 2];
@ -111,9 +135,9 @@ FSP_API NTSTATUS FspLaunchStart(
Argv[1] = InstanceName; Argv[1] = InstanceName;
memcpy(Argv + 2, Argv0, Argc * sizeof(PWSTR)); memcpy(Argv + 2, Argv0, Argc * sizeof(PWSTR));
return FspLaunchCallLauncherPipe( return FspLaunchCallLauncherPipeEx(
HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart,
Argc + 2, Argv, 0, 0, 0, PLauncherError); Argc + 2, Argv, 0, 0, 0, AllowImpersonation, PLauncherError);
} }
FSP_API NTSTATUS FspLaunchStop( FSP_API NTSTATUS FspLaunchStop(
@ -246,8 +270,10 @@ FSP_API NTSTATUS FspLaunchRegSetRecord(
SETFIELD(WorkDirectory); SETFIELD(WorkDirectory);
SETFIELD(RunAs); SETFIELD(RunAs);
SETFIELD(Security); SETFIELD(Security);
SETFIELD(AuthPackage);
SETFIELDI(JobControl, ~0); /* JobControl default is 1; but we treat as without default */ SETFIELDI(JobControl, ~0); /* JobControl default is 1; but we treat as without default */
SETFIELDI(Credentials, 0); SETFIELDI(Credentials, 0);
SETFIELDI(AuthPackageId, 0);
} }
else else
{ {
@ -396,8 +422,10 @@ FSP_API NTSTATUS FspLaunchRegGetRecord(
GETFIELD(WorkDirectory); GETFIELD(WorkDirectory);
GETFIELD(RunAs); GETFIELD(RunAs);
GETFIELD(Security); GETFIELD(Security);
GETFIELD(AuthPackage);
GETFIELDI(JobControl); GETFIELDI(JobControl);
GETFIELDI(Credentials); GETFIELDI(Credentials);
GETFIELDI(AuthPackageId);
if (0 == Record->Executable) if (0 == Record->Executable)
{ {
@ -426,8 +454,11 @@ FSP_API NTSTATUS FspLaunchRegGetRecord(
(PVOID)(Record->Buffer + ((PUINT8)RecordBuf.RunAs - RegBuf)) : 0; (PVOID)(Record->Buffer + ((PUINT8)RecordBuf.RunAs - RegBuf)) : 0;
Record->Security = 0 != RecordBuf.Security ? Record->Security = 0 != RecordBuf.Security ?
(PVOID)(Record->Buffer + ((PUINT8)RecordBuf.Security - RegBuf)) : 0; (PVOID)(Record->Buffer + ((PUINT8)RecordBuf.Security - RegBuf)) : 0;
Record->AuthPackage = 0 != RecordBuf.AuthPackage ?
(PVOID)(Record->Buffer + ((PUINT8)RecordBuf.AuthPackage - RegBuf)) : 0;
Record->JobControl = RecordBuf.JobControl; Record->JobControl = RecordBuf.JobControl;
Record->Credentials = RecordBuf.Credentials; Record->Credentials = RecordBuf.Credentials;
Record->AuthPackageId = RecordBuf.AuthPackageId;
*PRecord = Record; *PRecord = Record;
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -42,6 +46,7 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
Dynamic = 0 == Reserved; Dynamic = 0 == Reserved;
fsp_fuse_finalize(Dynamic); fsp_fuse_finalize(Dynamic);
FspServiceFinalize(Dynamic); FspServiceFinalize(Dynamic);
FspFileSystemFinalize(Dynamic);
FspEventLogFinalize(Dynamic); FspEventLogFinalize(Dynamic);
FspPosixFinalize(Dynamic); FspPosixFinalize(Dynamic);
FspWksidFinalize(Dynamic); FspWksidFinalize(Dynamic);

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_DLL_LIBRARY_H_INCLUDED #ifndef WINFSP_DLL_LIBRARY_H_INCLUDED
@ -43,6 +47,7 @@
VOID FspWksidFinalize(BOOLEAN Dynamic); VOID FspWksidFinalize(BOOLEAN Dynamic);
VOID FspPosixFinalize(BOOLEAN Dynamic); VOID FspPosixFinalize(BOOLEAN Dynamic);
VOID FspEventLogFinalize(BOOLEAN Dynamic); VOID FspEventLogFinalize(BOOLEAN Dynamic);
VOID FspFileSystemFinalize(BOOLEAN Dynamic);
VOID FspServiceFinalize(BOOLEAN Dynamic); VOID FspServiceFinalize(BOOLEAN Dynamic);
VOID fsp_fuse_finalize(BOOLEAN Dynamic); VOID fsp_fuse_finalize(BOOLEAN Dynamic);
VOID fsp_fuse_finalize_thread(VOID); VOID fsp_fuse_finalize_thread(VOID);

View File

@ -10,15 +10,22 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
#include <npapi.h> #include <npapi.h>
#include <wincred.h> #include <wincred.h>
#define _NTDEF_
#include <ntsecapi.h>
#define FSP_NP_NAME LIBRARY_NAME ".Np" #define FSP_NP_NAME LIBRARY_NAME ".Np"
#define FSP_NP_TYPE ' spF' /* pick a value hopefully not in use */ #define FSP_NP_TYPE ' spF' /* pick a value hopefully not in use */
#define FSP_NP_ADDCONNECTION_TIMEOUT 15000 #define FSP_NP_ADDCONNECTION_TIMEOUT 15000
@ -175,12 +182,14 @@ static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName,
static inline DWORD FspNpCallLauncherPipe( static inline DWORD FspNpCallLauncherPipe(
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
PWSTR Buffer, PULONG PSize) PWSTR Buffer, PULONG PSize,
BOOLEAN AllowImpersonation)
{ {
NTSTATUS Result; NTSTATUS Result;
ULONG ErrorCode; ULONG ErrorCode;
Result = FspLaunchCallLauncherPipe(Command, Argc, Argv, Argl, Buffer, PSize, &ErrorCode); Result = FspLaunchCallLauncherPipeEx(Command, Argc, Argv, Argl, Buffer, PSize, AllowImpersonation,
&ErrorCode);
return !NT_SUCCESS(Result) ? return !NT_SUCCESS(Result) ?
WN_NO_NETWORK : WN_NO_NETWORK :
(ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode); (ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode);
@ -247,7 +256,50 @@ static WCHAR FspNpGetDriveLetter(PDWORD PLogicalDrives, PWSTR VolumeName)
return 0; return 0;
} }
static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind) static NTSTATUS FspNpGetAuthPackage(PWSTR AuthPackageName, PULONG PAuthPackage)
{
HANDLE LsaHandle;
BOOLEAN LsaHandleValid = FALSE;
CHAR LsaAuthPackageNameBuf[127]; /* "The package name must not exceed 127 bytes in length." */
LSA_STRING LsaAuthPackageName;
ULONG AuthPackage;
NTSTATUS Result;
*PAuthPackage = 0;
Result = LsaConnectUntrusted(&LsaHandle);
if (!NT_SUCCESS(Result))
goto exit;
LsaHandleValid = TRUE;
LsaAuthPackageName.MaximumLength = sizeof LsaAuthPackageNameBuf;
LsaAuthPackageName.Buffer = LsaAuthPackageNameBuf;
LsaAuthPackageName.Length = WideCharToMultiByte(CP_UTF8, 0,
AuthPackageName, lstrlenW(AuthPackageName),
LsaAuthPackageNameBuf, sizeof LsaAuthPackageNameBuf,
0, 0);
if (0 == LsaAuthPackageName.Length)
{
Result = FspNtStatusFromWin32(GetLastError());
goto exit;
}
Result = LsaLookupAuthenticationPackage(LsaHandle, &LsaAuthPackageName, &AuthPackage);
if (!NT_SUCCESS(Result))
goto exit;
*PAuthPackage = AuthPackage;
Result = STATUS_SUCCESS;
exit:
if (LsaHandleValid)
LsaDeregisterLogonProcess(LsaHandle);
return Result;
}
static DWORD FspNpGetRemoteInfo(PWSTR RemoteName,
PDWORD PAuthPackage, PDWORD PCredentialsKind, PBOOLEAN PAllowImpersonation)
{ {
PWSTR ClassName, InstanceName; PWSTR ClassName, InstanceName;
ULONG ClassNameLen, InstanceNameLen; ULONG ClassNameLen, InstanceNameLen;
@ -255,7 +307,14 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
FSP_LAUNCH_REG_RECORD *Record; FSP_LAUNCH_REG_RECORD *Record;
NTSTATUS Result; NTSTATUS Result;
*PCredentialsKind = FSP_NP_CREDENTIALS_NONE; if (0 != PAuthPackage)
*PAuthPackage = 0;
if (0 != PCredentialsKind)
*PCredentialsKind = FSP_NP_CREDENTIALS_NONE;
if (0 != PAllowImpersonation)
*PAllowImpersonation = FALSE;
if (!FspNpParseRemoteName(RemoteName, if (!FspNpParseRemoteName(RemoteName,
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen)) &ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
@ -270,15 +329,36 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return WN_NO_NETWORK; return WN_NO_NETWORK;
switch (Record->Credentials) if (0 != PAuthPackage)
{ {
case FSP_NP_CREDENTIALS_NONE: if (0 != Record->AuthPackage)
case FSP_NP_CREDENTIALS_PASSWORD: {
case FSP_NP_CREDENTIALS_USERPASS: ULONG AuthPackage = 0;
*PCredentialsKind = Record->Credentials;
break; Result = FspNpGetAuthPackage(Record->AuthPackage, &AuthPackage);
if (!NT_SUCCESS(Result))
return WN_NO_NETWORK;
*PAuthPackage = AuthPackage + 1; /* ensure non-0 (Negotiate AuthPackage == 0) */
}
else if (0 != Record->AuthPackageId)
*PAuthPackage = Record->AuthPackageId + 1; /* ensure non-0 (Negotiate AuthPackage == 0) */
} }
if (0 != PCredentialsKind)
switch (Record->Credentials)
{
case FSP_NP_CREDENTIALS_NONE:
case FSP_NP_CREDENTIALS_PASSWORD:
case FSP_NP_CREDENTIALS_USERPASS:
*PCredentialsKind = Record->Credentials;
break;
}
if (0 != PAllowImpersonation)
*PAllowImpersonation = 0 != Record->RunAs &&
L'.' == Record->RunAs[0] && L'\0' == Record->RunAs[1];
FspLaunchRegFreeRecord(Record); FspLaunchRegFreeRecord(Record);
return WN_SUCCESS; return WN_SUCCESS;
@ -286,7 +366,7 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
static DWORD FspNpGetCredentials( static DWORD FspNpGetCredentials(
HWND hwndOwner, PWSTR Caption, DWORD PrevNpResult, HWND hwndOwner, PWSTR Caption, DWORD PrevNpResult,
DWORD CredentialsKind, DWORD AuthPackage0, DWORD CredentialsKind,
PBOOL PSave, PBOOL PSave,
PWSTR UserName, ULONG UserNameSize/* in chars */, PWSTR UserName, ULONG UserNameSize/* in chars */,
PWSTR Password, ULONG PasswordSize/* in chars */) PWSTR Password, ULONG PasswordSize/* in chars */)
@ -313,7 +393,7 @@ static DWORD FspNpGetCredentials(
(FSP_NP_CREDENTIALS_PASSWORD == CredentialsKind ? 0/*CREDUI_FLAGS_KEEP_USERNAME*/ : 0)); (FSP_NP_CREDENTIALS_PASSWORD == CredentialsKind ? 0/*CREDUI_FLAGS_KEEP_USERNAME*/ : 0));
#else #else
WCHAR Domain[CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1]; WCHAR Domain[CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1];
ULONG AuthPackage = 0; ULONG AuthPackage = 0 != AuthPackage0 ? AuthPackage0 - 1 : 0;
PVOID InAuthBuf = 0, OutAuthBuf = 0; PVOID InAuthBuf = 0, OutAuthBuf = 0;
ULONG InAuthSize, OutAuthSize, DomainSize; ULONG InAuthSize, OutAuthSize, DomainSize;
@ -342,7 +422,8 @@ static DWORD FspNpGetCredentials(
NpResult = CredUIPromptForWindowsCredentialsW(&UiInfo, PrevNpResult, NpResult = CredUIPromptForWindowsCredentialsW(&UiInfo, PrevNpResult,
&AuthPackage, InAuthBuf, InAuthSize, &OutAuthBuf, &OutAuthSize, PSave, &AuthPackage, InAuthBuf, InAuthSize, &OutAuthBuf, &OutAuthSize, PSave,
CREDUIWIN_GENERIC | (0 != PSave ? CREDUIWIN_CHECKBOX : 0)); (0 != AuthPackage0 ? CREDUIWIN_AUTHPACKAGE_ONLY : CREDUIWIN_GENERIC) |
(0 != PSave ? CREDUIWIN_CHECKBOX : 0));
if (ERROR_SUCCESS != NpResult) if (ERROR_SUCCESS != NpResult)
goto exit; goto exit;
@ -460,6 +541,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
PWSTR ClassName, InstanceName, RemoteName, P; PWSTR ClassName, InstanceName, RemoteName, P;
ULONG ClassNameLen, InstanceNameLen; ULONG ClassNameLen, InstanceNameLen;
DWORD CredentialsKind; DWORD CredentialsKind;
BOOLEAN AllowImpersonation;
ULONG Argc; ULONG Argc;
PWSTR Argv[6]; PWSTR Argv[6];
ULONG Argl[6]; ULONG Argl[6];
@ -489,7 +571,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
return WN_ALREADY_CONNECTED; return WN_ALREADY_CONNECTED;
} }
NpResult = FspNpGetRemoteInfo(lpRemoteName, &CredentialsKind); NpResult = FspNpGetRemoteInfo(lpRemoteName, 0, &CredentialsKind, &AllowImpersonation);
if (WN_SUCCESS != NpResult) if (WN_SUCCESS != NpResult)
return NpResult; return NpResult;
@ -546,7 +628,8 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
NpResult = FspNpCallLauncherPipe( NpResult = FspNpCallLauncherPipe(
FSP_NP_CREDENTIALS_NONE != CredentialsKind ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, FSP_NP_CREDENTIALS_NONE != CredentialsKind ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart,
Argc, Argv, Argl, 0, 0); Argc, Argv, Argl, 0, 0,
AllowImpersonation);
switch (NpResult) switch (NpResult)
{ {
case WN_SUCCESS: case WN_SUCCESS:
@ -598,7 +681,8 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
if (WN_SUCCESS != FspNpCallLauncherPipe( if (WN_SUCCESS != FspNpCallLauncherPipe(
FspLaunchCmdGetInfo, FspLaunchCmdGetInfo,
Argc, Argv, Argl, 0, 0)) Argc, Argv, Argl, 0, 0,
FALSE))
{ {
/* looks like the file system is gone! */ /* looks like the file system is gone! */
NpResult = WN_NO_NETWORK; NpResult = WN_NO_NETWORK;
@ -655,7 +739,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
{ {
DWORD NpResult; DWORD NpResult;
PWSTR RemoteName = lpNetResource->lpRemoteName; PWSTR RemoteName = lpNetResource->lpRemoteName;
DWORD 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 = TRUE;
@ -675,7 +759,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
return NpResult; return NpResult;
} }
NpResult = FspNpGetRemoteInfo(RemoteName, &CredentialsKind); NpResult = FspNpGetRemoteInfo(RemoteName, &AuthPackage, &CredentialsKind, 0);
if (WN_SUCCESS != NpResult) if (WN_SUCCESS != NpResult)
return NpResult; return NpResult;
if (FSP_NP_CREDENTIALS_NONE == CredentialsKind) if (FSP_NP_CREDENTIALS_NONE == CredentialsKind)
@ -691,7 +775,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
{ {
NpResult = FspNpGetCredentials( NpResult = FspNpGetCredentials(
hwndOwner, RemoteName, NpResult, hwndOwner, RemoteName, NpResult,
CredentialsKind, AuthPackage, CredentialsKind,
#if defined(FSP_NP_CREDENTIAL_MANAGER) #if defined(FSP_NP_CREDENTIAL_MANAGER)
&Save, &Save,
#else #else
@ -762,7 +846,8 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
NpResult = FspNpCallLauncherPipe( NpResult = FspNpCallLauncherPipe(
FspLaunchCmdStop, FspLaunchCmdStop,
Argc, Argv, Argl, 0, 0); Argc, Argv, Argl, 0, 0,
FALSE);
switch (NpResult) switch (NpResult)
{ {
case WN_SUCCESS: case WN_SUCCESS:

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -23,9 +23,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -337,26 +341,25 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
if (Request->Req.Create.UserMode) if (Request->Req.Create.UserMode)
{ {
if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY)) if (FILE_ATTRIBUTE_READONLY == (FileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY)) &&
(DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD)))
{ {
if (DesiredAccess & Result = STATUS_ACCESS_DENIED;
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD)) goto exit;
{ }
Result = STATUS_ACCESS_DENIED;
goto exit; if (FILE_ATTRIBUTE_READONLY == (FileAttributes & FILE_ATTRIBUTE_READONLY) &&
} (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE))
if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) {
{ Result = STATUS_CANNOT_DELETE;
Result = STATUS_CANNOT_DELETE; goto exit;
goto exit;
}
} }
if (0 == SecurityDescriptorSize) if (0 == SecurityDescriptorSize)
*PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ? *PGrantedAccess = (MAXIMUM_ALLOWED & DesiredAccess) ?
FspFileGenericMapping.GenericAll : DesiredAccess; FspFileGenericMapping.GenericAll : DesiredAccess;
if (0 != (FileAttributes & FILE_ATTRIBUTE_READONLY) && if (FILE_ATTRIBUTE_READONLY == (FileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY)) &&
0 != (MAXIMUM_ALLOWED & DesiredAccess)) 0 != (MAXIMUM_ALLOWED & DesiredAccess))
*PGrantedAccess &= ~(FILE_WRITE_DATA | FILE_APPEND_DATA | *PGrantedAccess &= ~(FILE_WRITE_DATA | FILE_APPEND_DATA |
FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD); FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD);

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -251,7 +255,7 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
/* ENTER CONSOLE MODE! */ /* ENTER CONSOLE MODE! */
/* create/reset the console mode event and console control handler */ /* create the console mode event and console control handler */
if (0 == FspServiceConsoleModeEvent) if (0 == FspServiceConsoleModeEvent)
{ {
FspServiceConsoleModeEvent = CreateEventW(0, TRUE, FALSE, 0); FspServiceConsoleModeEvent = CreateEventW(0, TRUE, FALSE, 0);
@ -267,12 +271,14 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
goto console_mode_exit; goto console_mode_exit;
} }
} }
#if 0
else else
{ {
ResetEvent(FspServiceConsoleModeEvent); ResetEvent(FspServiceConsoleModeEvent);
FspServiceConsoleCtrlHandlerDisabled = 0; FspServiceConsoleCtrlHandlerDisabled = 0;
MemoryBarrier(); MemoryBarrier();
} }
#endif
/* prepare the command line arguments */ /* prepare the command line arguments */
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>
@ -63,6 +67,16 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, PULONG PBytesTransferred, ULONG Timeout,
PSID Sid) PSID Sid)
{
return FspCallNamedPipeSecurelyEx(PipeName,
InBuffer, InBufferSize, OutBuffer, OutBufferSize, PBytesTransferred, Timeout,
FALSE, Sid);
}
FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName,
PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize,
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
PSID Sid)
{ {
NTSTATUS Result; NTSTATUS Result;
HANDLE Pipe = INVALID_HANDLE_VALUE; HANDLE Pipe = INVALID_HANDLE_VALUE;
@ -71,7 +85,8 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
Pipe = CreateFileW(PipeName, Pipe = CreateFileW(PipeName,
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0); SECURITY_SQOS_PRESENT | (AllowImpersonation ? SECURITY_IMPERSONATION : SECURITY_IDENTIFICATION),
0);
if (INVALID_HANDLE_VALUE == Pipe) if (INVALID_HANDLE_VALUE == Pipe)
{ {
if (ERROR_PIPE_BUSY != GetLastError()) if (ERROR_PIPE_BUSY != GetLastError())
@ -85,7 +100,8 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
Pipe = CreateFileW(PipeName, Pipe = CreateFileW(PipeName,
GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES, GENERIC_READ | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, 0); SECURITY_SQOS_PRESENT | (AllowImpersonation ? SECURITY_IMPERSONATION : SECURITY_IDENTIFICATION),
0);
if (INVALID_HANDLE_VALUE == Pipe) if (INVALID_HANDLE_VALUE == Pipe)
{ {
Result = FspNtStatusFromWin32(GetLastError()); Result = FspNtStatusFromWin32(GetLastError());

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <dll/library.h> #include <dll/library.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
using System; using System;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
using System; using System;
@ -337,6 +341,7 @@ namespace Fsp
/// These flags determine whether the file was modified and whether to delete the file. /// These flags determine whether the file was modified and whether to delete the file.
/// </param> /// </param>
/// <seealso cref="CanDelete"/> /// <seealso cref="CanDelete"/>
/// <seealso cref="SetDelete"/>
/// <seealso cref="Close"/> /// <seealso cref="Close"/>
public virtual void Cleanup( public virtual void Cleanup(
Object FileNode, Object FileNode,
@ -591,6 +596,22 @@ namespace Fsp
/// <summary> /// <summary>
/// Determines whether a file or directory can be deleted. /// Determines whether a file or directory can be deleted.
/// </summary> /// </summary>
/// <remarks>
/// <para>
/// 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
/// directories, etc.
/// </para><para>
/// This function should <b>NEVER</b> delete the file or directory in question. Deletion should
/// happen during Cleanup with the FspCleanupDelete flag set.
/// </para><para>
/// 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.
/// </para><para>
/// NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However
/// most file systems need only implement the CanDelete operation.
/// </para>
/// </remarks>
/// <param name="FileNode"> /// <param name="FileNode">
/// The file node of the file or directory to test for deletion. /// The file node of the file or directory to test for deletion.
/// </param> /// </param>
@ -602,6 +623,7 @@ namespace Fsp
/// </param> /// </param>
/// <returns>STATUS_SUCCESS or error code.</returns> /// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="Cleanup"/> /// <seealso cref="Cleanup"/>
/// <seealso cref="SetDelete"/>
public virtual Int32 CanDelete( public virtual Int32 CanDelete(
Object FileNode, Object FileNode,
Object FileDesc, Object FileDesc,
@ -685,7 +707,7 @@ namespace Fsp
/// Describes the modifications to apply to the file or directory security descriptor. /// Describes the modifications to apply to the file or directory security descriptor.
/// </param> /// </param>
/// <returns>STATUS_SUCCESS or error code.</returns> /// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="ModifySecurityDescriptor"/> /// <seealso cref="ModifySecurityDescriptorEx"/>
public virtual Int32 SetSecurity( public virtual Int32 SetSecurity(
Object FileNode, Object FileNode,
Object FileDesc, Object FileDesc,
@ -966,6 +988,96 @@ namespace Fsp
FileInfo = default(FileInfo); FileInfo = default(FileInfo);
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
/// <summary>
/// Processes a control code.
/// </summary>
/// <remarks>
/// This function is called when a program uses the DeviceIoControl API.
/// </remarks>
/// <param name="FileNode">
/// The file node of the file or directory to be controled.
/// </param>
/// <param name="FileDesc">
/// The file descriptor of the file or directory to be controled.
/// </param>
/// <param name="ControlCode">
/// The control code for the operation. This code must have a DeviceType with bit
/// 0x8000 set and must have a TransferType of METHOD_BUFFERED.
/// </param>
/// <param name="InputBuffer">
/// Pointer to a buffer that contains the input data.
/// </param>
/// <param name="InputBufferLength">
/// Input data length.
/// </param>
/// <param name="OutputBuffer">
/// Pointer to a buffer that will receive the output data.
/// </param>
/// <param name="OutputBufferLength">
/// Output data length.
/// </param>
/// <param name="BytesTransferred">
/// Receives the actual number of bytes transferred.
/// </param>
/// <returns>STATUS_SUCCESS or error code.</returns>
public virtual Int32 Control(
Object FileNode,
Object FileDesc,
UInt32 ControlCode,
IntPtr InputBuffer, UInt32 InputBufferLength,
IntPtr OutputBuffer, UInt32 OutputBufferLength,
out UInt32 BytesTransferred)
{
BytesTransferred = default(UInt32);
return STATUS_INVALID_DEVICE_REQUEST;
}
/// <summary>
/// Sets the file delete flag.
/// </summary>
/// <remarks>
/// <para>
/// 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
/// performs tasks such as check for empty directories, etc.
/// </para><para>
/// This function should <b>NEVER</b> delete the file or directory in question. Deletion should
/// happen during Cleanup with the FspCleanupDelete flag set.
/// </para><para>
/// 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.
/// </para><para>
/// NOTE: If both CanDelete and SetDelete are defined, SetDelete takes precedence. However
/// most file systems need only implement the CanDelete operation.
/// </para>
/// </remarks>
/// <param name="FileNode">
/// The file node of the file or directory to set the delete flag for.
/// </param>
/// <param name="FileDesc">
/// The file descriptor of the file or directory to set the delete flag for.
/// </param>
/// <param name="FileName">
/// The name of the file or directory to set the delete flag for.
/// </param>
/// <param name="DeleteFile">
/// If set to TRUE the FSD indicates that the file will be deleted on Cleanup; otherwise
/// it will not be deleted. It is legal to receive multiple SetDelete calls for the same
/// file with different DeleteFile parameters.
/// </param>
/// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="Cleanup"/>
/// <seealso cref="CanDelete"/>
public virtual Int32 SetDelete(
Object FileNode,
Object FileDesc,
String FileName,
Boolean DeleteFile)
{
if (DeleteFile)
return CanDelete(FileNode, FileDesc, FileName);
else
return STATUS_SUCCESS;
}
/* helpers */ /* helpers */
/// <summary> /// <summary>
@ -993,7 +1105,7 @@ namespace Fsp
return (int)Api.FspFileSystemOperationProcessId(); return (int)Api.FspFileSystemOperationProcessId();
} }
/// <summary> /// <summary>
/// Modifies a security descriptor. /// Modifies a security descriptor. [OBSOLETE]
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This is a helper for implementing the SetSecurity operation. /// This is a helper for implementing the SetSecurity operation.
@ -1009,6 +1121,7 @@ namespace Fsp
/// </param> /// </param>
/// <returns>The modified security descriptor.</returns> /// <returns>The modified security descriptor.</returns>
/// <seealso cref="SetSecurity"/> /// <seealso cref="SetSecurity"/>
[Obsolete("use ModifySecurityDescriptorEx")]
public static byte[] ModifySecurityDescriptor( public static byte[] ModifySecurityDescriptor(
Byte[] SecurityDescriptor, Byte[] SecurityDescriptor,
AccessControlSections Sections, AccessControlSections Sections,
@ -1028,6 +1141,47 @@ namespace Fsp
SecurityInformation, SecurityInformation,
ModificationDescriptor); ModificationDescriptor);
} }
/// <summary>
/// Modifies a security descriptor.
/// </summary>
/// <remarks>
/// This is a helper for implementing the SetSecurity operation.
/// </remarks>
/// <param name="SecurityDescriptor">
/// The original security descriptor.
/// </param>
/// <param name="Sections">
/// Describes what parts of the file or directory security descriptor should be modified.
/// </param>
/// <param name="ModificationDescriptor">
/// Describes the modifications to apply to the file or directory security descriptor.
/// </param>
/// <param name="ModifiedDescriptor">
/// The modified security descriptor. This parameter is modified only on success.
/// </param>
/// <returns>STATUS_SUCCESS or error code.</returns>
/// <seealso cref="SetSecurity"/>
public static Int32 ModifySecurityDescriptorEx(
Byte[] SecurityDescriptor,
AccessControlSections Sections,
Byte[] ModificationDescriptor,
ref Byte[] ModifiedDescriptor)
{
UInt32 SecurityInformation = 0;
if (0 != (Sections & AccessControlSections.Owner))
SecurityInformation |= 1/*OWNER_SECURITY_INFORMATION*/;
if (0 != (Sections & AccessControlSections.Group))
SecurityInformation |= 2/*GROUP_SECURITY_INFORMATION*/;
if (0 != (Sections & AccessControlSections.Access))
SecurityInformation |= 4/*DACL_SECURITY_INFORMATION*/;
if (0 != (Sections & AccessControlSections.Audit))
SecurityInformation |= 8/*SACL_SECURITY_INFORMATION*/;
return Api.ModifySecurityDescriptorEx(
SecurityDescriptor,
SecurityInformation,
ModificationDescriptor,
ref ModifiedDescriptor);
}
public Int32 SeekableReadDirectory( public Int32 SeekableReadDirectory(
Object FileNode, Object FileNode,
Object FileDesc, Object FileDesc,

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
using System; using System;
@ -194,6 +198,16 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryFileName); } get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryFileName); }
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryFileName : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryFileName : 0); }
} }
public Boolean FlushAndPurgeOnCleanup
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.FlushAndPurgeOnCleanup); }
set { _VolumeParams.Flags |= (value ? VolumeParams.FlushAndPurgeOnCleanup : 0); }
}
public Boolean DeviceControl
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.DeviceControl); }
set { _VolumeParams.Flags |= (value ? VolumeParams.DeviceControl : 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>
@ -347,6 +361,13 @@ namespace Fsp
{ {
return Api.SetDebugLogFile(FileName); return Api.SetDebugLogFile(FileName);
} }
/// <summary>
/// Return the installed version of WinFsp.
/// </summary>
public static Version Version()
{
return Api.GetVersion();
}
/* FSP_FILE_SYSTEM_INTERFACE */ /* FSP_FILE_SYSTEM_INTERFACE */
private static Byte[] ByteBufferNotNull = new Byte[0]; private static Byte[] ByteBufferNotNull = new Byte[0];
@ -733,26 +754,6 @@ namespace Fsp
return ExceptionHandler(FileSystem, ex); return ExceptionHandler(FileSystem, ex);
} }
} }
private static Int32 CanDelete(
IntPtr FileSystemPtr,
ref FullContext FullContext,
String FileName)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.CanDelete(
FileNode,
FileDesc,
FileName);
}
catch (Exception ex)
{
return ExceptionHandler(FileSystem, ex);
}
}
private static Int32 Rename( private static Int32 Rename(
IntPtr FileSystemPtr, IntPtr FileSystemPtr,
ref FullContext FullContext, ref FullContext FullContext,
@ -1020,6 +1021,57 @@ namespace Fsp
return ExceptionHandler(FileSystem, ex); return ExceptionHandler(FileSystem, ex);
} }
} }
private static Int32 Control(
IntPtr FileSystemPtr,
ref FullContext FullContext,
UInt32 ControlCode,
IntPtr InputBuffer, UInt32 InputBufferLength,
IntPtr OutputBuffer, UInt32 OutputBufferLength,
out UInt32 PBytesTransferred)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.Control(
FileNode,
FileDesc,
ControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
out PBytesTransferred);
}
catch (Exception ex)
{
PBytesTransferred = default(UInt32);
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);
}
}
static FileSystemHost() static FileSystemHost()
{ {
@ -1037,7 +1089,6 @@ namespace Fsp
_FileSystemInterface.GetFileInfo = GetFileInfo; _FileSystemInterface.GetFileInfo = GetFileInfo;
_FileSystemInterface.SetBasicInfo = SetBasicInfo; _FileSystemInterface.SetBasicInfo = SetBasicInfo;
_FileSystemInterface.SetFileSize = SetFileSize; _FileSystemInterface.SetFileSize = SetFileSize;
_FileSystemInterface.CanDelete = CanDelete;
_FileSystemInterface.Rename = Rename; _FileSystemInterface.Rename = Rename;
_FileSystemInterface.GetSecurity = GetSecurity; _FileSystemInterface.GetSecurity = GetSecurity;
_FileSystemInterface.SetSecurity = SetSecurity; _FileSystemInterface.SetSecurity = SetSecurity;
@ -1048,6 +1099,8 @@ namespace Fsp
_FileSystemInterface.DeleteReparsePoint = DeleteReparsePoint; _FileSystemInterface.DeleteReparsePoint = DeleteReparsePoint;
_FileSystemInterface.GetStreamInfo = GetStreamInfo; _FileSystemInterface.GetStreamInfo = GetStreamInfo;
_FileSystemInterface.GetDirInfoByName = GetDirInfoByName; _FileSystemInterface.GetDirInfoByName = GetDirInfoByName;
_FileSystemInterface.Control = Control;
_FileSystemInterface.SetDelete = SetDelete;
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size); _FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false); Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false);

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
using System; using System;
@ -43,6 +47,8 @@ namespace Fsp.Interop
internal const UInt32 PassQueryDirectoryPattern = 0x00000800; internal const UInt32 PassQueryDirectoryPattern = 0x00000800;
internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000; internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000;
internal const UInt32 PassQueryDirectoryFileName = 0x00002000; internal const UInt32 PassQueryDirectoryFileName = 0x00002000;
internal const UInt32 FlushAndPurgeOnCleanup = 0x00004000;
internal const UInt32 DeviceControl = 0x00008000;
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000; internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
internal const UInt32 UmFileContextIsFullContext = 0x00020000; internal const UInt32 UmFileContextIsFullContext = 0x00020000;
internal const int PrefixSize = 192; internal const int PrefixSize = 192;
@ -457,6 +463,20 @@ namespace Fsp.Interop
ref FullContext FullContext, ref FullContext FullContext,
[MarshalAs(UnmanagedType.LPWStr)] String FileName, [MarshalAs(UnmanagedType.LPWStr)] String FileName,
out DirInfo DirInfo); out DirInfo DirInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 Control(
IntPtr FileSystem,
ref FullContext FullContext,
UInt32 ControlCode,
IntPtr InputBuffer, UInt32 InputBufferLength,
IntPtr OutputBuffer, UInt32 OutputBufferLength,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 SetDelete(
IntPtr FileSystem,
ref FullContext FullContext,
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
[MarshalAs(UnmanagedType.U1)] Boolean DeleteFile);
} }
internal static int Size = IntPtr.Size * 64; internal static int Size = IntPtr.Size * 64;
@ -486,7 +506,9 @@ namespace Fsp.Interop
internal Proto.DeleteReparsePoint DeleteReparsePoint; internal Proto.DeleteReparsePoint DeleteReparsePoint;
internal Proto.GetStreamInfo GetStreamInfo; internal Proto.GetStreamInfo GetStreamInfo;
internal Proto.GetDirInfoByName GetDirInfoByName; internal Proto.GetDirInfoByName GetDirInfoByName;
/* NTSTATUS (*Reserved[39])(); */ internal Proto.Control Control;
internal Proto.SetDelete SetDelete;
/* NTSTATUS (*Reserved[37])(); */
} }
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -906,6 +928,26 @@ namespace Fsp.Interop
return SecurityDescriptorBytes; return SecurityDescriptorBytes;
} }
} }
internal unsafe static Int32 ModifySecurityDescriptorEx(
Byte[] SecurityDescriptorBytes,
UInt32 SecurityInformation,
Byte[] ModificationDescriptorBytes,
ref Byte[] ModifiedDescriptorBytes)
{
fixed (Byte *S = SecurityDescriptorBytes)
fixed (Byte *M = ModificationDescriptorBytes)
{
IntPtr SecurityDescriptor;
Int32 Result = FspSetSecurityDescriptor(
(IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
if (0 > Result)
return Result;
SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
ModifiedDescriptorBytes = SecurityDescriptorBytes;
return 0/*STATUS_SUCCESS*/;
}
}
internal unsafe static Int32 CopyReparsePoint( internal unsafe static Int32 CopyReparsePoint(
Byte[] ReparseData, Byte[] ReparseData,
@ -970,6 +1012,13 @@ namespace Fsp.Interop
return 0/*STATUS_SUCCESS*/; return 0/*STATUS_SUCCESS*/;
} }
internal static Version GetVersion()
{
UInt32 Version = 0;
FspVersion(out Version);
return new System.Version((Int32)Version >> 16, (Int32)Version & 0xFFFF);
}
/* initialization */ /* initialization */
private static IntPtr LoadDll() private static IntPtr LoadDll()
{ {

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
using System; using System;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <winfsp/winfsp.h> #include <winfsp/winfsp.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <winfsp/launch.h> #include <winfsp/launch.h>
@ -68,8 +72,8 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
NTSTATUS Result; NTSTATUS Result;
DWORD LastError, BytesTransferred; DWORD LastError, BytesTransferred;
Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize, Result = FspCallNamedPipeSecurelyEx(L"" FSP_LAUNCH_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, TRUE, FSP_LAUNCH_PIPE_OWNER);
LastError = FspWin32FromNtStatus(Result); LastError = FspWin32FromNtStatus(Result);
if (0 != LastError) if (0 != LastError)

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <winfsp/launch.h> #include <winfsp/launch.h>
@ -251,6 +255,7 @@ exit:
static BOOL LogonCreateProcess( static BOOL LogonCreateProcess(
PWSTR UserName, PWSTR UserName,
HANDLE Token,
LPCWSTR ApplicationName, LPCWSTR ApplicationName,
LPWSTR CommandLine, LPWSTR CommandLine,
LPSECURITY_ATTRIBUTES ProcessAttributes, LPSECURITY_ATTRIBUTES ProcessAttributes,
@ -267,11 +272,20 @@ static BOOL LogonCreateProcess(
if (0 != UserName) if (0 != UserName)
{ {
if (0 == invariant_wcsicmp(UserName, L"LocalSystem")) if (0 == invariant_wcsicmp(UserName, L"LocalSystem"))
{
UserName = 0; UserName = 0;
Token = 0;
}
else else
if (0 == invariant_wcsicmp(UserName, L"LocalService") || if (0 == invariant_wcsicmp(UserName, L"LocalService") ||
0 == invariant_wcsicmp(UserName, L"NetworkService")) 0 == invariant_wcsicmp(UserName, L"NetworkService"))
{
DomainName = L"NT AUTHORITY"; DomainName = L"NT AUTHORITY";
Token = 0;
}
else
if (0 == invariant_wcsicmp(UserName, L"."))
;
else else
{ {
SetLastError(ERROR_ACCESS_DENIED); SetLastError(ERROR_ACCESS_DENIED);
@ -295,18 +309,40 @@ static BOOL LogonCreateProcess(
HANDLE LogonToken = 0; HANDLE LogonToken = 0;
PVOID EnvironmentBlock = 0; PVOID EnvironmentBlock = 0;
DWORD SessionId;
DWORD LastError; DWORD LastError;
BOOL Success; BOOL Success;
Success = LogonUserW( if (0 == Token)
UserName, {
DomainName, Success = LogonUserW(
0, UserName,
LOGON32_LOGON_SERVICE, DomainName,
LOGON32_PROVIDER_DEFAULT, 0,
&LogonToken); LOGON32_LOGON_SERVICE,
if (!Success) LOGON32_PROVIDER_DEFAULT,
goto exit; &LogonToken);
if (!Success)
goto exit;
}
else
{
/* convert the impersonation token to a primary token */
Success = DuplicateTokenEx(Token,
TOKEN_ALL_ACCESS,
0,
SecurityAnonymous,
TokenPrimary,
&LogonToken);
if (!Success)
goto exit;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &SessionId))
SessionId = 0;
/* place the duplicated token in the service session (session 0) */
Success = SetTokenInformation(LogonToken, TokenSessionId, &SessionId, sizeof SessionId);
if (!Success)
goto exit;
}
if (0 == Environment) if (0 == Environment)
{ {
@ -659,7 +695,7 @@ static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
return Result; return Result;
} }
static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, HANDLE ClientToken,
PWSTR Executable, PWSTR CommandLine, PWSTR WorkDirectory, PWSTR Executable, PWSTR CommandLine, PWSTR WorkDirectory,
HANDLE StdioHandles[2], HANDLE StdioHandles[2],
PPROCESS_INFORMATION ProcessInfo) PPROCESS_INFORMATION ProcessInfo)
@ -754,7 +790,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1]; StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2]; StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, TRUE, Executable, CommandLine, 0, 0, TRUE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT,
0, WorkDirectory, 0, WorkDirectory,
@ -775,7 +811,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
* Not ideal, but... * Not ideal, but...
*/ */
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo; StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, TRUE, Executable, CommandLine, 0, 0, TRUE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
0, WorkDirectory, 0, WorkDirectory,
@ -788,7 +824,7 @@ static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
} }
else else
{ {
if (!LogonCreateProcess(UserName, if (!LogonCreateProcess(UserName, ClientToken,
Executable, CommandLine, 0, 0, FALSE, Executable, CommandLine, 0, 0, FALSE,
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
0, WorkDirectory, 0, WorkDirectory,
@ -1005,7 +1041,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0, Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0, ClientToken,
Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0, Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0,
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo); RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -1625,7 +1661,10 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
ClientToken = 0; ClientToken = 0;
if (!ImpersonateNamedPipeClient(SvcPipe) || if (!ImpersonateNamedPipeClient(SvcPipe) ||
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &ClientToken) || (
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE, FALSE, &ClientToken) &&
!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &ClientToken)
) ||
!RevertToSelf()) !RevertToSelf())
{ {
LastError = GetLastError(); LastError = GetLastError();

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_SHARED_MINIMAL_H_INCLUDED #ifndef WINFSP_SHARED_MINIMAL_H_INCLUDED

View File

@ -11,9 +11,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -294,7 +298,7 @@ VOID FspPropagateTopFlags(PIRP Irp, PIRP TopLevelIrp)
FspIrpSetTopFlags(Irp, FspFileNodeAcquireFull); FspIrpSetTopFlags(Irp, FspFileNodeAcquireFull);
} }
else if (IO_TYPE_IRP == TopLevelIrp->Type) else if ((PIRP)MM_SYSTEM_RANGE_START <= TopLevelIrp && IO_TYPE_IRP == TopLevelIrp->Type)
{ {
PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
PFILE_OBJECT TopLevelFileObject = IoGetCurrentIrpStackLocation(TopLevelIrp)->FileObject; PFILE_OBJECT TopLevelFileObject = IoGetCurrentIrpStackLocation(TopLevelIrp)->FileObject;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -123,6 +127,8 @@ static NTSTATUS FspFsvolCleanup(
FspFileNodeSetOwner(FileNode, Full, Request); FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestIrp) = Irp; FspIopRequestContext(Request, RequestIrp) = Irp;
FspFileNodeCleanupFlush(FileNode, FileObject);
if (Request->Req.Cleanup.Delete || if (Request->Req.Cleanup.Delete ||
Request->Req.Cleanup.SetAllocationSize || Request->Req.Cleanup.SetAllocationSize ||
Request->Req.Cleanup.SetArchiveBit || Request->Req.Cleanup.SetArchiveBit ||

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -65,6 +69,16 @@ FSP_DRIVER_DISPATCH FspCreate;
#pragma alloc_text(PAGE, FspCreate) #pragma alloc_text(PAGE, FspCreate)
#endif #endif
/*
* FSP_CREATE_REPARSE_POINT_ECP
*
* Define this macro to include code to fix file name case after crossing
* a reparse point as per http://online.osr.com/ShowThread.cfm?link=287522.
* Fixing this problem requires undocumented information; for this reason
* this fix is EXPERIMENTAL.
*/
#define FSP_CREATE_REPARSE_POINT_ECP
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX #define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR)) #define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
@ -122,8 +136,86 @@ static NTSTATUS FspFsvolCreate(
{ {
PAGED_CODE(); PAGED_CODE();
NTSTATUS Result = STATUS_SUCCESS; NTSTATUS Result;
BOOLEAN MainFileOpen = FspMainFileOpenCheck(Irp); PECP_LIST ExtraCreateParameters;
PVOID ExtraCreateParameter;
BOOLEAN MainFileOpen = FALSE;
/*
* Check if the IRP has ECP's.
*
* We do this check for the following reason:
*
* - To determine whether this is a "main file open", i.e. the opening
* of the main file for a stream. In this case this is a reentrant open
* and we should be careful not to try to acquire the rename resource,
* which is already acquired (otherwise DEADLOCK).
*
* - To determine whether this is an open after crossing a reparse point
* (e.g. when the file system is mounted as a directory). Unfortunately
* Windows does not preserve file name case in this case and sends us
* UPPERCASE file names, which results in all kinds of problems, esp.
* for case-sensitive file systems.
*/
ExtraCreateParameters = 0;
Result = FsRtlGetEcpListFromIrp(Irp, &ExtraCreateParameters);
if (NT_SUCCESS(Result) && 0 != ExtraCreateParameters)
{
ExtraCreateParameter = 0;
MainFileOpen =
NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspMainFileOpenEcpGuid, &ExtraCreateParameter, 0)) &&
0 != ExtraCreateParameter &&
!FsRtlIsEcpFromUserMode(ExtraCreateParameter);
#if defined(FSP_CREATE_REPARSE_POINT_ECP)
if (!FspHasReparsePointCaseSensitivityFix)
{
// {73d5118a-88ba-439f-92f4-46d38952d250}
static const GUID FspReparsePointEcpGuid =
{ 0x73d5118a, 0x88ba, 0x439f, { 0x92, 0xf4, 0x46, 0xd3, 0x89, 0x52, 0xd2, 0x50 } };
typedef struct _REPARSE_POINT_ECP
{
USHORT UnparsedNameLength;
USHORT Flags;
USHORT DeviceNameLength;
PVOID Reserved;
UNICODE_STRING Name;
} REPARSE_POINT_ECP;
REPARSE_POINT_ECP *ReparsePointEcp;
ExtraCreateParameter = 0;
ReparsePointEcp =
NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspReparsePointEcpGuid, &ExtraCreateParameter, 0)) &&
0 != ExtraCreateParameter &&
!FsRtlIsEcpFromUserMode(ExtraCreateParameter) ?
ExtraCreateParameter : 0;
if (0 != ReparsePointEcp)
{
//DEBUGLOG("%hu %wZ", ReparsePointEcp->UnparsedNameLength, ReparsePointEcp->Name);
UNICODE_STRING FileName = IrpSp->FileObject->FileName;
if (0 != ReparsePointEcp->UnparsedNameLength &&
FileName.Length == ReparsePointEcp->UnparsedNameLength &&
ReparsePointEcp->Name.Length > ReparsePointEcp->UnparsedNameLength)
{
/*
* If the ReparsePointEcp name and our file name differ only in case,
* go ahead and overwrite our file name.
*/
UNICODE_STRING UnparsedName;
UnparsedName.Length = UnparsedName.MaximumLength = ReparsePointEcp->UnparsedNameLength;
UnparsedName.Buffer = (PWCH)((UINT8 *)ReparsePointEcp->Name.Buffer +
(ReparsePointEcp->Name.Length - UnparsedName.Length));
if (0 == FspFileNameCompare(&UnparsedName, &FileName, TRUE, 0))
RtlMoveMemory(FileName.Buffer, UnparsedName.Buffer, UnparsedName.Length);
}
}
}
#endif
}
if (!MainFileOpen) if (!MainFileOpen)
{ {

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>

View File

@ -10,30 +10,120 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
static NTSTATUS FspFsvrtDeviceControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolDeviceControl( static NTSTATUS FspFsvolDeviceControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete; FSP_IOCMPL_DISPATCH FspFsvolDeviceControlComplete;
static FSP_IOP_REQUEST_FINI FspFsvolDeviceControlRequestFini;
FSP_DRIVER_DISPATCH FspDeviceControl; FSP_DRIVER_DISPATCH FspDeviceControl;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvrtDeviceControl)
#pragma alloc_text(PAGE, FspFsvolDeviceControl) #pragma alloc_text(PAGE, FspFsvolDeviceControl)
#pragma alloc_text(PAGE, FspFsvolDeviceControlComplete) #pragma alloc_text(PAGE, FspFsvolDeviceControlComplete)
#pragma alloc_text(PAGE, FspFsvolDeviceControlRequestFini)
#pragma alloc_text(PAGE, FspDeviceControl) #pragma alloc_text(PAGE, FspDeviceControl)
#endif #endif
static NTSTATUS FspFsvolDeviceControl( enum
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) {
RequestFileNode = 0,
};
static NTSTATUS FspFsvrtDeviceControl(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; /*
* Fix GitHub issue #177. All credit for the investigation of this issue
* and the suggested steps to reproduce and work around the problem goes
* to GitHub user @thinkport.
*
* When Windows attempts to mount a new volume it iterates over all disk file
* systems registered with IoRegisterFileSystem. Foreign (i.e. non-WinFsp) file
* systems would in some cases attempt to mount our Fsvrt volume device by
* sending it unknown IOCTL codes, which would then be failed with
* STATUS_INVALID_DEVICE_REQUEST. Unfortunately the file systems would then
* report this error code to the I/O Manager, which would cause it to abort the
* mounting process completely and thus WinFsp would never get a chance to
* mount its own volume device!
*/
return STATUS_UNRECOGNIZED_VOLUME;
}
static NTSTATUS FspFsvolDeviceControl(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFILE_OBJECT FileObject = IrpSp->FileObject;
ULONG IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
/* do we support DeviceControl? */
if (!FsvolDeviceExtension->VolumeParams.DeviceControl)
return STATUS_INVALID_DEVICE_REQUEST;
/* do not forward IRP's originating in the kernel! */
if (KernelMode == Irp->RequestorMode)
return STATUS_INVALID_DEVICE_REQUEST;
/* only allow custom devices and METHOD_BUFFERED */
if (0 == (DEVICE_TYPE_FROM_CTL_CODE(IoControlCode) & 0x8000) ||
METHOD_BUFFERED != METHOD_FROM_CTL_CODE(IoControlCode))
return STATUS_INVALID_DEVICE_REQUEST;
/* is this a valid FileObject? */
if (!FspFileNodeIsValid(FileObject->FsContext))
return STATUS_INVALID_PARAMETER;
NTSTATUS Result;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
PVOID InputBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
FSP_FSCTL_TRANSACT_REQ *Request;
ASSERT(FileNode == FileDesc->FileNode);
if (FSP_FSCTL_DEVICECONTROL_SIZEMAX < InputBufferLength ||
FSP_FSCTL_DEVICECONTROL_SIZEMAX < OutputBufferLength)
return STATUS_INVALID_BUFFER_SIZE;
Result = FspIopCreateRequestEx(Irp, 0, InputBufferLength,
FspFsvolDeviceControlRequestFini, &Request);
if (!NT_SUCCESS(Result))
return Result;
FspFileNodeAcquireShared(FileNode, Full);
Request->Kind = FspFsctlTransactDeviceControlKind;
Request->Req.DeviceControl.UserContext = FileNode->UserContext;
Request->Req.DeviceControl.UserContext2 = FileDesc->UserContext2;
Request->Req.DeviceControl.IoControlCode = IoControlCode;
Request->Req.DeviceControl.Buffer.Offset = 0;
Request->Req.DeviceControl.Buffer.Size = (UINT16)InputBufferLength;
Request->Req.DeviceControl.OutputLength = OutputBufferLength;
RtlCopyMemory(Request->Buffer, InputBuffer, InputBufferLength);
FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode;
return FSP_STATUS_IOQ_POST;
} }
NTSTATUS FspFsvolDeviceControlComplete( NTSTATUS FspFsvolDeviceControlComplete(
@ -41,12 +131,46 @@ NTSTATUS FspFsvolDeviceControlComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); FSP_ENTER_IOC(PAGED_CODE());
if (!NT_SUCCESS(Response->IoStatus.Status))
{
Irp->IoStatus.Information = 0;
Result = Response->IoStatus.Status;
FSP_RETURN();
}
PVOID OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (Response->Buffer + Response->Rsp.DeviceControl.Buffer.Offset +
Response->Rsp.DeviceControl.Buffer.Size > (PUINT8)Response + Response->Size)
FSP_RETURN(Result = STATUS_INTERNAL_ERROR);
if (OutputBufferLength >= Response->Rsp.DeviceControl.Buffer.Size)
OutputBufferLength = Response->Rsp.DeviceControl.Buffer.Size;
else
Result = STATUS_BUFFER_OVERFLOW;
RtlCopyMemory(OutputBuffer, Response->Buffer + Response->Rsp.DeviceControl.Buffer.Offset,
OutputBufferLength);
Irp->IoStatus.Information = OutputBufferLength;
FSP_LEAVE_IOC( FSP_LEAVE_IOC(
"%s, FileObject=%p", "%s, FileObject=%p",
IoctlCodeSym(IrpSp->Parameters.DeviceIoControl.IoControlCode), IoctlCodeSym(IrpSp->Parameters.DeviceIoControl.IoControlCode),
IrpSp->FileObject); IrpSp->FileObject);
} }
static VOID FspFsvolDeviceControlRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{
PAGED_CODE();
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
if (0 != FileNode)
FspFileNodeReleaseOwner(FileNode, Full, Request);
}
NTSTATUS FspDeviceControl( NTSTATUS FspDeviceControl(
PDEVICE_OBJECT DeviceObject, PIRP Irp) PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
@ -56,6 +180,8 @@ NTSTATUS FspDeviceControl(
{ {
case FspFsvolDeviceExtensionKind: case FspFsvolDeviceExtensionKind:
FSP_RETURN(Result = FspFsvolDeviceControl(DeviceObject, Irp, IrpSp)); FSP_RETURN(Result = FspFsvolDeviceControl(DeviceObject, Irp, IrpSp));
case FspFsvrtDeviceExtensionKind:
FSP_RETURN(Result = FspFsvrtDeviceControl(DeviceObject, Irp, IrpSp));
default: default:
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
} }

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -346,7 +350,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
FsvolDeviceExtension->InitDoneIoq = 1; FsvolDeviceExtension->InitDoneIoq = 1;
/* create our security meta cache */ /* create our security meta cache */
SecurityTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout); SecurityTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.SecurityTimeout);
/* convert millis to nanos */ /* convert millis to nanos */
Result = FspMetaCacheCreate( Result = FspMetaCacheCreate(
FspFsvolDeviceSecurityCacheCapacity, FspFsvolDeviceSecurityCacheItemSizeMax, &SecurityTimeout, FspFsvolDeviceSecurityCacheCapacity, FspFsvolDeviceSecurityCacheItemSizeMax, &SecurityTimeout,
@ -356,7 +360,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
FsvolDeviceExtension->InitDoneSec = 1; FsvolDeviceExtension->InitDoneSec = 1;
/* create our directory meta cache */ /* create our directory meta cache */
DirInfoTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout); DirInfoTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.DirInfoTimeout);
/* convert millis to nanos */ /* convert millis to nanos */
Result = FspMetaCacheCreate( Result = FspMetaCacheCreate(
FspFsvolDeviceDirInfoCacheCapacity, FspFsvolDeviceDirInfoCacheItemSizeMax, &DirInfoTimeout, FspFsvolDeviceDirInfoCacheCapacity, FspFsvolDeviceDirInfoCacheItemSizeMax, &DirInfoTimeout,
@ -366,7 +370,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
FsvolDeviceExtension->InitDoneDir = 1; FsvolDeviceExtension->InitDoneDir = 1;
/* create our stream info meta cache */ /* create our stream info meta cache */
StreamInfoTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout); StreamInfoTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.StreamInfoTimeout);
/* convert millis to nanos */ /* convert millis to nanos */
Result = FspMetaCacheCreate( Result = FspMetaCacheCreate(
FspFsvolDeviceStreamInfoCacheCapacity, FspFsvolDeviceStreamInfoCacheItemSizeMax, &StreamInfoTimeout, FspFsvolDeviceStreamInfoCacheCapacity, FspFsvolDeviceStreamInfoCacheItemSizeMax, &StreamInfoTimeout,
@ -873,7 +877,7 @@ VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VO
KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql); KeAcquireSpinLock(&FsvolDeviceExtension->InfoSpinLock, &Irql);
FsvolDeviceExtension->VolumeInfo = VolumeInfoNp; FsvolDeviceExtension->VolumeInfo = VolumeInfoNp;
FsvolDeviceExtension->InfoExpirationTime = FspExpirationTimeFromMillis( FsvolDeviceExtension->InfoExpirationTime = FspExpirationTimeFromMillis(
FsvolDeviceExtension->VolumeParams.FileInfoTimeout); FsvolDeviceExtension->VolumeParams.VolumeInfoTimeout);
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql); KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
} }

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -551,7 +555,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR); FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR);
QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8); QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8);
ASSERT(QueryDirectoryLengthMin < FspFsvolQueryDirectoryLengthMax); ASSERT(QueryDirectoryLengthMin < FspFsvolQueryDirectoryLengthMax);
if (0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && if (0 != FsvolDeviceExtension->VolumeParams.DirInfoTimeout &&
0 == FileDesc->DirectoryMarker.Buffer) 0 == FileDesc->DirectoryMarker.Buffer)
{ {
if (PatternIsFileName) if (PatternIsFileName)

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -165,6 +169,21 @@ NTSTATUS DriverEntry(
&FspFsmupDeviceObject); &FspFsmupDeviceObject);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
#if DBG
/*
* Fix GitHub issue #177. All credit for the investigation of this issue
* and the suggested steps to reproduce and work around the problem goes
* to GitHub user @thinkport.
*
* On debug builds set DO_LOW_PRIORITY_FILESYSTEM to place the file system
* at the end of the file system list during IoRegisterFileSystem below.
* This allows us to test the behavior of our Fsvrt devices when foreign
* file systems attempt to use them for mounting.
*/
SetFlag(FspFsctlDiskDeviceObject->Flags, DO_LOW_PRIORITY_FILESYSTEM);
#endif
Result = FspDeviceInitialize(FspFsctlDiskDeviceObject); Result = FspDeviceInitialize(FspFsctlDiskDeviceObject);
ASSERT(STATUS_SUCCESS == Result); ASSERT(STATUS_SUCCESS == Result);
Result = FspDeviceInitialize(FspFsctlNetDeviceObject); Result = FspDeviceInitialize(FspFsctlNetDeviceObject);
@ -229,6 +248,9 @@ static VOID FspDriverMultiVersionInitialize(VOID)
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8)) if (RtlIsNtDdiVersionAvailable(NTDDI_WIN8))
FspMvMdlMappingNoWrite = MdlMappingNoWrite; FspMvMdlMappingNoWrite = MdlMappingNoWrite;
if (RtlIsNtDdiVersionAvailable(0x0A000005/*NTDDI_WIN10_RS4*/))
FspHasReparsePointCaseSensitivityFix = TRUE;
} }
#if defined(FSP_UNLOAD) #if defined(FSP_UNLOAD)
@ -266,3 +288,4 @@ CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
ULONG FspProcessorCount; ULONG FspProcessorCount;
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
ULONG FspMvMdlMappingNoWrite = 0; ULONG FspMvMdlMappingNoWrite = 0;
BOOLEAN FspHasReparsePointCaseSensitivityFix = FALSE;

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#ifndef WINFSP_SYS_DRIVER_H_INCLUDED #ifndef WINFSP_SYS_DRIVER_H_INCLUDED
@ -1358,6 +1362,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
UINT32 GrantedAccess, UINT32 ShareAccess, UINT32 GrantedAccess, UINT32 ShareAccess,
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason); FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags); VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
PFILE_OBJECT FileObject, /* non-0 to remove share access */ PFILE_OBJECT FileObject, /* non-0 to remove share access */
@ -1447,28 +1452,6 @@ NTSTATUS FspMainFileOpen(
NTSTATUS FspMainFileClose( NTSTATUS FspMainFileClose(
HANDLE MainFileHandle, HANDLE MainFileHandle,
PFILE_OBJECT MainFileObject); PFILE_OBJECT MainFileObject);
static __forceinline
BOOLEAN FspMainFileOpenCheck(PIRP Irp)
{
extern const GUID FspMainFileOpenEcpGuid;
NTSTATUS Result;
PECP_LIST ExtraCreateParameters = 0;
PVOID ExtraCreateParameter = 0;
Result = FsRtlGetEcpListFromIrp(Irp, &ExtraCreateParameters);
if (!NT_SUCCESS(Result) || 0 == ExtraCreateParameters)
return FALSE;
Result = FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspMainFileOpenEcpGuid, &ExtraCreateParameter, 0);
if (!NT_SUCCESS(Result) || 0 == ExtraCreateParameter)
return FALSE;
if (FsRtlIsEcpFromUserMode(ExtraCreateParameter))
return FALSE;
return TRUE;
}
#define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F) #define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F)
#define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE) #define FspFileNodeTryAcquireShared(N,F) FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F, FALSE)
#define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F) #define FspFileNodeAcquireExclusive(N,F) FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F)
@ -1594,6 +1577,7 @@ extern const GUID FspMainFileOpenEcpGuid;
extern ULONG FspProcessorCount; extern ULONG FspProcessorCount;
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache; extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
extern ULONG FspMvMdlMappingNoWrite; extern ULONG FspMvMdlMappingNoWrite;
extern BOOLEAN FspHasReparsePointCaseSensitivityFix;
/* /*
* Fixes * Fixes

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>

View File

@ -10,9 +10,13 @@
* General Public License version 3 as published by the Free Software * General Public License version 3 as published by the Free Software
* Foundation. * Foundation.
* *
* Licensees holding a valid commercial license may use this file in * Licensees holding a valid commercial license may use this software
* accordance with the commercial license agreement provided with the * in accordance with the commercial license agreement provided in
* software. * conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/ */
#include <sys/driver.h> #include <sys/driver.h>
@ -37,6 +41,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
UINT32 GrantedAccess, UINT32 ShareAccess, UINT32 GrantedAccess, UINT32 ShareAccess,
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason); FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags); VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject); VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
PFILE_OBJECT FileObject, /* non-0 to remove share access */ PFILE_OBJECT FileObject, /* non-0 to remove share access */
@ -121,6 +126,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
#pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF) #pragma alloc_text(PAGE, FspFileNodeReleaseOwnerF)
#pragma alloc_text(PAGE, FspFileNodeOpen) #pragma alloc_text(PAGE, FspFileNodeOpen)
#pragma alloc_text(PAGE, FspFileNodeCleanup) #pragma alloc_text(PAGE, FspFileNodeCleanup)
#pragma alloc_text(PAGE, FspFileNodeCleanupFlush)
#pragma alloc_text(PAGE, FspFileNodeCleanupComplete) #pragma alloc_text(PAGE, FspFileNodeCleanupComplete)
#pragma alloc_text(PAGE, FspFileNodeClose) #pragma alloc_text(PAGE, FspFileNodeClose)
#pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache) #pragma alloc_text(PAGE, FspFileNodeFlushAndPurgeCache)
@ -772,6 +778,59 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG
*PCleanupFlags = SingleHandle ? DeletePending | (SetAllocationSize << 1) : 0; *PCleanupFlags = SingleHandle ? DeletePending | (SetAllocationSize << 1) : 0;
} }
VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
{
/*
* Optionally flush the FileNode during Cleanup.
*
* The FileNode must be acquired exclusive (Full) when calling this function.
*/
PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
if (!FsvolDeviceExtension->VolumeParams.FlushAndPurgeOnCleanup)
return; /* nothing to do! */
BOOLEAN DeletePending, SingleHandle;
LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
DeletePending = 0 != FileNode->DeletePending;
MemoryBarrier();
SingleHandle = 1 == FileNode->HandleCount;
if (SingleHandle && FileNode->TruncateOnClose)
{
/*
* Even when the FileInfo is expired, this is the best guess for a file size
* without asking the user-mode file system.
*/
TruncateSize = FileNode->Header.FileSize;
PTruncateSize = &TruncateSize;
}
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
/* Flush and purge on last Cleanup. Keeps files off the "standby" list. (GitHub issue #104) */
if (SingleHandle && !DeletePending)
{
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER ZeroOffset = { 0 };
if (0 != PTruncateSize && 0 == PTruncateSize->HighPart)
FspCcFlushCache(FileObject->SectionObjectPointer, &ZeroOffset, PTruncateSize->LowPart,
&IoStatus);
else
FspCcFlushCache(FileObject->SectionObjectPointer, 0, 0,
&IoStatus);
}
}
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject) VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
{ {
/* /*
@ -789,9 +848,9 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
PAGED_CODE(); PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
LARGE_INTEGER TruncateSize, *PTruncateSize = 0; LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
BOOLEAN DeletePending; BOOLEAN DeletePending, DeletedFromContextTable = FALSE, SingleHandle = FALSE;
BOOLEAN DeletedFromContextTable = FALSE;
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
@ -816,6 +875,8 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
ASSERT(0 < FileNode->HandleCount); ASSERT(0 < FileNode->HandleCount);
if (0 == --FileNode->HandleCount) if (0 == --FileNode->HandleCount)
{ {
SingleHandle = TRUE;
DeletePending = 0 != FileNode->DeletePending; DeletePending = 0 != FileNode->DeletePending;
MemoryBarrier(); MemoryBarrier();
@ -832,7 +893,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
* We now have to deal with the scenario where there are cleaned up, * We now have to deal with the scenario where there are cleaned up,
* but unclosed streams for this file still in the context table. * but unclosed streams for this file still in the context table.
*/ */
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.NamedStreams && if (FsvolDeviceExtension->VolumeParams.NamedStreams &&
0 == FileNode->MainFileNode) 0 == FileNode->MainFileNode)
{ {
BOOLEAN StreamDeletedFromContextTable; BOOLEAN StreamDeletedFromContextTable;
@ -869,8 +930,6 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
if (DeletePending || FileNode->TruncateOnClose) if (DeletePending || FileNode->TruncateOnClose)
{ {
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FsvolDeviceObject);
UINT64 AllocationUnit = UINT64 AllocationUnit =
FsvolDeviceExtension->VolumeParams.SectorSize * FsvolDeviceExtension->VolumeParams.SectorSize *
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit; FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
@ -891,6 +950,34 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
/* Flush and purge on last Cleanup. Keeps files off the "standby" list. (GitHub issue #104) */
if (SingleHandle && FsvolDeviceExtension->VolumeParams.FlushAndPurgeOnCleanup)
{
/*
* There is an important difference in behavior with respect to DeletePending when
* FlushAndPurgeOnCleanup is FALSE vs when it is TRUE.
*
* With FlushAndPurgeOnCleanup==FALSE (the default), the WinFsp FSD preserves data
* and allows a deleted file to have memory-mapped I/O done on it after the CLEANUP
* completes. It is up to the user mode file system to decide whether to handle
* this scenario or not. The MEMFS reference file system does.
*
* With FlushAndPurgeOnCleanup==TRUE, the FSD simply purges the cache section (if any),
* which means that CACHED DATA WILL BE LOST. This is desirable, because we do not want
* to unnecessarily flush data that are soon going to be deleted.
*
* This could affect a program that does memory-mapped I/O on a deleted file that has
* been CloseHandle'd. Tests have shown that even NTFS cannot properly handle this
* scenario in all cases (for example, when the file is not cached), so it is unlikely
* that there are any useful programs out there that do this.
*
* So we deem this difference in behavior ok and desirable.
*/
TruncateSize.QuadPart = 0;
PTruncateSize = &TruncateSize;
}
CcUninitializeCacheMap(FileObject, PTruncateSize, 0); CcUninitializeCacheMap(FileObject, PTruncateSize, 0);
if (DeletedFromContextTable) if (DeletedFromContextTable)

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