Compare commits

..

119 Commits

Author SHA1 Message Date
ee1ae0370e build: version.properties: fix product version 2019-03-29 16:38:14 -07:00
1ebceb8214 installer: fix refs to cygfuse 2019-03-29 13:38:19 -07:00
e6bb463444 cygfuse: update packages 2019-03-29 13:03:51 -07:00
86231de113 update changelog 2019-03-29 12:46:13 -07:00
a2cc564400 dll: posix: update upper limit on UID 2019-03-29 12:06:36 -07:00
5239c63274 Contributors: sort names 2019-03-29 11:50:34 -07:00
2d46387faa Merge pull request #223 from sganis/master
Fixed invalid Sid bug
2019-03-29 11:47:51 -07:00
d2381f3425 tst: passthrough-fuse3: xattr 2019-03-26 17:36:02 -07:00
4e7d2fd204 tst: passthrough-fuse: xattr 2019-03-26 17:25:46 -07:00
San
e6fb014c79 Updated contributors list 2019-03-23 02:57:25 +03:00
574efe3f72 sys: dirctl: add magic constant 4 to EaSize 2019-03-21 21:50:28 -07:00
88896c2fd8 dotnet: interop: FileInfo.EaSize is now a property 2019-03-21 21:42:27 -07:00
46210b0c48 tst: passthrough-dotnet: fix compilation problem 2019-03-21 19:48:06 -07:00
3d646bdf88 tools: run-tests: enable ifstest EA tests 2019-03-21 18:19:01 -07:00
732e6cc38c grand EaSize patch; passes winfsp-tests and ifstest 2019-03-21 18:14:15 -07:00
b619dbfe97 tst: memfs, memfs-dotnet: EaSize support 2019-03-21 15:05:39 -07:00
948254f083 dotnet: EA support 2019-03-21 15:05:14 -07:00
62b0e889b2 sys: FileEaInformation and EaSize support 2019-03-21 14:05:17 -07:00
8c0957f702 tools: run-tests: EA testing 2019-03-20 19:42:45 -07:00
0dbc3f9f25 tools: run-tests 2019-03-20 19:13:54 -07:00
2d0c8e14be sys: FspEaBufferFromOriginatingProcessValidate, FspEaBufferFromFileSystemValidate 2019-03-20 19:06:24 -07:00
8c6d037332 dll: fuse: extended attributes support 2019-03-20 14:32:00 -07:00
c23aabe533 sys: ea: return STATUS_INVALID_DEVICE_REQUEST if no ExtendedAttributes 2019-03-20 13:08:20 -07:00
San
6e2b509697 Fixed invalid Sid bug 2019-03-20 09:54:01 +03:00
d2b6c4691e sys: create: minor fix 2019-03-19 18:36:52 -07:00
ff6421866d Merge branch 'pvt-xattr' 2019-03-19 18:23:47 -07:00
0664b492c8 inc: fsctl: fix FSP_FSCTL_VOLUME_PARAMS sizes 2019-03-19 16:29:08 -07:00
58fa2a0620 appveyor: troubleshoot 2019-03-19 16:09:57 -07:00
e6d1de1cad appveyor: troubleshoot 2019-03-19 15:35:53 -07:00
37bcfc888a tst: memfs-dotnet: testing EA support 2019-03-19 15:27:43 -07:00
ff94a63c37 tst: winfsp-tests: Overwrite: EA support 2019-03-19 14:21:25 -07:00
a830de9d04 sys: create: overwrite EA support 2019-03-19 13:22:35 -07:00
02a650f8d0 sys: ea: return STATUS_EA_CORRUPT_ERROR when appropriate 2019-03-19 11:15:14 -07:00
5c42377c1b tst: memfs-dotnet: ea support 2019-03-18 18:43:18 -07:00
ad612c535d tst: memfs-dotnet: ea support 2019-03-18 13:51:58 -07:00
4d4bf92c32 tst: memfs: cosmetic change 2019-03-17 17:17:30 -07:00
7ee289fb13 tst: winfsp-tests: ea 2019-03-17 13:25:29 -07:00
c6e1b15b37 tst: winfsp-tests: ea 2019-03-17 13:13:12 -07:00
1dfbb0d9bf tst: winfsp-tests: ea 2019-03-17 13:08:12 -07:00
92dfb0be96 tst: winfsp-tests: ea 2019-03-17 12:39:00 -07:00
41c3465f2a tst: winfsp-tests: ea 2019-03-17 12:21:32 -07:00
9e5d75fadc sys: util: FspEaBufferAndNamesValid 2019-03-16 13:58:09 -07:00
91568edc45 sys: ea: testing 2019-03-16 00:04:00 -07:00
67bd49d5d4 tst: winfsp-tests: ea_getset_test 2019-03-15 16:43:54 -07:00
cdb1ca22fc tst: winfsp-tests: ea_getset_test 2019-03-15 15:29:37 -07:00
ef6df51b5e tst: winfsp-tests: ea_create_test 2019-03-15 14:21:17 -07:00
1aa2353ca6 tst: winfsp-tests: ea_create_test 2019-03-15 14:04:03 -07:00
351285f5c6 tst: winfsp-tests: ea_create_test 2019-03-15 13:44:45 -07:00
c4ef64e31f tst: winfsp-tests: ea_create_test 2019-03-15 12:47:36 -07:00
5aa06358fc tst: winfsp-tests: ea_create_test 2019-03-15 12:43:14 -07:00
9fd491fa3d sys, dll: ea testing 2019-03-15 11:21:11 -07:00
d3efdd9219 dll, sys: FSP_NEXT_EA 2019-03-14 22:04:31 -07:00
d59976bd5d tst: winfsp-tests: ea_create_test 2019-03-14 21:36:29 -07:00
3553aec992 dotnet: extended attributes support 2019-03-14 15:05:17 -07:00
795caec679 tst: memfs: VolumeParams.ExtendedAttributes 2019-03-13 21:59:27 -07:00
3dd8ae24a8 sys: FspFsvolSetEa: check EaName validity 2019-03-13 21:45:09 -07:00
d8686a7726 tst: memfs: extended attributes support 2019-03-13 21:44:10 -07:00
58c6708123 tools: cloc.bat wraps cloc 2019-03-13 15:15:07 -07:00
b2912460e0 tools: cloc.bat wraps cloc 2019-03-13 15:04:39 -07:00
a811cd2cf8 sys, dll: extended attributes: checkpoint 2019-03-13 14:29:49 -07:00
7ec47f8125 Update README 2019-03-11 17:12:44 -07:00
778f5f70dc build: remove anycpu configuration 2019-03-11 14:06:29 -07:00
09d9928195 README: add link to WinSpd 2019-03-11 13:08:50 -07:00
e2349fef10 Merge branch 'pvt-fix217' 2019-03-11 13:03:49 -07:00
ad866631b6 Merge pull request #219 from dworkin/read-4g-corruption
Fix read corruption issue.
2019-03-11 13:01:44 -07:00
4cdc8b4d9c Update contributor's agreement. 2019-03-07 09:57:49 +01:00
b350dffe6c Fix 32 bit overflow issue in FspFsvolReadCached.
FspFsvolReadCached takes care not to read beyond the end of the file.
However, the offset check uses a 32 bit comparison, which fails for
files >= 4G.  As a result, reads on a large file will skip blocks at
offset (filesize % 4G), and those blocks will zero-filled.
2019-03-07 09:45:42 +01:00
70dd54e114 sys: write: FspFsvolWriteCached
- double-check that WriteEndOffset is within file bounds
2019-02-28 11:00:47 -08:00
d2de5e996c update source copyright for 2019 2019-02-28 10:39:31 -08:00
85cdb37f10 bump version to v1.5 2019-02-28 10:30:52 -08:00
c2553e3451 Merge pull request #216 from VidaID/cpp-flushpurge
Make FlushAndPurgeOnCleanup accessible in C++
2019-02-25 14:07:48 -08:00
9cd2f6972b Set FlushAndPurgeOnCleanup in the C++ passthrough 2019-02-25 14:25:56 -05:00
791a2162a3 fix: Make FlushAndPurgeOnCleanup accessible in C++
Adds the appropriate setters and getters to the C++ API.
2019-02-22 11:14:48 -05:00
5d8686b64e Merge branch 'release/1.4' 2019-02-19 12:17:01 -08:00
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
d1c15b43ca Merge pull request #214 from felfert/fix-fuse-ioctl
Fix #213 and a typo in macro FSP_FUSE_CTLCODE_FROM_IOCTL
2019-02-12 10:29:55 -08:00
f97b8fcc3a Fix #213 and a typo in macro FSP_FUSE_CTLCODE_FROM_IOCTL 2019-02-12 11:51:07 +01:00
1d701a3560 Merge branch 'release/1.4' 2018-12-10 10:06:36 -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
d2f6ceaf28 Merge branch 'release/1.4' 2018-12-10 09:36:03 -08:00
b323925d94 update changelog 2018-12-10 09:34:17 -08:00
ab6e07853c Merge branch 'release/1.4' 2018-12-08 13:56:50 -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
e0a6312387 Merge branch 'release/1.4' 2018-11-27 16:27:15 -08:00
5d2705f3f9 Merge branch 'release/1.4' 2018-11-26 14:59:38 -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
618a59fc0e dll: ensure FspFileSystemFinalize is called 2018-11-13 10:11:39 -08:00
fcd3aff811 Merge branch 'release/1.4': fix #190 2018-11-06 10:12:45 -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
74df26a28d Merge branch 'release/1.4' 2018-10-09 14:32:42 -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
60aee6867c tools: run-tests: disable getfileattr_test for compat-fuse tests 2018-10-04 14:58:34 -07:00
33eb5d1703 fsbench: file_attr_test 2018-10-04 14:55:58 -07:00
4d49039abe sys: FspFastIoQueryOpen: access control
Extend the WinFsp kernel-user mode protocol to allow passing
security descriptors that can then be used for access control
during FastIoQueryOpen.
2018-10-04 13:21:29 -07:00
fd9eccbe8b memfs: AllowOpenInKernelMode==1
The getfileattr_test is expected to fail.
2018-10-03 09:32:14 -07:00
4255d4eec7 tools: run-tests: disable getfileattr_test on file systems that cannot pass it 2018-10-03 09:31:21 -07:00
d813116f77 winfsp-tests: getfileattr_test 2018-10-02 22:35:44 -07:00
a201919291 winfsp-tests: getfileattr_test 2018-10-02 21:44:23 -07:00
1aab4662e5 inc, sys, dotnet: FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode 2018-10-02 11:47:51 -07:00
02a4d3641e sys: implement FastIo operations
FspFastIoQueryOpen: return FALSE when RelatedFileObject is not NULL
2018-10-02 11:12:26 -07:00
3dfbdc313b sys: implement FastIo operations
DEBUGTEST
2018-10-02 11:12:25 -07:00
3a286324ff sys: implement FastIo operations
FspFastIoQueryOpen
2018-10-02 11:12:25 -07:00
0d849ffcc8 sys: implement FastIo operations
FastIoQueryBasicInfo, FastIoQueryStandardInfo, FastIoQueryNetworkOpenInfo
2018-10-02 11:12:24 -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
164 changed files with 5102 additions and 424 deletions

View File

@ -1,6 +1,71 @@
= Changelog = Changelog
v1.5B1 (2019.3 B1)::
Changes since v1.4:
* Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* Initial FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* A fix on the C++ layer. (Thanks @colatkinson.)
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):: v1.4B3 (2018.2 B3)::
Changes since v1.3: Changes since v1.3:

View File

@ -56,9 +56,12 @@ CONTRIBUTOR LIST
|=== |===
|Ben Rubson |ben.rubson at gmail.com |Ben Rubson |ben.rubson at gmail.com
|Bill Zissimopoulos |billziss at navimatics.com |Bill Zissimopoulos |billziss at navimatics.com
|Colin Atkinson (Atakama, https://atakama.com) |colin at atakama.com
|Felix Croes |felix at dworkin.nl
|Francois Karam (KS2, http://www.ks2.fr) |francois.karam at ks2.fr |Francois Karam (KS2, http://www.ks2.fr) |francois.karam at ks2.fr
|Fritz Elfert |fritz-github at fritz-elfert.de |Fritz Elfert |fritz-github at fritz-elfert.de
|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
|Santiago Ganis |sganis at gmail.com
|Tobias Urlaub |saibotu at outlook.de |Tobias Urlaub |saibotu at outlook.de
|=== |===

View File

@ -29,6 +29,9 @@
</a> </a>
<br/> <br/>
<br/> <br/>
<b>Check out my new kernel driver project <a href="https://github.com/billziss-gh/winspd">WinSpd</a>.</b>
<br/>
<br/>
</p> </p>
<p align="center"> <p align="center">

View File

@ -11,6 +11,9 @@ environment:
#- CONFIGURATION: Release #- CONFIGURATION: Release
# TESTING: Perf # TESTING: Perf
init:
#- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
install: install:
- git submodule update --init --recursive - git submodule update --init --recursive
- appveyor AddMessage "Change boot configuration and reboot" -Category Information - appveyor AddMessage "Change boot configuration and reboot" -Category Information
@ -42,3 +45,4 @@ test_script:
on_finish: on_finish:
- if exist %SystemRoot%\memory.dmp (7z a memory.dmp.zip %SystemRoot%\memory.dmp && appveyor PushArtifact memory.dmp.zip) - if exist %SystemRoot%\memory.dmp (7z a memory.dmp.zip %SystemRoot%\memory.dmp && appveyor PushArtifact memory.dmp.zip)
- verifier /query - verifier /query
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

View File

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

View File

@ -348,18 +348,18 @@
<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-9.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-10.tar.xz" KeyPath="yes" />
</Component> </Component>
<Component Id="C.fuse3.tar.xz.x64"> <Component Id="C.fuse3.tar.xz.x64">
<File Id="FILE.fuse3.tar.xz.x64" Name="fuse3-3.2-1.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse3.tar.xz.x64" Name="fuse3-3.2-2.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-9.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-10.tar.xz" KeyPath="yes" />
</Component> </Component>
<Component Id="C.fuse3.tar.xz.x86"> <Component Id="C.fuse3.tar.xz.x86">
<File Id="FILE.fuse3.tar.xz.x86" Name="fuse3-3.2-1.tar.xz" KeyPath="yes" /> <File Id="FILE.fuse3.tar.xz.x86" Name="fuse3-3.2-2.tar.xz" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
<Component Id="C.fuse.install.sh"> <Component Id="C.fuse.install.sh">

View File

@ -185,6 +185,7 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\devctl-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\ea-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" />

View File

@ -94,6 +94,9 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\fuse-test.c"> <ClCompile Include="..\..\..\tst\winfsp-tests\fuse-test.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\ea-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,9 +16,9 @@
<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.4</MyCanonicalVersion> <MyCanonicalVersion>1.5</MyCanonicalVersion>
<MyProductVersion>2018.2 B3</MyProductVersion> <MyProductVersion>2019.3 B1</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>

View File

@ -60,232 +60,168 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsptool", "tools\fsptool.vc
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Installer.Debug|Any CPU = Installer.Debug|Any CPU
Installer.Debug|x64 = Installer.Debug|x64 Installer.Debug|x64 = Installer.Debug|x64
Installer.Debug|x86 = Installer.Debug|x86 Installer.Debug|x86 = Installer.Debug|x86
Installer.Release|Any CPU = Installer.Release|Any CPU
Installer.Release|x64 = Installer.Release|x64 Installer.Release|x64 = Installer.Release|x64
Installer.Release|x86 = Installer.Release|x86 Installer.Release|x86 = Installer.Release|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|Any CPU.ActiveCfg = Debug|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x64.ActiveCfg = Debug|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x64.ActiveCfg = Debug|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x64.Build.0 = Debug|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x64.Build.0 = Debug|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x86.ActiveCfg = Debug|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x86.ActiveCfg = Debug|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x86.Build.0 = Debug|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Debug|x86.Build.0 = Debug|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Debug|x64.ActiveCfg = Debug|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Debug|x64.ActiveCfg = Debug|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Release|x64.ActiveCfg = Release|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Release|x64.ActiveCfg = Release|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Release|x86.ActiveCfg = Release|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Installer.Release|x86.ActiveCfg = Release|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|Any CPU.ActiveCfg = Release|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x64.ActiveCfg = Release|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x64.ActiveCfg = Release|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x64.Build.0 = Release|x64 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x64.Build.0 = Release|x64
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x86.ActiveCfg = Release|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x86.ActiveCfg = Release|Win32
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x86.Build.0 = Release|Win32 {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}.Release|x86.Build.0 = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|Any CPU.ActiveCfg = Debug|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x64.ActiveCfg = Debug|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x64.ActiveCfg = Debug|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x64.Build.0 = Debug|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x64.Build.0 = Debug|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x86.ActiveCfg = Debug|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x86.ActiveCfg = Debug|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x86.Build.0 = Debug|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Debug|x86.Build.0 = Debug|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Debug|x64.ActiveCfg = Debug|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Debug|x64.ActiveCfg = Debug|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Release|x64.ActiveCfg = Release|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Release|x64.ActiveCfg = Release|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Release|x86.ActiveCfg = Release|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Installer.Release|x86.ActiveCfg = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|Any CPU.ActiveCfg = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x64.ActiveCfg = Release|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x64.ActiveCfg = Release|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x64.Build.0 = Release|x64 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x64.Build.0 = Release|x64
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x86.ActiveCfg = Release|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x86.ActiveCfg = Release|Win32
{C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x86.Build.0 = Release|Win32 {C85C26BA-8C22-4D30-83DA-46C3548E6332}.Release|x86.Build.0 = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|Any CPU.ActiveCfg = Debug|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.ActiveCfg = Debug|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.ActiveCfg = Debug|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.Build.0 = Debug|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x64.Build.0 = Debug|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.ActiveCfg = Debug|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.ActiveCfg = Debug|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.Build.0 = Debug|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Debug|x86.Build.0 = Debug|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Debug|x64.ActiveCfg = Debug|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Debug|x64.ActiveCfg = Debug|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Release|x64.ActiveCfg = Release|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Release|x64.ActiveCfg = Release|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Release|x86.ActiveCfg = Release|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Installer.Release|x86.ActiveCfg = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|Any CPU.ActiveCfg = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.ActiveCfg = Release|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.ActiveCfg = Release|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.Build.0 = Release|x64 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x64.Build.0 = Release|x64
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.ActiveCfg = Release|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.ActiveCfg = Release|Win32
{262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.Build.0 = Release|Win32 {262DF8CC-E7A8-4460-A22C-683CBA322C32}.Release|x86.Build.0 = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|Any CPU.ActiveCfg = Debug|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x64.ActiveCfg = Debug|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x64.ActiveCfg = Debug|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x64.Build.0 = Debug|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x64.Build.0 = Debug|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x86.ActiveCfg = Debug|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x86.ActiveCfg = Debug|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x86.Build.0 = Debug|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Debug|x86.Build.0 = Debug|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Debug|x64.ActiveCfg = Debug|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Debug|x64.ActiveCfg = Debug|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Release|x64.ActiveCfg = Release|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Release|x64.ActiveCfg = Release|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Release|x86.ActiveCfg = Release|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Installer.Release|x86.ActiveCfg = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|Any CPU.ActiveCfg = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x64.ActiveCfg = Release|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x64.ActiveCfg = Release|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x64.Build.0 = Release|x64 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x64.Build.0 = Release|x64
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.ActiveCfg = Release|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.ActiveCfg = Release|Win32
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.Build.0 = Release|Win32 {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.Build.0 = Release|Win32
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|Any CPU.ActiveCfg = Debug|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x64.ActiveCfg = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x64.ActiveCfg = Debug|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x86.ActiveCfg = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x86.ActiveCfg = Debug|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|Any CPU.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|Any CPU.Build.0 = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x64.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x64.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x64.Build.0 = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x64.Build.0 = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x86.ActiveCfg = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x86.ActiveCfg = Debug|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x86.Build.0 = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Debug|x86.Build.0 = Debug|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|Any CPU.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|Any CPU.Build.0 = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x64.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x64.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x64.Build.0 = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x64.Build.0 = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x86.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x86.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x86.Build.0 = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Installer.Release|x86.Build.0 = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|Any CPU.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x64.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x64.ActiveCfg = Release|x86
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x86.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x86.ActiveCfg = Release|x86
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Debug|Any CPU.ActiveCfg = Debug|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Debug|x64.ActiveCfg = Debug|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Debug|x64.ActiveCfg = Debug|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Debug|x86.ActiveCfg = Debug|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Debug|x86.ActiveCfg = Debug|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|Any CPU.Build.0 = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x64.ActiveCfg = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x64.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x64.Build.0 = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x64.Build.0 = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x86.Build.0 = Debug|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Debug|x86.Build.0 = Debug|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|Any CPU.Build.0 = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x64.ActiveCfg = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x64.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x64.Build.0 = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x64.Build.0 = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x86.ActiveCfg = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x86.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x86.Build.0 = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Installer.Release|x86.Build.0 = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|Any CPU.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x64.ActiveCfg = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x64.ActiveCfg = Release|Win32
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x86.ActiveCfg = Release|Win32 {95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x86.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Debug|Any CPU.ActiveCfg = Debug|Win32
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.ActiveCfg = Debug|x64 {10757011-749D-4954-873B-AE38D8145472}.Debug|x64.ActiveCfg = Debug|x64
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.Build.0 = Debug|x64 {10757011-749D-4954-873B-AE38D8145472}.Debug|x64.Build.0 = Debug|x64
{10757011-749D-4954-873B-AE38D8145472}.Debug|x86.ActiveCfg = Debug|Win32 {10757011-749D-4954-873B-AE38D8145472}.Debug|x86.ActiveCfg = Debug|Win32
{10757011-749D-4954-873B-AE38D8145472}.Debug|x86.Build.0 = Debug|Win32 {10757011-749D-4954-873B-AE38D8145472}.Debug|x86.Build.0 = Debug|Win32
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x64.ActiveCfg = Debug|x64 {10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x64.ActiveCfg = Debug|x64
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x64.ActiveCfg = Release|x64 {10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x64.ActiveCfg = Release|x64
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x86.ActiveCfg = Release|Win32 {10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x86.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Release|Any CPU.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Release|x64.ActiveCfg = Release|x64 {10757011-749D-4954-873B-AE38D8145472}.Release|x64.ActiveCfg = Release|x64
{10757011-749D-4954-873B-AE38D8145472}.Release|x64.Build.0 = Release|x64 {10757011-749D-4954-873B-AE38D8145472}.Release|x64.Build.0 = Release|x64
{10757011-749D-4954-873B-AE38D8145472}.Release|x86.ActiveCfg = Release|Win32 {10757011-749D-4954-873B-AE38D8145472}.Release|x86.ActiveCfg = Release|Win32
{10757011-749D-4954-873B-AE38D8145472}.Release|x86.Build.0 = Release|Win32 {10757011-749D-4954-873B-AE38D8145472}.Release|x86.Build.0 = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|Any CPU.ActiveCfg = Debug|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x64.ActiveCfg = Debug|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x64.ActiveCfg = Debug|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x64.Build.0 = Debug|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x64.Build.0 = Debug|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x86.ActiveCfg = Debug|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x86.ActiveCfg = Debug|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x86.Build.0 = Debug|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x86.Build.0 = Debug|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x64.ActiveCfg = Debug|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x64.ActiveCfg = Debug|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x64.ActiveCfg = Release|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x64.ActiveCfg = Release|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x86.ActiveCfg = Release|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x86.ActiveCfg = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|Any CPU.ActiveCfg = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x64.ActiveCfg = Release|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x64.ActiveCfg = Release|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x64.Build.0 = Release|x64 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x64.Build.0 = Release|x64
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x86.ActiveCfg = Release|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x86.ActiveCfg = Release|Win32
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x86.Build.0 = Release|Win32 {C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x86.Build.0 = Release|Win32
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x64.ActiveCfg = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x64.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x64.Build.0 = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x64.Build.0 = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x86.ActiveCfg = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x86.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x86.Build.0 = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Debug|x86.Build.0 = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Release|Any CPU.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Release|x64.ActiveCfg = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Release|x64.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Release|x86.ActiveCfg = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Installer.Release|x86.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|Any CPU.Build.0 = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x64.ActiveCfg = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x64.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x64.Build.0 = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x64.Build.0 = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.ActiveCfg = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.ActiveCfg = Release|Any CPU
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.Build.0 = Release|Any CPU {94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.Build.0 = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.ActiveCfg = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.Build.0 = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.Build.0 = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.ActiveCfg = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.Build.0 = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.Build.0 = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.ActiveCfg = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.ActiveCfg = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.Build.0 = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.ActiveCfg = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.Build.0 = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.Build.0 = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.ActiveCfg = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.ActiveCfg = Release|Any CPU
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.Build.0 = Release|Any CPU {4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.Build.0 = Release|Any CPU
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|Any CPU.ActiveCfg = Debug|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.ActiveCfg = Debug|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.ActiveCfg = Debug|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.Build.0 = Debug|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.Build.0 = Debug|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.ActiveCfg = Debug|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.ActiveCfg = Debug|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.Build.0 = Debug|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.Build.0 = Debug|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x64.ActiveCfg = Debug|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x64.ActiveCfg = Debug|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|Any CPU.ActiveCfg = Release|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x64.ActiveCfg = Release|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x64.ActiveCfg = Release|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x86.ActiveCfg = Release|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x86.ActiveCfg = Release|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|Any CPU.ActiveCfg = Release|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.ActiveCfg = Release|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.ActiveCfg = Release|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.Build.0 = Release|x64 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.Build.0 = Release|x64
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.ActiveCfg = Release|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.ActiveCfg = Release|Win32
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.Build.0 = Release|Win32 {6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.Build.0 = Release|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|Any CPU.ActiveCfg = Debug|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.ActiveCfg = Debug|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.ActiveCfg = Debug|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.Build.0 = Debug|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.Build.0 = Debug|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.ActiveCfg = Debug|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.ActiveCfg = Debug|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.Build.0 = Debug|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.Build.0 = Debug|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x64.ActiveCfg = Debug|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x64.ActiveCfg = Debug|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|Any CPU.ActiveCfg = Release|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x64.ActiveCfg = Release|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x64.ActiveCfg = Release|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x86.ActiveCfg = Release|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x86.ActiveCfg = Release|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|Any CPU.ActiveCfg = Release|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.ActiveCfg = Release|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.ActiveCfg = Release|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.Build.0 = Release|x64 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.Build.0 = Release|x64
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.ActiveCfg = Release|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.ActiveCfg = Release|Win32
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.Build.0 = Release|Win32 {264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.Build.0 = Release|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|Any CPU.ActiveCfg = Debug|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.ActiveCfg = Debug|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.ActiveCfg = Debug|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.Build.0 = Debug|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.Build.0 = Debug|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.ActiveCfg = Debug|Win32 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.ActiveCfg = Debug|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.Build.0 = Debug|Win32 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.Build.0 = Debug|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x64.ActiveCfg = Debug|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x64.ActiveCfg = Debug|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x86.ActiveCfg = Debug|Win32 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x86.ActiveCfg = Debug|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|Any CPU.ActiveCfg = Release|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x64.ActiveCfg = Release|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x64.ActiveCfg = Release|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x86.ActiveCfg = Release|Win32 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x86.ActiveCfg = Release|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|Any CPU.ActiveCfg = Release|Win32
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.ActiveCfg = Release|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.ActiveCfg = Release|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.Build.0 = Release|x64 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.Build.0 = Release|x64
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x86.ActiveCfg = Release|Win32 {1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x86.ActiveCfg = Release|Win32

View File

@ -222,7 +222,7 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<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>
@ -250,7 +250,7 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<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>
@ -281,7 +281,7 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<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>
@ -312,7 +312,7 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -67,11 +67,11 @@ struct fuse_operations
/* S */ int (*flush)(const char *path, struct fuse_file_info *fi); /* S */ int (*flush)(const char *path, struct fuse_file_info *fi);
/* S */ int (*release)(const char *path, struct fuse_file_info *fi); /* S */ int (*release)(const char *path, struct fuse_file_info *fi);
/* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi); /* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi);
/* _ */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size, /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
int flags); int flags);
/* _ */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size);
/* _ */ int (*listxattr)(const char *path, char *namebuf, size_t size); /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size);
/* _ */ int (*removexattr)(const char *path, const char *name); /* S */ int (*removexattr)(const char *path, const char *name);
/* S */ int (*opendir)(const char *path, struct fuse_file_info *fi); /* S */ int (*opendir)(const char *path, struct fuse_file_info *fi);
/* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off, /* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
struct fuse_file_info *fi); struct fuse_file_info *fi);

View File

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

View File

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

View File

@ -2,7 +2,7 @@
* @file fuse/winfsp_fuse.h * @file fuse/winfsp_fuse.h
* WinFsp FUSE compatible API. * WinFsp FUSE compatible API.
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -59,7 +59,7 @@ extern "C" {
#define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */ #define FSP_FUSE_DEVICE_TYPE (0x8000 | 'W' | 'F' * 0x100) /* DeviceIoControl -> ioctl */
#define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\ #define FSP_FUSE_CTLCODE_FROM_IOCTL(cmd)\
(FSP_FUSE_DEVICE_TYPE << 16) | (((c) & 0x0fff) << 2) (FSP_FUSE_DEVICE_TYPE << 16) | (((cmd) & 0x0fff) << 2)
#define FSP_FUSE_IOCTL(cmd, isiz, osiz) \ #define FSP_FUSE_IOCTL(cmd, isiz, osiz) \
( \ ( \
(((osiz) != 0) << 31) | \ (((osiz) != 0) << 31) | \

View File

@ -6,7 +6,7 @@
* FUSE: Filesystem in Userspace * FUSE: Filesystem in Userspace
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -106,11 +106,11 @@ struct fuse3_operations
/* S */ int (*flush)(const char *path, struct fuse3_file_info *fi); /* S */ int (*flush)(const char *path, struct fuse3_file_info *fi);
/* S */ int (*release)(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); /* 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, /* S */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
int flags); int flags);
/* _ */ int (*getxattr)(const char *path, const char *name, char *value, size_t size); /* S */ int (*getxattr)(const char *path, const char *name, char *value, size_t size);
/* _ */ int (*listxattr)(const char *path, char *namebuf, size_t size); /* S */ int (*listxattr)(const char *path, char *namebuf, size_t size);
/* _ */ int (*removexattr)(const char *path, const char *name); /* S */ int (*removexattr)(const char *path, const char *name);
/* S */ int (*opendir)(const char *path, struct fuse3_file_info *fi); /* 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, /* 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); struct fuse3_file_info *fi, enum fuse3_readdir_flags);

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file winfsp/fsctl.h * @file winfsp/fsctl.h
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -152,7 +152,7 @@ enum
UINT32 ReparsePointsAccessCheck:1; /* file system performs reparse point access checks */\ UINT32 ReparsePointsAccessCheck:1; /* file system performs reparse point access checks */\
UINT32 NamedStreams:1; /* file system supports named streams */\ UINT32 NamedStreams:1; /* file system supports named streams */\
UINT32 HardLinks:1; /* unimplemented; set to 0 */\ UINT32 HardLinks:1; /* unimplemented; set to 0 */\
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */\ UINT32 ExtendedAttributes:1; /* file system supports extended attributes */\
UINT32 ReadOnlyVolume:1;\ UINT32 ReadOnlyVolume:1;\
/* kernel-mode flags */\ /* kernel-mode flags */\
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */\ UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */\
@ -166,7 +166,9 @@ enum
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */\ UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */\
UINT32 UmReservedFlags:6;\ UINT32 UmReservedFlags:6;\
/* additional kernel-mode flags */\ /* additional kernel-mode flags */\
UINT32 KmReservedFlags:8;\ UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
UINT32 KmReservedFlags:6;\
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ #define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
@ -175,22 +177,28 @@ enum
UINT32 DirInfoTimeoutValid:1; /* DirInfoTimeout field is valid */\ UINT32 DirInfoTimeoutValid:1; /* DirInfoTimeout field is valid */\
UINT32 SecurityTimeoutValid:1; /* SecurityTimeout field is valid*/\ UINT32 SecurityTimeoutValid:1; /* SecurityTimeout field is valid*/\
UINT32 StreamInfoTimeoutValid:1; /* StreamInfoTimeout field is valid */\ UINT32 StreamInfoTimeoutValid:1; /* StreamInfoTimeout field is valid */\
UINT32 KmAdditionalReservedFlags:28;\ UINT32 EaTimeoutValid:1; /* EaTimeout field is valid */\
UINT32 KmAdditionalReservedFlags:27;\
UINT32 VolumeInfoTimeout; /* volume info timeout (millis); overrides FileInfoTimeout */\ UINT32 VolumeInfoTimeout; /* volume info timeout (millis); overrides FileInfoTimeout */\
UINT32 DirInfoTimeout; /* dir info timeout (millis); overrides FileInfoTimeout */\ UINT32 DirInfoTimeout; /* dir info timeout (millis); overrides FileInfoTimeout */\
UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\ UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\
UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\ UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\
UINT32 Reserved32[3];\ UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\
UINT32 Reserved32[2];\
UINT64 Reserved64[2]; UINT64 Reserved64[2];
typedef struct typedef struct
{ {
FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN
} FSP_FSCTL_VOLUME_PARAMS_V0; } FSP_FSCTL_VOLUME_PARAMS_V0;
FSP_FSCTL_STATIC_ASSERT(456 == sizeof(FSP_FSCTL_VOLUME_PARAMS_V0),
"sizeof(FSP_FSCTL_VOLUME_PARAMS_V0) must be exactly 456.");
typedef struct typedef struct
{ {
FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN FSP_FSCTL_VOLUME_PARAMS_V0_FIELD_DEFN
FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN
} FSP_FSCTL_VOLUME_PARAMS; } FSP_FSCTL_VOLUME_PARAMS;
FSP_FSCTL_STATIC_ASSERT(504 == sizeof(FSP_FSCTL_VOLUME_PARAMS),
"sizeof(FSP_FSCTL_VOLUME_PARAMS) is currently 504. Update this assertion check if it changes.");
typedef struct typedef struct
{ {
UINT64 TotalSize; UINT64 TotalSize;
@ -198,6 +206,8 @@ typedef struct
UINT16 VolumeLabelLength; UINT16 VolumeLabelLength;
WCHAR VolumeLabel[32]; WCHAR VolumeLabel[32];
} FSP_FSCTL_VOLUME_INFO; } FSP_FSCTL_VOLUME_INFO;
FSP_FSCTL_STATIC_ASSERT(88 == sizeof(FSP_FSCTL_VOLUME_INFO),
"sizeof(FSP_FSCTL_VOLUME_INFO) must be exactly 88.");
typedef struct typedef struct
{ {
UINT32 FileAttributes; UINT32 FileAttributes;
@ -210,7 +220,10 @@ typedef struct
UINT64 ChangeTime; UINT64 ChangeTime;
UINT64 IndexNumber; UINT64 IndexNumber;
UINT32 HardLinks; /* unimplemented: set to 0 */ UINT32 HardLinks; /* unimplemented: set to 0 */
UINT32 EaSize;
} FSP_FSCTL_FILE_INFO; } FSP_FSCTL_FILE_INFO;
FSP_FSCTL_STATIC_ASSERT(72 == sizeof(FSP_FSCTL_FILE_INFO),
"sizeof(FSP_FSCTL_FILE_INFO) must be exactly 72.");
typedef struct typedef struct
{ {
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
@ -225,6 +238,8 @@ typedef struct
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */ /* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */
WCHAR FileNameBuf[]; WCHAR FileNameBuf[];
} FSP_FSCTL_DIR_INFO; } FSP_FSCTL_DIR_INFO;
FSP_FSCTL_STATIC_ASSERT(104 == sizeof(FSP_FSCTL_DIR_INFO),
"sizeof(FSP_FSCTL_DIR_INFO) must be exactly 104.");
typedef struct typedef struct
{ {
UINT16 Size; UINT16 Size;
@ -232,6 +247,8 @@ typedef struct
UINT64 StreamAllocationSize; UINT64 StreamAllocationSize;
WCHAR StreamNameBuf[]; WCHAR StreamNameBuf[];
} FSP_FSCTL_STREAM_INFO; } FSP_FSCTL_STREAM_INFO;
FSP_FSCTL_STATIC_ASSERT(24 == sizeof(FSP_FSCTL_STREAM_INFO),
"sizeof(FSP_FSCTL_STREAM_INFO) must be exactly 24.");
typedef struct typedef struct
{ {
UINT64 UserContext; UINT64 UserContext;
@ -260,7 +277,7 @@ typedef struct
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
FSP_FSCTL_TRANSACT_BUF Ea; /* reserved; not currently implemented */ FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */
UINT32 UserMode:1; /* request originated in user mode */ UINT32 UserMode:1; /* request originated in user mode */
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */ UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
@ -268,7 +285,8 @@ typedef struct
UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */ UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */ UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
UINT32 ReservedFlags:25; UINT32 AcceptsSecurityDescriptor:1;
UINT32 ReservedFlags:24;
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */ UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
} Create; } Create;
struct struct
@ -278,6 +296,7 @@ typedef struct
UINT32 FileAttributes; /* file attributes for overwritten/superseded files */ UINT32 FileAttributes; /* file attributes for overwritten/superseded files */
UINT64 AllocationSize; /* allocation size for overwritten/superseded files */ UINT64 AllocationSize; /* allocation size for overwritten/superseded files */
UINT32 Supersede:1; /* 0: FILE_OVERWRITE operation, 1: FILE_SUPERSEDE operation */ UINT32 Supersede:1; /* 0: FILE_OVERWRITE operation, 1: FILE_SUPERSEDE operation */
FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */
} Overwrite; } Overwrite;
struct struct
{ {
@ -354,6 +373,17 @@ typedef struct
} Info; } Info;
} SetInformation; } SetInformation;
struct struct
{
UINT64 UserContext;
UINT64 UserContext2;
} QueryEa;
struct
{
UINT64 UserContext;
UINT64 UserContext2;
FSP_FSCTL_TRANSACT_BUF Ea;
} SetEa;
struct
{ {
UINT64 UserContext; UINT64 UserContext;
UINT64 UserContext2; UINT64 UserContext2;
@ -439,9 +469,11 @@ typedef struct
UINT64 UserContext; /* user context associated with file node */ UINT64 UserContext; /* user context associated with file node */
UINT64 UserContext2; /* user context associated with file descriptor (handle) */ UINT64 UserContext2; /* user context associated with file descriptor (handle) */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
FSP_FSCTL_TRANSACT_BUF FileName; FSP_FSCTL_TRANSACT_BUF FileName;
UINT32 DisableCache:1; UINT32 DisableCache:1;
UINT32 HasSecurityDescriptor:1;
} Opened; } Opened;
/* IoStatus.Status == STATUS_REPARSE */ /* IoStatus.Status == STATUS_REPARSE */
struct struct
@ -466,6 +498,15 @@ typedef struct
FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */ FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */
} SetInformation; } SetInformation;
struct struct
{
FSP_FSCTL_TRANSACT_BUF Ea;
} QueryEa;
struct
{
FSP_FSCTL_FILE_INFO FileInfo;
FSP_FSCTL_TRANSACT_BUF Ea; /* Size==0 means no extended atttributed returned */
} SetEa;
struct
{ {
FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */ FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */
} FlushBuffers; } FlushBuffers;

View File

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

@ -5,7 +5,7 @@
* In order to use the WinFsp API the user mode file system must include &lt;winfsp/winfsp.h&gt; * In order to use the WinFsp API the user mode file system must include &lt;winfsp/winfsp.h&gt;
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library. * and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -85,6 +85,21 @@ typedef struct _REPARSE_DATA_BUFFER
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#endif #endif
/*
* The FILE_FULL_EA_INFORMATION definitions are missing from the user mode headers.
*/
#if !defined(FILE_NEED_EA)
#define FILE_NEED_EA 0x00000080
#endif
typedef struct _FILE_FULL_EA_INFORMATION
{
ULONG NextEntryOffset;
UCHAR Flags;
UCHAR EaNameLength;
USHORT EaValueLength;
CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
/** /**
* @group File System * @group File System
* *
@ -894,12 +909,138 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
*/ */
NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*SetDelete)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile); PVOID FileContext, PWSTR FileName, BOOLEAN DeleteFile);
/**
* Create new file or directory.
*
* This function works like Create, except that it also accepts EA (extended attributes).
*
* NOTE: If both Create and CreateEx are defined, CreateEx takes precedence.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileName
* The name of the file or directory to be created.
* @param CreateOptions
* Create options for this request. This parameter has the same meaning as the
* CreateOptions parameter of the NtCreateFile API. User mode file systems should typically
* only be concerned with the flag FILE_DIRECTORY_FILE, which is an instruction to create a
* directory rather than a file. Some file systems may also want to pay attention to the
* FILE_NO_INTERMEDIATE_BUFFERING and FILE_WRITE_THROUGH flags, although these are
* typically handled by the FSD component.
* @param GrantedAccess
* Determines the specific access rights that have been granted for this request. Upon
* receiving this call all access checks have been performed and the user mode file system
* need not perform any additional checks. However this parameter may be useful to a user
* mode file system; for example the WinFsp-FUSE layer uses this parameter to determine
* which flags to use in its POSIX open() call.
* @param FileAttributes
* File attributes to apply to the newly created file or directory.
* @param SecurityDescriptor
* Security descriptor to apply to the newly created file or directory. This security
* descriptor will always be in self-relative format. Its length can be retrieved using the
* Windows GetSecurityDescriptorLength API. Will be NULL for named streams.
* @param AllocationSize
* Allocation size for the newly created file.
* @param Ea
* Extended attributes buffer.
* @param EaLength
* Extended attributes buffer length.
* @param PFileContext [out]
* Pointer that will receive the file context on successful return from this call.
* @param FileInfo [out]
* Pointer to a structure that will receive the file information on successful return
* from this call. This information includes file attributes, file times, etc.
* @return
* STATUS_SUCCESS or error code.
*/
NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
/**
* Overwrite a file.
*
* This function works like Overwrite, except that it also accepts EA (extended attributes).
*
* NOTE: If both Overwrite and OverwriteEx are defined, OverwriteEx takes precedence.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the file to overwrite.
* @param FileAttributes
* File attributes to apply to the overwritten file.
* @param ReplaceFileAttributes
* When TRUE the existing file attributes should be replaced with the new ones.
* When FALSE the existing file attributes should be merged (or'ed) with the new ones.
* @param AllocationSize
* Allocation size for the overwritten file.
* @param Ea
* Extended attributes buffer.
* @param EaLength
* Extended attributes buffer length.
* @param FileInfo [out]
* Pointer to a structure that will receive the file information on successful return
* from this call. This information includes file attributes, file times, etc.
* @return
* STATUS_SUCCESS or error code.
*/
NTSTATUS (*OverwriteEx)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
FSP_FSCTL_FILE_INFO *FileInfo);
/**
* Get extended attributes.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the file to get extended attributes for.
* @param Ea
* Extended attributes buffer.
* @param EaLength
* Extended attributes buffer length.
* @param PBytesTransferred [out]
* Pointer to a memory location that will receive the actual number of bytes transferred.
* @return
* STATUS_SUCCESS or error code.
* @see
* SetEa
* FspFileSystemAddEa
*/
NTSTATUS (*GetEa)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred);
/**
* Set extended attributes.
*
* @param FileSystem
* The file system on which this request is posted.
* @param FileContext
* The file context of the file to set extended attributes for.
* @param Ea
* Extended attributes buffer.
* @param EaLength
* Extended attributes buffer length.
* @param FileInfo [out]
* Pointer to a structure that will receive the file information on successful return
* from this call. This information includes file attributes, file times, etc.
* @return
* STATUS_SUCCESS or error code.
* @see
* GetEa
*/
NTSTATUS (*SetEa)(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
FSP_FSCTL_FILE_INFO *FileInfo);
/* /*
* 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[37])(); NTSTATUS (*Reserved[33])();
} 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.");
@ -1203,6 +1344,10 @@ FSP_API NTSTATUS FspFileSystemOpQueryInformation(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 FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpSetInformation(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 FspFileSystemOpQueryEa(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpFlushBuffers(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 FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
@ -1433,6 +1578,70 @@ FSP_API NTSTATUS FspFileSystemCanReplaceReparsePoint(
*/ */
FSP_API BOOLEAN FspFileSystemAddStreamInfo(FSP_FSCTL_STREAM_INFO *StreamInfo, FSP_API BOOLEAN FspFileSystemAddStreamInfo(FSP_FSCTL_STREAM_INFO *StreamInfo,
PVOID Buffer, ULONG Length, PULONG PBytesTransferred); PVOID Buffer, ULONG Length, PULONG PBytesTransferred);
/**
* Enumerate extended attributes in a buffer.
*
* This is a helper for implementing the CreateEx and SetEa operations in file systems
* that support extended attributes.
*
* @param FileSystem
* The file system object.
* @param EnumerateEa
* Pointer to function that receives a single extended attribute. The function
* should return STATUS_SUCCESS or an error code if unsuccessful.
* @param Context
* User context to supply to EnumEa.
* @param Ea
* Extended attributes buffer.
* @param EaLength
* Extended attributes buffer length.
* @return
* STATUS_SUCCESS or error code from EnumerateEa.
*/
FSP_API NTSTATUS FspFileSystemEnumerateEa(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*EnumerateEa)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PFILE_FULL_EA_INFORMATION SingleEa),
PVOID Context,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength);
/**
* Add extended attribute to a buffer.
*
* This is a helper for implementing the GetEa operation.
*
* @param SingleEa
* The extended attribute to add. A value of NULL acts as an EOF marker for a GetEa
* operation.
* @param Ea
* Pointer to a buffer that will receive the extended attribute. This should contain
* the same value passed to the GetEa Ea parameter.
* @param EaLength
* Length of buffer. This should contain the same value passed to the GetEa
* EaLength parameter.
* @param PBytesTransferred [out]
* Pointer to a memory location that will receive the actual number of bytes stored. This should
* contain the same value passed to the GetEa PBytesTransferred parameter.
* @return
* TRUE if the extended attribute was added, FALSE if there was not enough space to add it.
* @see
* GetEa
*/
FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PULONG PBytesTransferred);
/**
* Get extended attribute "packed" size. This computation matches what NTFS reports.
*
* @param SingleEa
* The extended attribute to get the size for.
* @return
* The packed size of the extended attribute.
*/
static inline
UINT32 FspFileSystemGetEaPackedSize(PFILE_FULL_EA_INFORMATION SingleEa)
{
/* magic computations are courtesy of NTFS */
return 5 + SingleEa->EaNameLength + SingleEa->EaValueLength;
}
/* /*
* Directory buffering * Directory buffering
@ -1795,6 +2004,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

@ -2,7 +2,7 @@
* @file winfsp/winfsp.hpp * @file winfsp/winfsp.hpp
* WinFsp C++ Layer. * WinFsp C++ Layer.
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -612,6 +612,14 @@ public:
{ {
_VolumeParams.PassQueryDirectoryPattern = !!PassQueryDirectoryPattern; _VolumeParams.PassQueryDirectoryPattern = !!PassQueryDirectoryPattern;
} }
BOOLEAN FlushAndPurgeOnCleanup()
{
return _VolumeParams.FlushAndPurgeOnCleanup;
}
VOID SetFlushAndPurgeOnCleanup(BOOLEAN FlushAndPurgeOnCleanup)
{
_VolumeParams.FlushAndPurgeOnCleanup = !!FlushAndPurgeOnCleanup;
}
PWSTR Prefix() PWSTR Prefix()
{ {
return _VolumeParams.Prefix; return _VolumeParams.Prefix;

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

View File

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

View File

@ -1,6 +1,6 @@
NAME="fuse" NAME="fuse"
VERSION=2.8 VERSION=2.8
RELEASE=9 RELEASE=10
CATEGORY="Utils" CATEGORY="Utils"
SUMMARY="WinFsp FUSE compatibility layer" SUMMARY="WinFsp FUSE compatibility layer"
DESCRIPTION="Enables FUSE file systems to be run on Cygwin." DESCRIPTION="Enables FUSE file systems to be run on Cygwin."

View File

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

View File

@ -1,6 +1,6 @@
NAME="fuse3" NAME="fuse3"
VERSION=3.2 VERSION=3.2
RELEASE=1 RELEASE=2
CATEGORY="Utils" CATEGORY="Utils"
SUMMARY="WinFsp FUSE3 compatibility layer" SUMMARY="WinFsp FUSE3 compatibility layer"
DESCRIPTION="Enables FUSE3 file systems to be run on Cygwin." DESCRIPTION="Enables FUSE3 file systems to be run on Cygwin."

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fs.c * @file dll/fs.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -161,6 +161,8 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
FileSystem->Operations[FspFsctlTransactWriteKind] = FspFileSystemOpWrite; FileSystem->Operations[FspFsctlTransactWriteKind] = FspFileSystemOpWrite;
FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation; FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation;
FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation; FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation;
FileSystem->Operations[FspFsctlTransactQueryEaKind] = FspFileSystemOpQueryEa;
FileSystem->Operations[FspFsctlTransactSetEaKind] = FspFileSystemOpSetEa;
FileSystem->Operations[FspFsctlTransactFlushBuffersKind] = FspFileSystemOpFlushBuffers; FileSystem->Operations[FspFsctlTransactFlushBuffersKind] = FspFileSystemOpFlushBuffers;
FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation; FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation;
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation; FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fsop.c * @file dll/fsop.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -242,7 +242,8 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
static inline static inline
NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem, NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response, FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response,
BOOLEAN AllowTraverseCheck, PUINT32 PGrantedAccess) BOOLEAN AllowTraverseCheck, PUINT32 PGrantedAccess,
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
@ -257,10 +258,11 @@ NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem,
* requested in DesiredAccess. * requested in DesiredAccess.
*/ */
Result = FspAccessCheck(FileSystem, Request, FALSE, AllowTraverseCheck, Result = FspAccessCheckEx(FileSystem, Request, FALSE, AllowTraverseCheck,
Request->Req.Create.DesiredAccess | Request->Req.Create.DesiredAccess |
((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0), ((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0),
&GrantedAccess); &GrantedAccess,
Request->Req.Create.AcceptsSecurityDescriptor ? PSecurityDescriptor : 0);
if (STATUS_REPARSE == Result) if (STATUS_REPARSE == Result)
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess); Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
else if (NT_SUCCESS(Result)) else if (NT_SUCCESS(Result))
@ -391,21 +393,40 @@ NTSTATUS FspFileSystemRenameCheck(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
static inline
VOID FspFileSystemOpCreate_SetOpenDescriptor(FSP_FSCTL_TRANSACT_RSP *Response,
PSECURITY_DESCRIPTOR OpenDescriptor)
{
FSP_FSCTL_TRANSACT_BUF Buf;
Buf.Offset = FSP_FSCTL_DEFAULT_ALIGN_UP(Response->Rsp.Create.Opened.FileName.Size);
Buf.Size = (UINT16)GetSecurityDescriptorLength(OpenDescriptor);
if (FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX >= Buf.Offset + Buf.Size)
{
Response->Size += Buf.Offset + Buf.Size;
Response->Rsp.Create.Opened.SecurityDescriptor.Offset = Buf.Offset;
Response->Rsp.Create.Opened.SecurityDescriptor.Size = Buf.Size;
Response->Rsp.Create.Opened.HasSecurityDescriptor = 1;
memcpy(Response->Buffer + Buf.Offset, OpenDescriptor, Buf.Size);
}
}
static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS FspFileSystemOpCreate_FileCreate(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 Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor; PSECURITY_DESCRIPTOR ParentDescriptor;
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext; FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
PSECURITY_DESCRIPTOR OpenDescriptor = 0;
Result = FspFileSystemCreateCheck(FileSystem, Request, Response, TRUE, Result = FspFileSystemCreateCheck(FileSystem, Request, Response, TRUE,
&GrantedAccess, &ParentDescriptor); &GrantedAccess, &ParentDescriptor);
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result) if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
return Result; return Result;
Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &ObjectDescriptor); Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &OpenDescriptor);
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx); FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -415,13 +436,24 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
memset(&OpenFileInfo, 0, sizeof OpenFileInfo); memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer; OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
if (0 != FileSystem->Interface->CreateEx)
Result = FileSystem->Interface->CreateEx(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{
FspDeleteSecurityDescriptor(OpenDescriptor, FspCreateSecurityDescriptor);
return Result; return Result;
}
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize) if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
{ {
@ -430,6 +462,12 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize; Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
} }
if (0 != OpenDescriptor)
{
FspFileSystemOpCreate_SetOpenDescriptor(Response, OpenDescriptor);
FspDeleteSecurityDescriptor(OpenDescriptor, FspCreateSecurityDescriptor);
}
Response->IoStatus.Information = FILE_CREATED; Response->IoStatus.Information = FILE_CREATED;
SetFileContext(Response->Rsp.Create.Opened, FullContext); SetFileContext(Response->Rsp.Create.Opened, FullContext);
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess; Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
@ -445,8 +483,10 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
UINT32 GrantedAccess; UINT32 GrantedAccess;
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext; FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
PSECURITY_DESCRIPTOR OpenDescriptor = 0;
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess); Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess,
&OpenDescriptor);
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result) if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
return Result; return Result;
@ -459,7 +499,10 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{
FspDeleteSecurityDescriptor(OpenDescriptor, FspAccessCheckEx);
return Result; return Result;
}
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize) if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
{ {
@ -468,6 +511,12 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize; Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
} }
if (0 != OpenDescriptor)
{
FspFileSystemOpCreate_SetOpenDescriptor(Response, OpenDescriptor);
FspDeleteSecurityDescriptor(OpenDescriptor, FspAccessCheckEx);
}
Response->IoStatus.Information = FILE_OPENED; Response->IoStatus.Information = FILE_OPENED;
SetFileContext(Response->Rsp.Create.Opened, FullContext); SetFileContext(Response->Rsp.Create.Opened, FullContext);
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess; Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
@ -481,12 +530,14 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
{ {
NTSTATUS Result; NTSTATUS Result;
UINT32 GrantedAccess; UINT32 GrantedAccess;
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor; PSECURITY_DESCRIPTOR ParentDescriptor;
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext; FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo; FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
PSECURITY_DESCRIPTOR OpenDescriptor = 0;
BOOLEAN Create = FALSE; BOOLEAN Create = FALSE;
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess); Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess,
&OpenDescriptor);
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result) if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
{ {
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
@ -506,6 +557,9 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
FspDeleteSecurityDescriptor(OpenDescriptor, FspAccessCheckEx);
OpenDescriptor = 0;
if (STATUS_OBJECT_NAME_NOT_FOUND != Result) if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
return Result; return Result;
Create = TRUE; Create = TRUE;
@ -519,7 +573,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result) if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
return Result; return Result;
Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &ObjectDescriptor); Result = FspCreateSecurityDescriptor(FileSystem, Request, ParentDescriptor, &OpenDescriptor);
FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx); FspDeleteSecurityDescriptor(ParentDescriptor, FspAccessCheckEx);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -529,14 +583,25 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
memset(&OpenFileInfo, 0, sizeof OpenFileInfo); memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer; OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
if (0 != FileSystem->Interface->CreateEx)
Result = FileSystem->Interface->CreateEx(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{
FspDeleteSecurityDescriptor(OpenDescriptor, FspCreateSecurityDescriptor);
return Result; return Result;
} }
}
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize) if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
{ {
@ -545,6 +610,13 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize; Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
} }
if (0 != OpenDescriptor)
{
FspFileSystemOpCreate_SetOpenDescriptor(Response, OpenDescriptor);
FspDeleteSecurityDescriptor(OpenDescriptor, Create ?
(NTSTATUS (*)())FspCreateSecurityDescriptor : (NTSTATUS (*)())FspAccessCheckEx);
}
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED; Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED;
SetFileContext(Response->Rsp.Create.Opened, FullContext); SetFileContext(Response->Rsp.Create.Opened, FullContext);
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess; Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
@ -645,6 +717,15 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
memset(&OpenFileInfo, 0, sizeof OpenFileInfo); memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer; OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX; OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
if (0 != FileSystem->Interface->CreateEx)
Result = FileSystem->Interface->CreateEx(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
@ -811,9 +892,9 @@ FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
{ {
NTSTATUS Result; NTSTATUS Result;
if (0 == FileSystem->Interface->Create || if ((0 == FileSystem->Interface->Create && 0 == FileSystem->Interface->CreateEx) ||
0 == FileSystem->Interface->Open || 0 == FileSystem->Interface->Open ||
0 == FileSystem->Interface->Overwrite) (0 == FileSystem->Interface->Overwrite && 0 == FileSystem->Interface->OverwriteEx))
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
if (Request->Req.Create.OpenTargetDirectory) if (Request->Req.Create.OpenTargetDirectory)
@ -856,10 +937,21 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS Result; NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_FILE_INFO FileInfo;
if (0 == FileSystem->Interface->Overwrite) if (0 == FileSystem->Interface->Overwrite && 0 == FileSystem->Interface->OverwriteEx)
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo); memset(&FileInfo, 0, sizeof FileInfo);
if (0 != FileSystem->Interface->OverwriteEx)
Result = FileSystem->Interface->OverwriteEx(FileSystem,
(PVOID)ValOfFileContext(Request->Req.Overwrite),
Request->Req.Overwrite.FileAttributes,
Request->Req.Overwrite.Supersede,
Request->Req.Overwrite.AllocationSize,
0 != Request->Req.Overwrite.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Overwrite.Ea.Offset) : 0,
Request->Req.Overwrite.Ea.Size,
&FileInfo);
else
Result = FileSystem->Interface->Overwrite(FileSystem, Result = FileSystem->Interface->Overwrite(FileSystem,
(PVOID)ValOfFileContext(Request->Req.Overwrite), (PVOID)ValOfFileContext(Request->Req.Overwrite),
Request->Req.Overwrite.FileAttributes, Request->Req.Overwrite.FileAttributes,
@ -1091,6 +1183,49 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
FSP_API NTSTATUS FspFileSystemOpQueryEa(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
NTSTATUS Result;
ULONG BytesTransferred;
if (0 == FileSystem->Interface->GetEa)
return STATUS_INVALID_DEVICE_REQUEST;
BytesTransferred = 0;
Result = FileSystem->Interface->GetEa(FileSystem,
(PVOID)ValOfFileContext(Request->Req.QueryEa),
(PVOID)Response->Buffer, FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX, &BytesTransferred);
if (!NT_SUCCESS(Result))
return STATUS_BUFFER_OVERFLOW != Result ? Result : STATUS_EA_LIST_INCONSISTENT;
Response->Size = (UINT16)(sizeof *Response + BytesTransferred);
Response->Rsp.QueryEa.Ea.Offset = 0;
Response->Rsp.QueryEa.Ea.Size = (UINT16)BytesTransferred;
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemOpSetEa(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{
NTSTATUS Result;
FSP_FSCTL_FILE_INFO FileInfo;
if (0 == FileSystem->Interface->SetEa)
return STATUS_INVALID_DEVICE_REQUEST;
memset(&FileInfo, 0, sizeof FileInfo);
Result = FileSystem->Interface->SetEa(FileSystem,
(PVOID)ValOfFileContext(Request->Req.SetEa),
(PVOID)Request->Buffer, Request->Req.SetEa.Ea.Size,
&FileInfo);
if (!NT_SUCCESS(Result))
return Result;
memcpy(&Response->Rsp.SetEa.FileInfo, &FileInfo, sizeof FileInfo);
return STATUS_SUCCESS;
}
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
@ -1672,3 +1807,51 @@ FSP_API BOOLEAN FspFileSystemAddStreamInfo(FSP_FSCTL_STREAM_INFO *StreamInfo,
{ {
return FspFileSystemAddXxxInfo(StreamInfo, Buffer, Length, PBytesTransferred); return FspFileSystemAddXxxInfo(StreamInfo, Buffer, Length, PBytesTransferred);
} }
FSP_API NTSTATUS FspFileSystemEnumerateEa(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS (*EnumerateEa)(
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PFILE_FULL_EA_INFORMATION SingleEa),
PVOID Context,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength)
{
NTSTATUS Result = STATUS_SUCCESS;
for (PFILE_FULL_EA_INFORMATION EaEnd = (PVOID)((PUINT8)Ea + EaLength);
EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd))
{
Result = EnumerateEa(FileSystem, Context, Ea);
if (!NT_SUCCESS(Result))
break;
}
return Result;
}
FSP_API BOOLEAN FspFileSystemAddEa(PFILE_FULL_EA_INFORMATION SingleEa,
PFILE_FULL_EA_INFORMATION Ea, ULONG Length, PULONG PBytesTransferred)
{
if (0 != SingleEa)
{
PUINT8 EaPtr = (PUINT8)Ea + FSP_FSCTL_ALIGN_UP(*PBytesTransferred, sizeof(ULONG));
PUINT8 EaEnd = (PUINT8)Ea + Length;
ULONG EaLen = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
SingleEa->EaNameLength + 1 + SingleEa->EaValueLength;
if (EaEnd < EaPtr + EaLen)
return FALSE;
memcpy(EaPtr, SingleEa, EaLen);
((PFILE_FULL_EA_INFORMATION)EaPtr)->NextEntryOffset = FSP_FSCTL_ALIGN_UP(EaLen, sizeof(ULONG));
*PBytesTransferred = (ULONG)(EaPtr + EaLen - (PUINT8)Ea);
}
else if ((ULONG)FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) <= *PBytesTransferred)
{
PUINT8 EaEnd = (PUINT8)Ea + *PBytesTransferred;
while (EaEnd > (PUINT8)Ea + Ea->NextEntryOffset)
Ea = (PVOID)((PUINT8)Ea + Ea->NextEntryOffset);
Ea->NextEntryOffset = 0;
}
return TRUE;
}

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse.c * @file dll/fuse/fuse.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -83,6 +83,8 @@ static struct fuse_opt fsp_fuse_core_opts[] =
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=", set_DirInfoTimeout, 1),
FSP_FUSE_CORE_OPT("DirInfoTimeout=%d", VolumeParams.DirInfoTimeout, 0), FSP_FUSE_CORE_OPT("DirInfoTimeout=%d", VolumeParams.DirInfoTimeout, 0),
FSP_FUSE_CORE_OPT("EaTimeout=", set_EaTimeout, 1),
FSP_FUSE_CORE_OPT("EaTimeout=%d", VolumeParams.EaTimeout, 0),
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1), FSP_FUSE_CORE_OPT("VolumeInfoTimeout=", set_VolumeInfoTimeout, 1),
FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0), FSP_FUSE_CORE_OPT("VolumeInfoTimeout=%d", VolumeParams.VolumeInfoTimeout, 0),
FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1), FSP_FUSE_CORE_OPT("KeepFileCache=", set_KeepFileCache, 1),
@ -252,6 +254,7 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
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 DirInfoTimeout=N directory info timeout (millis)\n" " -o DirInfoTimeout=N directory info timeout (millis)\n"
" -o EaTimeout=N extended attribute timeout (millis)\n"
" -o VolumeInfoTimeout=N volume info timeout (millis)\n" " -o VolumeInfoTimeout=N volume info timeout (millis)\n"
" -o KeepFileCache do not discard cache when files are closed\n" " -o KeepFileCache do not discard cache when files are closed\n"
" -o ThreadCount number of file system dispatcher threads\n" " -o ThreadCount number of file system dispatcher threads\n"
@ -392,6 +395,8 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.FileInfoTimeout = opt_data.attr_timeout * 1000; opt_data.VolumeParams.FileInfoTimeout = opt_data.attr_timeout * 1000;
if (opt_data.set_DirInfoTimeout) if (opt_data.set_DirInfoTimeout)
opt_data.VolumeParams.DirInfoTimeoutValid = 1; opt_data.VolumeParams.DirInfoTimeoutValid = 1;
if (opt_data.set_EaTimeout)
opt_data.VolumeParams.EaTimeoutValid = 1;
if (opt_data.set_VolumeInfoTimeout) if (opt_data.set_VolumeInfoTimeout)
opt_data.VolumeParams.VolumeInfoTimeoutValid = 1; opt_data.VolumeParams.VolumeInfoTimeoutValid = 1;
if (opt_data.set_KeepFileCache) if (opt_data.set_KeepFileCache)

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_intf.c * @file dll/fuse/fuse_intf.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -438,6 +438,9 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim, &FileInfo->ChangeTime); FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim, &FileInfo->ChangeTime);
FileInfo->IndexNumber = stbuf.st_ino; FileInfo->IndexNumber = stbuf.st_ino;
FileInfo->HardLinks = 0;
FileInfo->EaSize = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -666,6 +669,9 @@ static NTSTATUS fsp_fuse_intf_GetReparsePointEx(FSP_FILE_SYSTEM *FileSystem,
static NTSTATUS fsp_fuse_intf_GetReparsePointByName( static NTSTATUS fsp_fuse_intf_GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem, PVOID Context, FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize); PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize);
static NTSTATUS fsp_fuse_intf_SetEaEntry(
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PFILE_FULL_EA_INFORMATION SingleEa);
static NTSTATUS fsp_fuse_intf_GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_VOLUME_INFO *VolumeInfo) FSP_FSCTL_VOLUME_INFO *VolumeInfo)
@ -737,6 +743,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
@ -750,6 +757,16 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
int err; int err;
NTSTATUS Result; NTSTATUS Result;
if (0 != Ea)
{
if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
{
Result = STATUS_EAS_NOT_SUPPORTED;
goto exit;
}
}
filedesc = MemAlloc(sizeof *filedesc); filedesc = MemAlloc(sizeof *filedesc);
if (0 == filedesc) if (0 == filedesc)
{ {
@ -849,6 +866,13 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
if (0 != Ea)
{
Result = FspFileSystemEnumerateEa(FileSystem,
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, Ea, EaLength);
if (!NT_SUCCESS(Result))
goto exit;
}
/* /*
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache. * Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
* NOTE: Originally WinFsp dit not support disabling the cache manager * NOTE: Originally WinFsp dit not support disabling the cache manager
@ -1001,6 +1025,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, PVOID FileDesc, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
FSP_FSCTL_FILE_INFO *FileInfo) FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
@ -1013,6 +1038,29 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
if (filedesc->IsDirectory || filedesc->IsReparsePoint) if (filedesc->IsDirectory || filedesc->IsReparsePoint)
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
if (0 != Ea)
{
char names[3 * 1024];
int namesize;
if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
return STATUS_EAS_NOT_SUPPORTED;
namesize = f->ops.listxattr(filedesc->PosixPath, names, sizeof names);
if (0 < namesize)
for (char *p = names, *endp = p + namesize; endp > p; p += namesize)
{
namesize = lstrlenA(p) + 1;
f->ops.removexattr(filedesc->PosixPath, p);
}
Result = FspFileSystemEnumerateEa(FileSystem,
fsp_fuse_intf_SetEaEntry, filedesc->PosixPath, Ea, EaLength);
if (!NT_SUCCESS(Result))
return Result;
}
if (0 != f->ops.ftruncate) if (0 != f->ops.ftruncate)
{ {
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
@ -2168,18 +2216,118 @@ static NTSTATUS fsp_fuse_intf_Control(FSP_FILE_SYSTEM *FileSystem,
memcpy(OutputBuffer, InputBuffer, InputBufferLength); memcpy(OutputBuffer, InputBuffer, InputBufferLength);
err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, OutputBuffer); err = f->ops.ioctl(filedesc->PosixPath, cmd, 0, &fi, 0, OutputBuffer);
} }
*PBytesTransferred = OutputBufferLength;
return fsp_fuse_ntstatus_from_errno(f->env, err); return fsp_fuse_ntstatus_from_errno(f->env, err);
} }
static NTSTATUS fsp_fuse_intf_GetEa(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc,
PFILE_FULL_EA_INFORMATION Ea0, ULONG EaLength, PULONG PBytesTransferred)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
char names[3 * 1024];
int namesize, valuesize;
PFILE_FULL_EA_INFORMATION Ea = Ea0, PrevEa = 0;
PUINT8 EaEnd = (PUINT8)Ea + EaLength, EaValue;
if (0 == f->ops.listxattr || 0 == f->ops.getxattr)
return STATUS_INVALID_DEVICE_REQUEST;
namesize = f->ops.listxattr(filedesc->PosixPath, names, sizeof names);
if (0 >= namesize)
{
*PBytesTransferred = 0;
return fsp_fuse_ntstatus_from_errno(f->env, namesize);
}
for (char *p = names, *endp = p + namesize; endp > p; p += namesize)
{
namesize = lstrlenA(p) + 1;
EaValue = (PUINT8)Ea + FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) + namesize;
if (EaValue >= EaEnd)
/* if there is no space (at least 1 byte) for a value bail out */
break;
valuesize = f->ops.getxattr(filedesc->PosixPath, p, EaValue, EaEnd - EaValue);
if (0 >= valuesize)
continue;
Ea->NextEntryOffset = 0;
Ea->Flags = 0;
Ea->EaNameLength = namesize - 1;
Ea->EaValueLength = valuesize;
memcpy(Ea->EaName, p, namesize);
if (0 != PrevEa)
PrevEa->NextEntryOffset = (ULONG)((PUINT8)Ea - (PUINT8)PrevEa);
PrevEa = Ea;
*PBytesTransferred = (ULONG)((PUINT8)EaValue - (PUINT8)Ea0 + valuesize);
Ea = (PVOID)((PUINT8)Ea +
FSP_FSCTL_ALIGN_UP(
FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) + namesize + valuesize,
sizeof(ULONG)));
}
return STATUS_SUCCESS;
}
static NTSTATUS fsp_fuse_intf_SetEaEntry(
FSP_FILE_SYSTEM *FileSystem, PVOID Context,
PFILE_FULL_EA_INFORMATION SingleEa)
{
struct fuse *f = FileSystem->UserContext;
const char *PosixPath = Context;
int err;
if (0 != SingleEa->EaValueLength)
err = f->ops.setxattr(PosixPath,
SingleEa->EaName, SingleEa->EaName + SingleEa->EaNameLength + 1, SingleEa->EaValueLength, 0);
else
err = f->ops.removexattr(PosixPath,
SingleEa->EaName);
return fsp_fuse_ntstatus_from_errno(f->env, err);
}
static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
PVOID FileDesc,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength,
FSP_FSCTL_FILE_INFO *FileInfo)
{
struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_file_desc *filedesc = FileDesc;
UINT32 Uid, Gid, Mode;
struct fuse_file_info fi;
NTSTATUS Result;
if (0 == f->ops.setxattr || 0 == f->ops.removexattr)
return STATUS_INVALID_DEVICE_REQUEST;
Result = FspFileSystemEnumerateEa(FileSystem,
fsp_fuse_intf_SetEaEntry, filedesc->PosixPath, Ea, EaLength);
if (!NT_SUCCESS(Result))
return Result;
memset(&fi, 0, sizeof fi);
fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
&Uid, &Gid, &Mode, FileInfo);
}
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf = FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
{ {
fsp_fuse_intf_GetVolumeInfo, fsp_fuse_intf_GetVolumeInfo,
fsp_fuse_intf_SetVolumeLabel, fsp_fuse_intf_SetVolumeLabel,
fsp_fuse_intf_GetSecurityByName, fsp_fuse_intf_GetSecurityByName,
fsp_fuse_intf_Create, 0,
fsp_fuse_intf_Open, fsp_fuse_intf_Open,
fsp_fuse_intf_Overwrite, 0,
fsp_fuse_intf_Cleanup, fsp_fuse_intf_Cleanup,
fsp_fuse_intf_Close, fsp_fuse_intf_Close,
fsp_fuse_intf_Read, fsp_fuse_intf_Read,
@ -2200,6 +2348,11 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
0, 0,
fsp_fuse_intf_GetDirInfoByName, fsp_fuse_intf_GetDirInfoByName,
fsp_fuse_intf_Control, fsp_fuse_intf_Control,
0,
fsp_fuse_intf_Create,
fsp_fuse_intf_Overwrite,
fsp_fuse_intf_GetEa,
fsp_fuse_intf_SetEa,
}; };
/* /*

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/fuse_loop.c * @file dll/fuse/fuse_loop.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -160,6 +160,9 @@ static NTSTATUS fsp_fuse_loop_start(struct fuse *f)
err = f->ops.readlink("/", buf, sizeof buf); err = f->ops.readlink("/", buf, sizeof buf);
f->has_symlinks = -ENOSYS_(f->env) != err; f->has_symlinks = -ENOSYS_(f->env) != err;
} }
if (0 != f->ops.listxattr && 0 != f->ops.getxattr &&
0 != f->ops.setxattr && 0 != f->ops.removexattr)
f->VolumeParams.ExtendedAttributes = 1;
/* the FSD does not currently limit these VolumeParams fields; do so here! */ /* the FSD does not currently limit these VolumeParams fields; do so here! */
if (f->VolumeParams.SectorSize < FSP_FUSE_SECTORSIZE_MIN || if (f->VolumeParams.SectorSize < FSP_FUSE_SECTORSIZE_MIN ||

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/fuse/library.h * @file dll/fuse/library.h
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -143,6 +143,7 @@ struct fsp_fuse_core_opt_data
rellinks; rellinks;
int set_FileInfoTimeout, int set_FileInfoTimeout,
set_DirInfoTimeout, set_DirInfoTimeout,
set_EaTimeout,
set_VolumeInfoTimeout, set_VolumeInfoTimeout,
set_KeepFileCache; set_KeepFileCache;
unsigned ThreadCount; unsigned ThreadCount;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/launch.c * @file dll/launch.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -23,7 +23,18 @@
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;
@ -53,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;
@ -102,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];
@ -115,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(
@ -250,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
{ {
@ -400,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)
{ {
@ -430,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

@ -1,7 +1,7 @@
/** /**
* @file dll/library.c * @file dll/library.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -46,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

@ -1,7 +1,7 @@
/** /**
* @file dll/library.h * @file dll/library.h
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -47,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);
@ -91,4 +92,7 @@ static inline BOOLEAN FspPathIsDrive(PWSTR FileName)
L':' == FileName[1] && L'\0' == FileName[2]; L':' == FileName[1] && L'\0' == FileName[2];
} }
#define FSP_NEXT_EA(Ea, EaEnd) \
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
#endif #endif

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/np.c * @file dll/np.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -23,6 +23,9 @@
#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
@ -179,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);
@ -251,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;
@ -259,8 +307,15 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
FSP_LAUNCH_REG_RECORD *Record; FSP_LAUNCH_REG_RECORD *Record;
NTSTATUS Result; NTSTATUS Result;
if (0 != PAuthPackage)
*PAuthPackage = 0;
if (0 != PCredentialsKind)
*PCredentialsKind = FSP_NP_CREDENTIALS_NONE; *PCredentialsKind = FSP_NP_CREDENTIALS_NONE;
if (0 != PAllowImpersonation)
*PAllowImpersonation = FALSE;
if (!FspNpParseRemoteName(RemoteName, if (!FspNpParseRemoteName(RemoteName,
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen)) &ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
return WN_BAD_NETNAME; return WN_BAD_NETNAME;
@ -274,6 +329,23 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return WN_NO_NETWORK; return WN_NO_NETWORK;
if (0 != PAuthPackage)
{
if (0 != Record->AuthPackage)
{
ULONG AuthPackage = 0;
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) switch (Record->Credentials)
{ {
case FSP_NP_CREDENTIALS_NONE: case FSP_NP_CREDENTIALS_NONE:
@ -283,6 +355,10 @@ static DWORD FspNpGetRemoteInfo(PWSTR RemoteName, PDWORD PCredentialsKind)
break; 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;
@ -290,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 */)
@ -317,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;
@ -346,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;
@ -464,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];
@ -493,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;
@ -550,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:
@ -602,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;
@ -659,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;
@ -679,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)
@ -695,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
@ -766,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

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

View File

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

View File

@ -14,7 +14,7 @@
* [SNAME] * [SNAME]
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html * https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -190,7 +190,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
Uid - 0x30000); Uid - 0x30000);
} }
} }
else if (0x100000 <= Uid && Uid < 0x200000) else if (0x100000 <= Uid && Uid < 0xff000000)
{ {
if (0 != FspPrimaryDomainSid && if (0 != FspPrimaryDomainSid &&
5 == FspPrimaryDomainSid->IdentifierAuthority.Value[5] && 5 == FspPrimaryDomainSid->IdentifierAuthority.Value[5] &&

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/security.c * @file dll/security.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -341,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 &
(FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY | FILE_DELETE_CHILD))
{ {
Result = STATUS_ACCESS_DENIED; Result = STATUS_ACCESS_DENIED;
goto exit; goto exit;
} }
if (Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE)
if (FILE_ATTRIBUTE_READONLY == (FileAttributes & FILE_ATTRIBUTE_READONLY) &&
(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

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

View File

@ -1,7 +1,7 @@
/** /**
* @file dll/util.c * @file dll/util.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -67,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;
@ -75,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())
@ -89,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

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

View File

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

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemBase.cs * dotnet/FileSystemBase.cs
* *
* Copyright 2015-2018 Bill Zissimopoulos * Copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -707,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,
@ -1078,6 +1078,115 @@ namespace Fsp
else else
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
public virtual Int32 CreateEx(
String FileName,
UInt32 CreateOptions,
UInt32 GrantedAccess,
UInt32 FileAttributes,
Byte[] SecurityDescriptor,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out Object FileNode,
out Object FileDesc,
out FileInfo FileInfo,
out String NormalizedName)
{
return Create(
FileName,
CreateOptions,
GrantedAccess,
FileAttributes,
SecurityDescriptor,
AllocationSize,
out FileNode,
out FileDesc,
out FileInfo,
out NormalizedName);
}
public virtual Int32 OverwriteEx(
Object FileNode,
Object FileDesc,
UInt32 FileAttributes,
Boolean ReplaceFileAttributes,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo)
{
return Overwrite(
FileNode,
FileDesc,
FileAttributes,
ReplaceFileAttributes,
AllocationSize,
out FileInfo);
}
public virtual Int32 GetEa(
Object FileNode,
Object FileDesc,
IntPtr Ea,
UInt32 EaLength,
out UInt32 BytesTransferred)
{
Object Context = null;
String EaName;
Byte[] EaValue;
Boolean NeedEa;
FullEaInformation EaInfo = new FullEaInformation();
BytesTransferred = default(UInt32);
while (GetEaEntry(FileNode, FileDesc, ref Context, out EaName, out EaValue, out NeedEa))
{
EaInfo.Set(EaName, EaValue, NeedEa);
if (!Api.FspFileSystemAddEa(ref EaInfo, Ea, EaLength, out BytesTransferred))
return STATUS_SUCCESS;
}
Api.FspFileSystemEndEa(Ea, EaLength, out BytesTransferred);
return STATUS_SUCCESS;
}
public virtual Boolean GetEaEntry(
Object FileNode,
Object FileDesc,
ref Object Context,
out String EaName,
out Byte[] EaValue,
out Boolean NeedEa)
{
EaName = default(String);
EaValue = default(Byte[]);
NeedEa = default(Boolean);
return false;
}
public virtual Int32 SetEa(
Object FileNode,
Object FileDesc,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo)
{
Int32 Result;
Result = SetEaEntries(
FileNode,
FileDesc,
Ea,
EaLength);
if (0 > Result)
{
FileInfo = default(FileInfo);
return Result;
}
return GetFileInfo(FileNode, FileDesc, out FileInfo);
}
public virtual Int32 SetEaEntry(
Object FileNode,
Object FileDesc,
ref Object Context,
String EaName,
Byte[] EaValue,
Boolean NeedEa)
{
return STATUS_INVALID_DEVICE_REQUEST;
}
/* helpers */ /* helpers */
/// <summary> /// <summary>
@ -1105,7 +1214,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.
@ -1121,6 +1230,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,
@ -1140,6 +1250,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,
@ -1301,6 +1452,26 @@ namespace Fsp
return self.ExceptionHandler(ex); return self.ExceptionHandler(ex);
} }
} }
public Int32 SetEaEntries(
Object FileNode,
Object FileDesc,
IntPtr Ea,
UInt32 EaLength)
{
return Api.FspFileSystemEnumerateEa(
FileNode,
FileDesc,
this.SetEaEntry,
Ea,
EaLength);
}
public static UInt32 GetEaEntrySize(
String EaName,
Byte[] EaValue,
Boolean NeedEa)
{
return FullEaInformation.PackedSize(EaName, EaValue, NeedEa);
}
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/FileSystemHost.cs * dotnet/FileSystemHost.cs
* *
* Copyright 2015-2018 Bill Zissimopoulos * Copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -183,6 +183,14 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.NamedStreams); } get { return 0 != (_VolumeParams.Flags & VolumeParams.NamedStreams); }
set { _VolumeParams.Flags |= (value ? VolumeParams.NamedStreams : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.NamedStreams : 0); }
} }
/// <summary>
/// Gets or sets a value that determines whether the file system supports extended attributes.
/// </summary>
public Boolean ExtendedAttributes
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.ExtendedAttributes); }
set { _VolumeParams.Flags |= (value ? VolumeParams.ExtendedAttributes : 0); }
}
public Boolean PostCleanupWhenModifiedOnly public Boolean PostCleanupWhenModifiedOnly
{ {
get { return 0 != (_VolumeParams.Flags & VolumeParams.PostCleanupWhenModifiedOnly); } get { return 0 != (_VolumeParams.Flags & VolumeParams.PostCleanupWhenModifiedOnly); }
@ -208,6 +216,11 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.DeviceControl); } get { return 0 != (_VolumeParams.Flags & VolumeParams.DeviceControl); }
set { _VolumeParams.Flags |= (value ? VolumeParams.DeviceControl : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.DeviceControl : 0); }
} }
public Boolean AllowOpenInKernelMode
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); }
set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 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>
@ -459,6 +472,8 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
IntPtr SecurityDescriptor, IntPtr SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
ref FullContext FullContext, ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo) ref OpenFileInfo OpenFileInfo)
{ {
@ -468,13 +483,15 @@ namespace Fsp
Object FileNode, FileDesc; Object FileNode, FileDesc;
String NormalizedName; String NormalizedName;
Int32 Result; Int32 Result;
Result = FileSystem.Create( Result = FileSystem.CreateEx(
FileName, FileName,
CreateOptions, CreateOptions,
GrantedAccess, GrantedAccess,
FileAttributes, FileAttributes,
Api.MakeSecurityDescriptor(SecurityDescriptor), Api.MakeSecurityDescriptor(SecurityDescriptor),
AllocationSize, AllocationSize,
Ea,
EaLength,
out FileNode, out FileNode,
out FileDesc, out FileDesc,
out OpenFileInfo.FileInfo, out OpenFileInfo.FileInfo,
@ -533,6 +550,8 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
Boolean ReplaceFileAttributes, Boolean ReplaceFileAttributes,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo) out FileInfo FileInfo)
{ {
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr); FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
@ -540,12 +559,14 @@ namespace Fsp
{ {
Object FileNode, FileDesc; Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc); Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.Overwrite( return FileSystem.OverwriteEx(
FileNode, FileNode,
FileDesc, FileDesc,
FileAttributes, FileAttributes,
ReplaceFileAttributes, ReplaceFileAttributes,
AllocationSize, AllocationSize,
Ea,
EaLength,
out FileInfo); out FileInfo);
} }
catch (Exception ex) catch (Exception ex)
@ -1072,15 +1093,65 @@ namespace Fsp
return ExceptionHandler(FileSystem, ex); return ExceptionHandler(FileSystem, ex);
} }
} }
private static Int32 GetEa(
IntPtr FileSystemPtr,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength,
out UInt32 PBytesTransferred)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.GetEa(
FileNode,
FileDesc,
Ea,
EaLength,
out PBytesTransferred);
}
catch (Exception ex)
{
PBytesTransferred = default(UInt32);
return ExceptionHandler(FileSystem, ex);
}
}
private static Int32 SetEa(
IntPtr FileSystemPtr,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo)
{
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
try
{
Object FileNode, FileDesc;
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
return FileSystem.SetEa(
FileNode,
FileDesc,
Ea,
EaLength,
out FileInfo);
}
catch (Exception ex)
{
FileInfo = default(FileInfo);
return ExceptionHandler(FileSystem, ex);
}
}
static FileSystemHost() static FileSystemHost()
{ {
_FileSystemInterface.GetVolumeInfo = GetVolumeInfo; _FileSystemInterface.GetVolumeInfo = GetVolumeInfo;
_FileSystemInterface.SetVolumeLabel = SetVolumeLabel; _FileSystemInterface.SetVolumeLabel = SetVolumeLabel;
_FileSystemInterface.GetSecurityByName = GetSecurityByName; _FileSystemInterface.GetSecurityByName = GetSecurityByName;
_FileSystemInterface.Create = Create; _FileSystemInterface.CreateEx = Create;
_FileSystemInterface.Open = Open; _FileSystemInterface.Open = Open;
_FileSystemInterface.Overwrite = Overwrite; _FileSystemInterface.OverwriteEx = Overwrite;
_FileSystemInterface.Cleanup = Cleanup; _FileSystemInterface.Cleanup = Cleanup;
_FileSystemInterface.Close = Close; _FileSystemInterface.Close = Close;
_FileSystemInterface.Read = Read; _FileSystemInterface.Read = Read;
@ -1101,6 +1172,8 @@ namespace Fsp
_FileSystemInterface.GetDirInfoByName = GetDirInfoByName; _FileSystemInterface.GetDirInfoByName = GetDirInfoByName;
_FileSystemInterface.Control = Control; _FileSystemInterface.Control = Control;
_FileSystemInterface.SetDelete = SetDelete; _FileSystemInterface.SetDelete = SetDelete;
_FileSystemInterface.GetEa = GetEa;
_FileSystemInterface.SetEa = SetEa;
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size); _FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false); Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false);

View File

@ -1,7 +1,7 @@
/* /*
* dotnet/Interop.cs * dotnet/Interop.cs
* *
* Copyright 2015-2018 Bill Zissimopoulos * Copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -51,6 +51,8 @@ namespace Fsp.Interop
internal const UInt32 DeviceControl = 0x00008000; 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 UInt32 AllowOpenInKernelMode = 0x01000000;
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
internal const int PrefixSize = 192; internal const int PrefixSize = 192;
internal const int FileSystemNameSize = 16; internal const int FileSystemNameSize = 16;
@ -194,6 +196,28 @@ namespace Fsp.Interop
/// Not currently implemented. Set to 0. /// Not currently implemented. Set to 0.
/// </summary> /// </summary>
public UInt32 HardLinks; public UInt32 HardLinks;
/// <summary>
/// The extended attribute size of the file.
/// </summary>
public UInt32 EaSize
{
get { return GetEaSize(); }
set { SetEaSize(value); }
}
internal static int EaSizeOffset =
(int)Marshal.OffsetOf(typeof(FileInfo), "HardLinks") + 4;
internal unsafe UInt32 GetEaSize()
{
fixed (FileInfo *P = &this)
return *(UInt32 *)((Int64)(IntPtr)P + EaSizeOffset);
}
internal unsafe void SetEaSize(UInt32 value)
{
fixed (FileInfo *P = &this)
*(UInt32 *)((Int64)(IntPtr)P + EaSizeOffset) = value;
}
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@ -269,6 +293,53 @@ namespace Fsp.Interop
} }
} }
[StructLayout(LayoutKind.Sequential)]
internal struct FullEaInformation
{
internal const int EaNameSize = 15 * 1024;
/* Set this to a value smaller than 16384 with sufficient space for additional data.
* This should really be:
* FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX - FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName)
*/
internal UInt32 NextEntryOffset;
internal Byte Flags;
internal Byte EaNameLength;
internal UInt16 EaValueLength;
internal unsafe fixed Byte EaName[EaNameSize];
internal unsafe void Set(String Name, Byte[] Value, Boolean NeedEa)
{
int NameLength = 254 < Name.Length ? 254 : Name.Length;
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
EaNameSize - Name.Length - 1 : Value.Length;
NextEntryOffset = 0;
Flags = NeedEa ? (Byte)0x80/*FILE_NEED_EA*/ : (Byte)0;
EaNameLength = (Byte)NameLength;
EaValueLength = (UInt16)ValueLength;
fixed (Byte *P = EaName)
{
int I = 0, J = 0;
for (; NameLength > I; I++)
P[I] = (Byte)Name[I];
P[I++] = 0;
for (; ValueLength > J; J++)
P[I + J] = Value[J];
}
}
internal static UInt32 PackedSize(String Name, Byte[] Value, Boolean NeedEa)
{
int NameLength = 254 < Name.Length ? 254 : Name.Length;
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
EaNameSize - Name.Length - 1 : Value.Length;
/* magic computations are courtesy of NTFS */
return (UInt32)(5 + NameLength + ValueLength);
}
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct FullContext internal struct FullContext
{ {
@ -477,6 +548,43 @@ namespace Fsp.Interop
ref FullContext FullContext, ref FullContext FullContext,
[MarshalAs(UnmanagedType.LPWStr)] String FileName, [MarshalAs(UnmanagedType.LPWStr)] String FileName,
[MarshalAs(UnmanagedType.U1)] Boolean DeleteFile); [MarshalAs(UnmanagedType.U1)] Boolean DeleteFile);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 CreateEx(
IntPtr FileSystem,
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
UInt32 CreateOptions,
UInt32 GrantedAccess,
UInt32 FileAttributes,
IntPtr SecurityDescriptor,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 OverwriteEx(
IntPtr FileSystem,
ref FullContext FullContext,
UInt32 FileAttributes,
[MarshalAs(UnmanagedType.U1)] Boolean ReplaceFileAttributes,
UInt64 AllocationSize,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 GetEa(
IntPtr FileSystem,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 SetEa(
IntPtr FileSystem,
ref FullContext FullContext,
IntPtr Ea,
UInt32 EaLength,
out FileInfo FileInfo);
} }
internal static int Size = IntPtr.Size * 64; internal static int Size = IntPtr.Size * 64;
@ -508,7 +616,11 @@ namespace Fsp.Interop
internal Proto.GetDirInfoByName GetDirInfoByName; internal Proto.GetDirInfoByName GetDirInfoByName;
internal Proto.Control Control; internal Proto.Control Control;
internal Proto.SetDelete SetDelete; internal Proto.SetDelete SetDelete;
/* NTSTATUS (*Reserved[37])(); */ internal Proto.CreateEx CreateEx;
internal Proto.OverwriteEx OverwriteEx;
internal Proto.GetEa GetEa;
internal Proto.SetEa SetEa;
/* NTSTATUS (*Reserved[33])(); */
} }
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]
@ -603,6 +715,13 @@ namespace Fsp.Interop
out UInt32 PBytesTransferred); out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal delegate Boolean FspFileSystemAddEa(
IntPtr SingleEa,
IntPtr Ea,
UInt32 EaLength,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer( internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
ref IntPtr PDirBuffer, ref IntPtr PDirBuffer,
[MarshalAs(UnmanagedType.U1)] Boolean Reset, [MarshalAs(UnmanagedType.U1)] Boolean Reset,
@ -736,6 +855,7 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints; internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint; internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo; internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer; internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer; internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer; internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
@ -805,6 +925,62 @@ namespace Fsp.Interop
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred); return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
} }
internal delegate Int32 EnumerateEa(
Object FileNode,
Object FileDesc,
ref Object Context,
String EaName,
Byte[] EaValue,
Boolean NeedEa);
internal static unsafe Int32 FspFileSystemEnumerateEa(
Object FileNode,
Object FileDesc,
EnumerateEa EnumerateEa,
IntPtr Ea,
UInt32 EaLength)
{
Object Context = null;
FullEaInformation *P = (FullEaInformation *)Ea;
FullEaInformation *EndP = (FullEaInformation *)(Ea.ToInt64() + EaLength);
Int32 Result;
Result = 0/*STATUS_SUCCESS*/;
for (; EndP > P;
P = 0 != P->NextEntryOffset ?
(FullEaInformation *)(((IntPtr)P).ToInt64() + P->NextEntryOffset) :
EndP)
{
String EaName = Marshal.PtrToStringAnsi((IntPtr)P->EaName, P->EaNameLength);
Byte[] EaValue = null;
if (0 != P->EaValueLength)
{
EaValue = new Byte[P->EaValueLength];
Marshal.Copy((IntPtr)(((IntPtr)P->EaName).ToInt64() + P->EaNameLength + 1),
EaValue, 0, P->EaValueLength);
}
Boolean NeedEa = 0 != (0x80/*FILE_NEED_EA*/ & P->Flags);
Result = EnumerateEa(FileNode, FileDesc, ref Context, EaName, EaValue, NeedEa);
if (0 > Result)
break;
}
return Result;
}
internal static unsafe Boolean FspFileSystemAddEa(
ref FullEaInformation EaInfo,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
fixed (FullEaInformation *P = &EaInfo)
return _FspFileSystemAddEa((IntPtr)P, Buffer, Length, out PBytesTransferred);
}
internal static unsafe Boolean FspFileSystemEndEa(
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
return _FspFileSystemAddEa(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
}
internal unsafe static Object GetUserContext( internal unsafe static Object GetUserContext(
IntPtr NativePtr) IntPtr NativePtr)
{ {
@ -928,6 +1104,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,
@ -1053,6 +1249,7 @@ namespace Fsp.Interop
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module); FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module); _FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module); _FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module); FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module); FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module); FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file launcher/launchctl.c * @file launcher/launchctl.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -72,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

@ -1,7 +1,7 @@
/** /**
* @file launcher/launcher.c * @file launcher/launcher.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -255,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,
@ -271,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);
@ -299,9 +309,12 @@ 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;
if (0 == Token)
{
Success = LogonUserW( Success = LogonUserW(
UserName, UserName,
DomainName, DomainName,
@ -311,6 +324,25 @@ static BOOL LogonCreateProcess(
&LogonToken); &LogonToken);
if (!Success) if (!Success)
goto exit; 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)
{ {
@ -663,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)
@ -758,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,
@ -779,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,
@ -792,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,
@ -1009,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))
@ -1629,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

@ -1,7 +1,7 @@
/** /**
* @file shared/minimal.h * @file shared/minimal.h
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

@ -2,7 +2,7 @@
* @file sys/callbacks.c * @file sys/callbacks.c
* Fast I/O and resource acquisition callbacks. * Fast I/O and resource acquisition callbacks.
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/create.c * @file sys/create.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -96,7 +96,11 @@ enum
RequestFileObject = 2, RequestFileObject = 2,
RequestState = 3, RequestState = 3,
/* RequestState */ /* TryOpen RequestState */
RequestFlushImage = 1,
RequestAcceptsSecurityDescriptor = 2,
/* Overwrite RequestState */
RequestPending = 0, RequestPending = 0,
RequestProcessing = 1, RequestProcessing = 1,
}; };
@ -274,7 +278,7 @@ static NTSTATUS FspFsvolCreateNoLock(
ACCESS_MASK GrantedAccess = AccessState->PreviouslyGrantedAccess; ACCESS_MASK GrantedAccess = AccessState->PreviouslyGrantedAccess;
USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess;
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
//ULONG EaLength = IrpSp->Parameters.Create.EaLength; ULONG EaLength = IrpSp->Parameters.Create.EaLength;
ULONG Flags = IrpSp->Flags; ULONG Flags = IrpSp->Flags;
KPROCESSOR_MODE RequestorMode = KPROCESSOR_MODE RequestorMode =
FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode;
@ -298,10 +302,24 @@ static NTSTATUS FspFsvolCreateNoLock(
if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID)) if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID))
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
/* no EA support currently */ /* was an EA buffer specified? */
if (0 != EaBuffer) if (0 != EaBuffer)
{
/* does the file system support EA? */
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
return STATUS_EAS_NOT_SUPPORTED; return STATUS_EAS_NOT_SUPPORTED;
/* do we need EA knowledge? */
if (FlagOn(CreateOptions, FILE_NO_EA_KNOWLEDGE))
return STATUS_ACCESS_DENIED;
/* is the EA buffer valid? */
Result = FspEaBufferFromOriginatingProcessValidate(
EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information);
if (!NT_SUCCESS(Result))
return Result;
}
/* cannot open a paging file */ /* cannot open a paging file */
if (FlagOn(Flags, SL_OPEN_PAGING_FILE)) if (FlagOn(Flags, SL_OPEN_PAGING_FILE))
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
@ -537,6 +555,10 @@ static NTSTATUS FspFsvolCreateNoLock(
SecurityDescriptorSize = 0; SecurityDescriptorSize = 0;
FileAttributes = 0; FileAttributes = 0;
/* cannot set EA on named stream */
EaBuffer = 0;
EaLength = 0;
/* remember the main file node */ /* remember the main file node */
ASSERT(0 == FileNode->MainFileNode); ASSERT(0 == FileNode->MainFileNode);
FileNode->MainFileNode = FileDesc->MainFileObject->FsContext; FileNode->MainFileNode = FileDesc->MainFileObject->FsContext;
@ -554,7 +576,9 @@ static NTSTATUS FspFsvolCreateNoLock(
} }
/* create the user-mode file system request */ /* create the user-mode file system request */
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, SecurityDescriptorSize, Result = FspIopCreateRequestEx(Irp, &FileNode->FileName,
0 != EaBuffer ?
FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + EaLength : SecurityDescriptorSize,
FspFsvolCreateRequestFini, &Request); FspFsvolCreateRequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
@ -580,19 +604,22 @@ static NTSTATUS FspFsvolCreateNoLock(
FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
/* populate the Create request */ /* populate the Create request */
#define NEXTOFS(B) ((B).Offset + FSP_FSCTL_DEFAULT_ALIGN_UP((B).Size))
Request->Kind = FspFsctlTransactCreateKind; Request->Kind = FspFsctlTransactCreateKind;
Request->Req.Create.CreateOptions = CreateOptions; Request->Req.Create.CreateOptions = CreateOptions;
Request->Req.Create.FileAttributes = FileAttributes; Request->Req.Create.FileAttributes = FileAttributes;
Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 : Request->Req.Create.SecurityDescriptor.Offset = 0 != SecurityDescriptorSize ?
FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size); NEXTOFS(Request->FileName) : 0;
Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize;
Request->Req.Create.AllocationSize = AllocationSize; Request->Req.Create.AllocationSize = AllocationSize;
Request->Req.Create.AccessToken = 0; Request->Req.Create.AccessToken = 0;
Request->Req.Create.DesiredAccess = DesiredAccess; Request->Req.Create.DesiredAccess = DesiredAccess;
Request->Req.Create.GrantedAccess = GrantedAccess; Request->Req.Create.GrantedAccess = GrantedAccess;
Request->Req.Create.ShareAccess = ShareAccess; Request->Req.Create.ShareAccess = ShareAccess;
Request->Req.Create.Ea.Offset = 0; Request->Req.Create.Ea.Offset = 0 != EaBuffer ?
Request->Req.Create.Ea.Size = 0; (0 != Request->Req.Create.SecurityDescriptor.Offset ?
NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0;
Request->Req.Create.Ea.Size = 0 != EaBuffer ? (UINT16)EaLength : 0;
Request->Req.Create.UserMode = UserMode == RequestorMode; Request->Req.Create.UserMode = UserMode == RequestorMode;
Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege;
Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege; Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege;
@ -601,6 +628,10 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.CaseSensitive = CaseSensitive; Request->Req.Create.CaseSensitive = CaseSensitive;
Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash; Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash;
Request->Req.Create.NamedStream = MainFileName.Length; Request->Req.Create.NamedStream = MainFileName.Length;
#undef NEXTOFS
Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream &&
!!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode;
ASSERT( ASSERT(
0 == StreamPart.Length && 0 == MainFileName.Length || 0 == StreamPart.Length && 0 == MainFileName.Length ||
@ -611,6 +642,11 @@ static NTSTATUS FspFsvolCreateNoLock(
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
SecurityDescriptor, SecurityDescriptorSize); SecurityDescriptor, SecurityDescriptorSize);
/* copy the EA buffer (if any) into the request */
if (0 != EaBuffer)
RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset,
EaBuffer, EaLength);
/* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */ /* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */
if (Request->Req.Create.OpenTargetDirectory) if (Request->Req.Create.OpenTargetDirectory)
{ {
@ -1074,6 +1110,7 @@ NTSTATUS FspFsvolCreateComplete(
} }
PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject); PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject);
FSP_FSCTL_TRANSACT_BUF Ea = Request->Req.Create.Ea;
/* disassociate the FileDesc momentarily from the Request */ /* disassociate the FileDesc momentarily from the Request */
FspIopRequestContext(Request, RequestDeviceObject) = 0; FspIopRequestContext(Request, RequestDeviceObject) = 0;
@ -1094,6 +1131,7 @@ NTSTATUS FspFsvolCreateComplete(
Request->Req.Overwrite.FileAttributes = FileAttributes; Request->Req.Overwrite.FileAttributes = FileAttributes;
Request->Req.Overwrite.AllocationSize = AllocationSize; Request->Req.Overwrite.AllocationSize = AllocationSize;
Request->Req.Overwrite.Supersede = FILE_SUPERSEDED == Response->IoStatus.Information; Request->Req.Overwrite.Supersede = FILE_SUPERSEDED == Response->IoStatus.Information;
Request->Req.Overwrite.Ea = Ea;
/* /*
* Post it as BestEffort. * Post it as BestEffort.
@ -1110,7 +1148,8 @@ NTSTATUS FspFsvolCreateComplete(
* A Reserved request is a special request used when retrying a file open. * A Reserved request is a special request used when retrying a file open.
*/ */
BOOLEAN FlushImage = 0 != FspIopRequestContext(Request, RequestState); BOOLEAN FlushImage =
0 != (RequestFlushImage & (UINT_PTR)FspIopRequestContext(Request, RequestState));
Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage);
} }
@ -1133,8 +1172,16 @@ NTSTATUS FspFsvolCreateComplete(
if (0 == FileNode->MainFileNode) if (0 == FileNode->MainFileNode)
FspFileNodeOverwriteStreams(FileNode); FspFileNodeOverwriteStreams(FileNode);
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE); FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE);
if (0 == FileNode->MainFileNode && FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
{
/* invalidate any existing EA and increment the EA change count */
FspFileNodeSetEa(FileNode, 0, 0);
FileNode->EaChangeCount++;
}
FspFileNodeNotifyChange(FileNode, FspFileNodeNotifyChange(FileNode,
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE, FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
(0 == FileNode->MainFileNode && FsvolDeviceExtension->VolumeParams.ExtendedAttributes ?
FILE_NOTIFY_CHANGE_EA : 0),
FILE_ACTION_MODIFIED, FILE_ACTION_MODIFIED,
FALSE); FALSE);
@ -1178,7 +1225,9 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
FspIopRequestContext(Request, RequestDeviceObject) = RequestDeviceObjectValue; FspIopRequestContext(Request, RequestDeviceObject) = RequestDeviceObjectValue;
FspIopRequestContext(Request, RequestFileDesc) = FileDesc; FspIopRequestContext(Request, RequestFileDesc) = FileDesc;
FspIopRequestContext(Request, RequestFileObject) = FileObject; FspIopRequestContext(Request, RequestFileObject) = FileObject;
FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)FlushImage; FspIopRequestContext(Request, RequestState) = (PVOID)(UINT_PTR)(
(FlushImage ? RequestFlushImage : 0) |
(Request->Req.Create.AcceptsSecurityDescriptor ? RequestAcceptsSecurityDescriptor : 0));
} }
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
@ -1199,8 +1248,28 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
return Result; return Result;
} }
PSECURITY_DESCRIPTOR OpenDescriptor = 0;
ULONG OpenDescriptorSize = 0;
if (0 != (RequestAcceptsSecurityDescriptor &
(UINT_PTR)FspIopRequestContext(Request, RequestState)) &&
Response->Rsp.Create.Opened.HasSecurityDescriptor &&
0 < Response->Rsp.Create.Opened.SecurityDescriptor.Size &&
Response->Buffer +
Response->Rsp.Create.Opened.SecurityDescriptor.Offset +
Response->Rsp.Create.Opened.SecurityDescriptor.Size <=
(PUINT8)Response + Response->Size &&
RtlValidRelativeSecurityDescriptor(
(PUINT8)Response->Buffer +
Response->Rsp.Create.Opened.SecurityDescriptor.Offset,
Response->Rsp.Create.Opened.SecurityDescriptor.Size, 0))
{
OpenDescriptor = (PSECURITY_DESCRIPTOR)(Response->Buffer +
Response->Rsp.Create.Opened.SecurityDescriptor.Offset);
OpenDescriptorSize = Response->Rsp.Create.Opened.SecurityDescriptor.Size;
}
/* /*
* FspFileNodeTrySetFileInfoOnOpen sets the FileNode's metadata to values reported * FspFileNodeTrySetFileInfoAndSecurityOnOpen sets the FileNode's metadata to values reported
* by the user mode file system. It does so only if the file is not already open; the * by the user mode file system. It does so only if the file is not already open; the
* reason is that there is a subtle race condition otherwise. * reason is that there is a subtle race condition otherwise.
* *
@ -1231,12 +1300,13 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
* example, Explorer often opens files to get information about them and may inappropriately * example, Explorer often opens files to get information about them and may inappropriately
* update the FSD view of the file size during WRITE's. * update the FSD view of the file size during WRITE's.
* *
* FspFileNodeTrySetFileInfoOnOpen attempts to mitigate this problem by only updating the * FspFileNodeTrySetFileInfoAndSecurityOnOpen attempts to mitigate this problem by only updating
* FileInfo if the file is not already open. This avoids placing stale information in the * the FileInfo if the file is not already open. This avoids placing stale information in the
* FileNode. * FileNode.
*/ */
FspFileNodeTrySetFileInfoOnOpen(FileNode, FileObject, &Response->Rsp.Create.Opened.FileInfo, FspFileNodeTrySetFileInfoAndSecurityOnOpen(FileNode, FileObject,
&Response->Rsp.Create.Opened.FileInfo, OpenDescriptor, OpenDescriptorSize,
FILE_CREATED == Response->IoStatus.Information); FILE_CREATED == Response->IoStatus.Information);
if (FlushImage) if (FlushImage)

View File

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

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/devctl.c * @file sys/devctl.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -21,6 +21,8 @@
#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;
@ -28,6 +30,7 @@ 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, FspFsvolDeviceControlRequestFini)
@ -39,6 +42,28 @@ enum
RequestFileNode = 0, RequestFileNode = 0,
}; };
static NTSTATUS FspFsvrtDeviceControl(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
/*
* 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( static NTSTATUS FspFsvolDeviceControl(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -155,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

@ -1,7 +1,7 @@
/** /**
* @file sys/device.c * @file sys/device.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -317,7 +317,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
NTSTATUS Result; NTSTATUS Result;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
LARGE_INTEGER IrpTimeout; LARGE_INTEGER IrpTimeout;
LARGE_INTEGER SecurityTimeout, DirInfoTimeout, StreamInfoTimeout; LARGE_INTEGER SecurityTimeout, DirInfoTimeout, StreamInfoTimeout, EaTimeout;
/* /*
* Volume device initialization is a mess, because of the different ways of * Volume device initialization is a mess, because of the different ways of
@ -379,6 +379,16 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
return Result; return Result;
FsvolDeviceExtension->InitDoneStrm = 1; FsvolDeviceExtension->InitDoneStrm = 1;
/* create our EA meta cache */
EaTimeout.QuadPart = FspTimeoutFromMillis(FsvolDeviceExtension->VolumeParams.EaTimeout);
/* convert millis to nanos */
Result = FspMetaCacheCreate(
FspFsvolDeviceEaCacheCapacity, FspFsvolDeviceEaCacheItemSizeMax, &EaTimeout,
&FsvolDeviceExtension->EaCache);
if (!NT_SUCCESS(Result))
return Result;
FsvolDeviceExtension->InitDoneEa = 1;
/* initialize the FSRTL Notify mechanism */ /* initialize the FSRTL Notify mechanism */
Result = FspNotifyInitializeSync(&FsvolDeviceExtension->NotifySync); Result = FspNotifyInitializeSync(&FsvolDeviceExtension->NotifySync);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -449,6 +459,10 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
FspNotifyUninitializeSync(&FsvolDeviceExtension->NotifySync); FspNotifyUninitializeSync(&FsvolDeviceExtension->NotifySync);
} }
/* delete the EA meta cache */
if (FsvolDeviceExtension->InitDoneEa)
FspMetaCacheDelete(FsvolDeviceExtension->EaCache);
/* delete the stream info meta cache */ /* delete the stream info meta cache */
if (FsvolDeviceExtension->InitDoneStrm) if (FsvolDeviceExtension->InitDoneStrm)
FspMetaCacheDelete(FsvolDeviceExtension->StreamInfoCache); FspMetaCacheDelete(FsvolDeviceExtension->StreamInfoCache);

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/dirctl.c * @file sys/dirctl.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -25,6 +25,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive, PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut, PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
BOOLEAN ReturnEaSize,
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize, FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
PVOID DestBuf, PULONG PDestLen); PVOID DestBuf, PULONG PDestLen);
static NTSTATUS FspFsvolQueryDirectoryCopyCache( static NTSTATUS FspFsvolQueryDirectoryCopyCache(
@ -88,6 +89,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive, PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut, PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry,
BOOLEAN ReturnEaSize,
FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize, FSP_FSCTL_DIR_INFO **PDirInfo, ULONG DirInfoSize,
PVOID DestBuf, PULONG PDestLen) PVOID DestBuf, PULONG PDestLen)
{ {
@ -226,12 +228,18 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
break; break;
case FileFullDirectoryInformation: case FileFullDirectoryInformation:
FILL_INFO(FILE_FULL_DIR_INFORMATION, FILL_INFO(FILE_FULL_DIR_INFORMATION,
Info->EaSize = 0; Info->EaSize = ReturnEaSize ? DirInfo->FileInfo.EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaSize)
Info->EaSize += 4;
); );
break; break;
case FileIdFullDirectoryInformation: case FileIdFullDirectoryInformation:
FILL_INFO(FILE_ID_FULL_DIR_INFORMATION, FILL_INFO(FILE_ID_FULL_DIR_INFORMATION,
Info->EaSize = 0; Info->EaSize = ReturnEaSize ? DirInfo->FileInfo.EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaSize)
Info->EaSize += 4;
Info->FileId.QuadPart = DirInfo->FileInfo.IndexNumber; Info->FileId.QuadPart = DirInfo->FileInfo.IndexNumber;
); );
break; break;
@ -240,14 +248,20 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
break; break;
case FileBothDirectoryInformation: case FileBothDirectoryInformation:
FILL_INFO(FILE_BOTH_DIR_INFORMATION, FILL_INFO(FILE_BOTH_DIR_INFORMATION,
Info->EaSize = 0; Info->EaSize = ReturnEaSize ? DirInfo->FileInfo.EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaSize)
Info->EaSize += 4;
Info->ShortNameLength = 0; Info->ShortNameLength = 0;
RtlZeroMemory(Info->ShortName, sizeof Info->ShortName); RtlZeroMemory(Info->ShortName, sizeof Info->ShortName);
); );
break; break;
case FileIdBothDirectoryInformation: case FileIdBothDirectoryInformation:
FILL_INFO(FILE_ID_BOTH_DIR_INFORMATION, FILL_INFO(FILE_ID_BOTH_DIR_INFORMATION,
Info->EaSize = 0; Info->EaSize = ReturnEaSize ? DirInfo->FileInfo.EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaSize)
Info->EaSize += 4;
Info->ShortNameLength = 0; Info->ShortNameLength = 0;
RtlZeroMemory(Info->ShortName, sizeof Info->ShortName); RtlZeroMemory(Info->ShortName, sizeof Info->ShortName);
Info->FileId.QuadPart = DirInfo->FileInfo.IndexNumber; Info->FileId.QuadPart = DirInfo->FileInfo.IndexNumber;
@ -321,6 +335,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyCache(
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive, Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
0 != FileDesc->DirInfoCacheHint ? 0 : &FileDesc->DirectoryMarker, &DirectoryMarker, 0 != FileDesc->DirInfoCacheHint ? 0 : &FileDesc->DirectoryMarker, &DirectoryMarker,
FileInformationClass, ReturnSingleEntry, FileInformationClass, ReturnSingleEntry,
!!FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes,
&DirInfo, DirInfoSize, &DirInfo, DirInfoSize,
DestBuf, PDestLen); DestBuf, PDestLen);
@ -354,6 +369,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive; BOOLEAN CaseInsensitive = !FileDesc->CaseSensitive;
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern; PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker; UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
FSP_FILE_NODE *FileNode = FileDesc->FileNode;
FSP_FSCTL_STATIC_ASSERT( FSP_FSCTL_STATIC_ASSERT(
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >= FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >=
@ -363,6 +379,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive, Result = FspFsvolQueryDirectoryCopy(DirectoryPattern, CaseInsensitive,
0, &DirectoryMarker, 0, &DirectoryMarker,
FileInformationClass, ReturnSingleEntry, FileInformationClass, ReturnSingleEntry,
!!FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes,
&DirInfo, DirInfoSize, &DirInfo, DirInfoSize,
DestBuf, PDestLen); DestBuf, PDestLen);

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/driver.c * @file sys/driver.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -102,8 +102,8 @@ NTSTATUS DriverEntry(
FspFastIoDispatch.FastIoCheckIfPossible = FspFastIoCheckIfPossible; FspFastIoDispatch.FastIoCheckIfPossible = FspFastIoCheckIfPossible;
//FspFastIoDispatch.FastIoRead = 0; //FspFastIoDispatch.FastIoRead = 0;
//FspFastIoDispatch.FastIoWrite = 0; //FspFastIoDispatch.FastIoWrite = 0;
//FspFastIoDispatch.FastIoQueryBasicInfo = 0; FspFastIoDispatch.FastIoQueryBasicInfo = FspFastIoQueryBasicInfo;
//FspFastIoDispatch.FastIoQueryStandardInfo = 0; FspFastIoDispatch.FastIoQueryStandardInfo = FspFastIoQueryStandardInfo;
//FspFastIoDispatch.FastIoLock = 0; //FspFastIoDispatch.FastIoLock = 0;
//FspFastIoDispatch.FastIoUnlockSingle = 0; //FspFastIoDispatch.FastIoUnlockSingle = 0;
//FspFastIoDispatch.FastIoUnlockAll = 0; //FspFastIoDispatch.FastIoUnlockAll = 0;
@ -112,7 +112,7 @@ NTSTATUS DriverEntry(
FspFastIoDispatch.AcquireFileForNtCreateSection = FspAcquireFileForNtCreateSection; FspFastIoDispatch.AcquireFileForNtCreateSection = FspAcquireFileForNtCreateSection;
FspFastIoDispatch.ReleaseFileForNtCreateSection = FspReleaseFileForNtCreateSection; FspFastIoDispatch.ReleaseFileForNtCreateSection = FspReleaseFileForNtCreateSection;
//FspFastIoDispatch.FastIoDetachDevice = 0; //FspFastIoDispatch.FastIoDetachDevice = 0;
//FspFastIoDispatch.FastIoQueryNetworkOpenInfo = 0; FspFastIoDispatch.FastIoQueryNetworkOpenInfo = FspFastIoQueryNetworkOpenInfo;
FspFastIoDispatch.AcquireForModWrite = FspAcquireForModWrite; FspFastIoDispatch.AcquireForModWrite = FspAcquireForModWrite;
//FspFastIoDispatch.MdlRead = 0; //FspFastIoDispatch.MdlRead = 0;
//FspFastIoDispatch.MdlReadComplete = 0; //FspFastIoDispatch.MdlReadComplete = 0;
@ -122,7 +122,7 @@ NTSTATUS DriverEntry(
//FspFastIoDispatch.FastIoWriteCompressed = 0; //FspFastIoDispatch.FastIoWriteCompressed = 0;
//FspFastIoDispatch.MdlReadCompleteCompressed = 0; //FspFastIoDispatch.MdlReadCompleteCompressed = 0;
//FspFastIoDispatch.MdlWriteCompleteCompressed = 0; //FspFastIoDispatch.MdlWriteCompleteCompressed = 0;
//FspFastIoDispatch.FastIoQueryOpen = 0; FspFastIoDispatch.FastIoQueryOpen = FspFastIoQueryOpen;
FspFastIoDispatch.ReleaseForModWrite = FspReleaseForModWrite; FspFastIoDispatch.ReleaseForModWrite = FspReleaseForModWrite;
FspFastIoDispatch.AcquireForCcFlush = FspAcquireForCcFlush; FspFastIoDispatch.AcquireForCcFlush = FspAcquireForCcFlush;
FspFastIoDispatch.ReleaseForCcFlush = FspReleaseForCcFlush; FspFastIoDispatch.ReleaseForCcFlush = FspReleaseForCcFlush;
@ -169,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);

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/driver.h * @file sys/driver.h
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -338,6 +338,10 @@ FSP_IOPREP_DISPATCH FspFsvolWritePrepare;
FSP_IOCMPL_DISPATCH FspFsvolWriteComplete; FSP_IOCMPL_DISPATCH FspFsvolWriteComplete;
/* fast I/O and resource acquisition callbacks */ /* fast I/O and resource acquisition callbacks */
FAST_IO_QUERY_BASIC_INFO FspFastIoQueryBasicInfo;
FAST_IO_QUERY_STANDARD_INFO FspFastIoQueryStandardInfo;
FAST_IO_QUERY_NETWORK_OPEN_INFO FspFastIoQueryNetworkOpenInfo;
FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
FAST_IO_CHECK_IF_POSSIBLE FspFastIoCheckIfPossible; FAST_IO_CHECK_IF_POSSIBLE FspFastIoCheckIfPossible;
FAST_IO_ACQUIRE_FILE FspAcquireFileForNtCreateSection; FAST_IO_ACQUIRE_FILE FspAcquireFileForNtCreateSection;
FAST_IO_RELEASE_FILE FspReleaseFileForNtCreateSection; FAST_IO_RELEASE_FILE FspReleaseFileForNtCreateSection;
@ -448,12 +452,17 @@ enum
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength, BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
PUNICODE_STRING StreamPart, PULONG StreamType); PUNICODE_STRING StreamPart, PULONG StreamType);
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern, ULONG MaxComponentLength); BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern, ULONG MaxComponentLength);
BOOLEAN FspEaNameIsValid(PSTRING Name);
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
#if 0 #if 0
NTSTATUS FspFileNameUpcase( NTSTATUS FspFileNameUpcase(
PUNICODE_STRING DestinationName, PUNICODE_STRING DestinationName,
PUNICODE_STRING SourceName, PUNICODE_STRING SourceName,
PCWCH UpcaseTable); PCWCH UpcaseTable);
VOID FspEaNameUpcase(
PSTRING DestinationName,
PSTRING SourceName,
PCWCH UpcaseTable);
LONG FspFileNameCompare( LONG FspFileNameCompare(
PUNICODE_STRING Name1, PUNICODE_STRING Name1,
PUNICODE_STRING Name2, PUNICODE_STRING Name2,
@ -466,6 +475,7 @@ BOOLEAN FspFileNameIsPrefix(
PCWCH UpcaseTable); PCWCH UpcaseTable);
#else #else
#define FspFileNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpcaseUnicodeString(D,S,FALSE)) #define FspFileNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpcaseUnicodeString(D,S,FALSE))
#define FspEaNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpperString(D,S))
#define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), RtlCompareUnicodeString(N1,N2,I)) #define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), RtlCompareUnicodeString(N1,N2,I))
#define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I)) #define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I))
#endif #endif
@ -505,6 +515,14 @@ NTSTATUS FspCcFlushCache(PSECTION_OBJECT_POINTERS SectionObjectPointer,
NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation, NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength,
PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor); PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor);
NTSTATUS FspEaBufferFromOriginatingProcessValidate(
PFILE_FULL_EA_INFORMATION Buffer,
ULONG Length,
PULONG PErrorOffset);
NTSTATUS FspEaBufferFromFileSystemValidate(
PFILE_FULL_EA_INFORMATION Buffer,
ULONG Length,
PULONG PErrorOffset);
NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync); NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync);
NTSTATUS FspNotifyFullChangeDirectory( NTSTATUS FspNotifyFullChangeDirectory(
PNOTIFY_SYNC NotifySync, PNOTIFY_SYNC NotifySync,
@ -563,6 +581,8 @@ NTSTATUS FspOplockFsctrl(
FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0) FspNotifyFullChangeDirectory(NS, NL, FC, 0, 0, FALSE, 0, 0, 0, 0)
#define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\ #define FspNotifyReportChange(NS, NL, FN, FO, NP, F, A)\
FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0) FspNotifyFullReportChange(NS, NL, (PSTRING)(FN), FO, 0, (PSTRING)(NP), F, A, 0)
#define FSP_NEXT_EA(Ea, EaEnd) \
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
/* utility: synchronous work queue */ /* utility: synchronous work queue */
typedef struct typedef struct
@ -993,6 +1013,8 @@ enum
FspFsvolDeviceDirInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE), FspFsvolDeviceDirInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE),
FspFsvolDeviceStreamInfoCacheCapacity = 100, FspFsvolDeviceStreamInfoCacheCapacity = 100,
FspFsvolDeviceStreamInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE), FspFsvolDeviceStreamInfoCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE),
FspFsvolDeviceEaCacheCapacity = 100,
FspFsvolDeviceEaCacheItemSizeMax = FSP_FSCTL_ALIGN_UP(16384, PAGE_SIZE),
}; };
typedef struct typedef struct
{ {
@ -1025,7 +1047,7 @@ typedef struct
typedef struct typedef struct
{ {
FSP_DEVICE_EXTENSION Base; FSP_DEVICE_EXTENSION Base;
UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1, UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1, InitDoneEa:1,
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1; InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
PDEVICE_OBJECT FsctlDeviceObject; PDEVICE_OBJECT FsctlDeviceObject;
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
@ -1039,6 +1061,7 @@ typedef struct
FSP_META_CACHE *SecurityCache; FSP_META_CACHE *SecurityCache;
FSP_META_CACHE *DirInfoCache; FSP_META_CACHE *DirInfoCache;
FSP_META_CACHE *StreamInfoCache; FSP_META_CACHE *StreamInfoCache;
FSP_META_CACHE *EaCache;
KSPIN_LOCK ExpirationLock; KSPIN_LOCK ExpirationLock;
WORK_QUEUE_ITEM ExpirationWorkItem; WORK_QUEUE_ITEM ExpirationWorkItem;
BOOLEAN ExpirationInProgress; BOOLEAN ExpirationInProgress;
@ -1262,11 +1285,15 @@ typedef struct FSP_FILE_NODE
UINT64 LastAccessTime; UINT64 LastAccessTime;
UINT64 LastWriteTime; UINT64 LastWriteTime;
UINT64 ChangeTime; UINT64 ChangeTime;
UINT32 EaSize;
ULONG FileInfoChangeNumber; ULONG FileInfoChangeNumber;
UINT64 Security; UINT64 Security;
ULONG SecurityChangeNumber; ULONG SecurityChangeNumber;
ULONG DirInfoChangeNumber; ULONG DirInfoChangeNumber;
ULONG StreamInfoChangeNumber; ULONG StreamInfoChangeNumber;
UINT64 Ea;
ULONG EaChangeNumber;
ULONG EaChangeCount;
BOOLEAN TruncateOnClose; BOOLEAN TruncateOnClose;
FILE_LOCK FileLock; FILE_LOCK FileLock;
#if (NTDDI_VERSION < NTDDI_WIN8) #if (NTDDI_VERSION < NTDDI_WIN8)
@ -1305,6 +1332,8 @@ typedef struct
UNICODE_STRING DirectoryMarker; UNICODE_STRING DirectoryMarker;
UINT64 DirInfo; UINT64 DirInfo;
ULONG DirInfoCacheHint; ULONG DirInfoCacheHint;
ULONG EaIndex;
ULONG EaChangeCount;
/* stream support */ /* stream support */
HANDLE MainFileHandle; HANDLE MainFileHandle;
PFILE_OBJECT MainFileObject; PFILE_OBJECT MainFileObject;
@ -1382,10 +1411,14 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
BOOLEAN FspFileNodeTryGetFileInfoByName(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
PUNICODE_STRING FileName, FSP_FSCTL_FILE_INFO *FileInfo);
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose); const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose);
BOOLEAN FspFileNodeTrySetFileInfoOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, BOOLEAN FspFileNodeTrySetFileInfoAndSecurityOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose); const FSP_FSCTL_FILE_INFO *FileInfo,
const PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorSize,
BOOLEAN TruncateOnClose);
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber); const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode);
@ -1431,6 +1464,17 @@ ULONG FspFileNodeStreamInfoChangeNumber(FSP_FILE_NODE *FileNode)
return FileNode->StreamInfoChangeNumber; return FileNode->StreamInfoChangeNumber;
} }
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
BOOLEAN FspFileNodeReferenceEa(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
VOID FspFileNodeSetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG EaChangeNumber);
static inline
ULONG FspFileNodeEaChangeNumber(FSP_FILE_NODE *FileNode)
{
if (0 != FileNode->MainFileNode)
FileNode = FileNode->MainFileNode;
return FileNode->EaChangeNumber;
}
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
BOOLEAN InvalidateCaches); BOOLEAN InvalidateCaches);
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
@ -1463,6 +1507,7 @@ NTSTATUS FspMainFileClose(
#define FspFileNodeDereferenceSecurity(P) FspMetaCacheDereferenceItemBuffer(P) #define FspFileNodeDereferenceSecurity(P) FspMetaCacheDereferenceItemBuffer(P)
#define FspFileNodeDereferenceDirInfo(P) FspMetaCacheDereferenceItemBuffer(P) #define FspFileNodeDereferenceDirInfo(P) FspMetaCacheDereferenceItemBuffer(P)
#define FspFileNodeDereferenceStreamInfo(P) FspMetaCacheDereferenceItemBuffer(P) #define FspFileNodeDereferenceStreamInfo(P) FspMetaCacheDereferenceItemBuffer(P)
#define FspFileNodeDereferenceEa(P) FspMetaCacheDereferenceItemBuffer(P)
#define FspFileNodeUnlockAll(N,F,P) FsRtlFastUnlockAll(&(N)->FileLock, F, P, N) #define FspFileNodeUnlockAll(N,F,P) FsRtlFastUnlockAll(&(N)->FileLock, F, P, N)
#if (NTDDI_VERSION < NTDDI_WIN8) #if (NTDDI_VERSION < NTDDI_WIN8)
#define FspFileNodeAddrOfOplock(N) (&(N)->Oplock) #define FspFileNodeAddrOfOplock(N) (&(N)->Oplock)

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/ea.c * @file sys/ea.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -21,30 +21,390 @@
#include <sys/driver.h> #include <sys/driver.h>
static VOID FspFsvolQueryEaGetCopy(
BOOLEAN CasePreservedExtendedAttributes,
BOOLEAN ReturnSingleEntry,
PFILE_GET_EA_INFORMATION GetBufBgn, ULONG GetSize,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus);
static VOID FspFsvolQueryEaIndexCopy(
BOOLEAN CasePreservedExtendedAttributes,
BOOLEAN ReturnSingleEntry,
BOOLEAN IndexSpecified, PULONG PEaIndex,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus);
static VOID FspFsvolQueryEaCopy(
BOOLEAN CasePreservedExtendedAttributes,
PIO_STACK_LOCATION IrpSp,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus);
static NTSTATUS FspFsvolQueryEa( static NTSTATUS FspFsvolQueryEa(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete;
static FSP_IOP_REQUEST_FINI FspFsvolQueryEaRequestFini;
static NTSTATUS FspFsvolSetEa( static NTSTATUS FspFsvolSetEa(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolSetEaComplete; FSP_IOCMPL_DISPATCH FspFsvolSetEaComplete;
static FSP_IOP_REQUEST_FINI FspFsvolSetEaRequestFini;
FSP_DRIVER_DISPATCH FspQueryEa; FSP_DRIVER_DISPATCH FspQueryEa;
FSP_DRIVER_DISPATCH FspSetEa; FSP_DRIVER_DISPATCH FspSetEa;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvolQueryEaGetCopy)
#pragma alloc_text(PAGE, FspFsvolQueryEaIndexCopy)
#pragma alloc_text(PAGE, FspFsvolQueryEa) #pragma alloc_text(PAGE, FspFsvolQueryEa)
#pragma alloc_text(PAGE, FspFsvolQueryEaComplete) #pragma alloc_text(PAGE, FspFsvolQueryEaComplete)
#pragma alloc_text(PAGE, FspFsvolQueryEaRequestFini)
#pragma alloc_text(PAGE, FspFsvolSetEa) #pragma alloc_text(PAGE, FspFsvolSetEa)
#pragma alloc_text(PAGE, FspFsvolSetEaComplete) #pragma alloc_text(PAGE, FspFsvolSetEaComplete)
#pragma alloc_text(PAGE, FspFsvolSetEaRequestFini)
#pragma alloc_text(PAGE, FspQueryEa) #pragma alloc_text(PAGE, FspQueryEa)
#pragma alloc_text(PAGE, FspSetEa) #pragma alloc_text(PAGE, FspSetEa)
#endif #endif
static NTSTATUS FspFsvolQueryEa( enum
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) {
/* QueryEa */
RequestFileNode = 0,
RequestEaChangeNumber = 1,
/* SetEa */
//RequestFileNode = 0,
};
static VOID FspFsvolQueryEaGetCopy(
BOOLEAN CasePreservedExtendedAttributes,
BOOLEAN ReturnSingleEntry,
PFILE_GET_EA_INFORMATION GetBufBgn, ULONG GetSize,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus)
{ {
PAGED_CODE(); PAGED_CODE();
PFILE_GET_EA_INFORMATION GetBuf, GetBufEnd = (PVOID)((PUINT8)GetBufBgn + GetSize);
PFILE_GET_EA_INFORMATION Get;
PFILE_FULL_EA_INFORMATION SrcBuf, SrcBufEnd = (PVOID)((PUINT8)SrcBufBgn + SrcSize);
PFILE_FULL_EA_INFORMATION DstBuf, DstBufEnd = (PVOID)((PUINT8)DstBufBgn + DstSize);
PFILE_FULL_EA_INFORMATION PrevDstBuf;
PFILE_FULL_EA_INFORMATION Src;
STRING GetName, Name;
ULONG CopyLength;
IoStatus->Information = 0;
DstBuf = DstBufBgn, PrevDstBuf = 0;
for (GetBuf = GetBufBgn; GetBufEnd > GetBuf; GetBuf = FSP_NEXT_EA(GetBuf, GetBufEnd))
{
GetName.Length = GetName.MaximumLength = GetBuf->EaNameLength;
GetName.Buffer = GetBuf->EaName;
/* ignore duplicate names */
for (Get = GetBufBgn; GetBuf > Get; Get = (PVOID)((PUINT8)Get + Get->NextEntryOffset))
{
Name.Length = Name.MaximumLength = Get->EaNameLength;
Name.Buffer = Get->EaName;
if (RtlEqualString(&GetName, &Name, TRUE/* always case-insensitive */))
break;
}
if (GetBuf > Get)
continue;
if (!FspEaNameIsValid(&GetName))
{
IoStatus->Status = STATUS_INVALID_EA_NAME;
IoStatus->Information = (ULONG)((PUINT8)GetBuf - (PUINT8)GetBufBgn);
return;
}
Src = 0;
for (SrcBuf = SrcBufBgn; SrcBufEnd > SrcBuf; SrcBuf = FSP_NEXT_EA(SrcBuf, SrcBufEnd))
{
Name.Length = Name.MaximumLength = SrcBuf->EaNameLength;
Name.Buffer = SrcBuf->EaName;
if (RtlEqualString(&GetName, &Name, TRUE/* always case-insensitive */))
{
Src = SrcBuf;
break;
}
}
if (0 != Src)
CopyLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
Src->EaNameLength + 1 + Src->EaValueLength;
else
CopyLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
GetBuf->EaNameLength + 1;
if ((PUINT8)DstBuf + CopyLength > (PUINT8)DstBufEnd)
{
IoStatus->Status = STATUS_BUFFER_OVERFLOW;
IoStatus->Information = 0;
return;
}
if (0 != Src)
RtlMoveMemory(DstBuf, Src, CopyLength);
else
{
DstBuf->Flags = 0;
DstBuf->EaNameLength = GetBuf->EaNameLength;
DstBuf->EaValueLength = 0;
RtlCopyMemory(DstBuf->EaName, GetBuf->EaName, GetBuf->EaNameLength + 1);
}
DstBuf->NextEntryOffset = 0;
if (!CasePreservedExtendedAttributes)
{
Name.Length = Name.MaximumLength = DstBuf->EaNameLength;
Name.Buffer = DstBuf->EaName;
FspEaNameUpcase(&Name, &Name, 0);
}
if (0 != PrevDstBuf)
PrevDstBuf->NextEntryOffset = (ULONG)((PUINT8)DstBuf - (PUINT8)PrevDstBuf);
PrevDstBuf = DstBuf;
IoStatus->Information = (ULONG)((PUINT8)DstBuf - (PUINT8)DstBufBgn + CopyLength);
DstBuf = (PVOID)((PUINT8)DstBuf + FSP_FSCTL_ALIGN_UP(CopyLength, sizeof(ULONG)));
if (ReturnSingleEntry)
break;
}
IoStatus->Status = STATUS_SUCCESS;
}
static VOID FspFsvolQueryEaIndexCopy(
BOOLEAN CasePreservedExtendedAttributes,
BOOLEAN ReturnSingleEntry,
BOOLEAN IndexSpecified, PULONG PEaIndex,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus)
{
PAGED_CODE();
ULONG EaIndex = 1;
PFILE_FULL_EA_INFORMATION SrcBuf, SrcBufEnd = (PVOID)((PUINT8)SrcBufBgn + SrcSize);
PFILE_FULL_EA_INFORMATION DstBuf, DstBufEnd = (PVOID)((PUINT8)DstBufBgn + DstSize);
PFILE_FULL_EA_INFORMATION PrevDstBuf;
STRING Name;
ULONG CopyLength;
if (IndexSpecified && 0 == *PEaIndex)
{
IoStatus->Status = STATUS_NONEXISTENT_EA_ENTRY;
IoStatus->Information = 0;
return;
}
for (SrcBuf = SrcBufBgn; EaIndex < *PEaIndex && SrcBufEnd > SrcBuf;
SrcBuf = FSP_NEXT_EA(SrcBuf, SrcBufEnd))
EaIndex++;
IoStatus->Information = 0;
DstBuf = DstBufBgn, PrevDstBuf = 0;
for (; SrcBufEnd > SrcBuf; SrcBuf = FSP_NEXT_EA(SrcBuf, SrcBufEnd))
{
CopyLength = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
((PFILE_FULL_EA_INFORMATION)SrcBuf)->EaNameLength + 1 +
((PFILE_FULL_EA_INFORMATION)SrcBuf)->EaValueLength;
if ((PUINT8)DstBuf + CopyLength > (PUINT8)DstBufEnd)
{
if (0 != PrevDstBuf)
break;
IoStatus->Status = STATUS_BUFFER_TOO_SMALL;
IoStatus->Information = 0;
return;
}
RtlMoveMemory(DstBuf, SrcBuf, CopyLength);
DstBuf->NextEntryOffset = 0;
if (!CasePreservedExtendedAttributes)
{
Name.Length = Name.MaximumLength = DstBuf->EaNameLength;
Name.Buffer = DstBuf->EaName;
FspEaNameUpcase(&Name, &Name, 0);
}
if (0 != PrevDstBuf)
PrevDstBuf->NextEntryOffset = (ULONG)((PUINT8)DstBuf - (PUINT8)PrevDstBuf);
PrevDstBuf = DstBuf;
IoStatus->Information = (ULONG)((PUINT8)DstBuf - (PUINT8)DstBufBgn + CopyLength);
DstBuf = (PVOID)((PUINT8)DstBuf + FSP_FSCTL_ALIGN_UP(CopyLength, sizeof(ULONG)));
EaIndex++;
if (ReturnSingleEntry)
break;
}
if (IndexSpecified)
{
if (0 != PrevDstBuf)
{
*PEaIndex = EaIndex;
IoStatus->Status = SrcBufEnd > SrcBuf && !ReturnSingleEntry ?
STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
}
else
{
IoStatus->Status = *PEaIndex == EaIndex ?
STATUS_NO_MORE_EAS : STATUS_NONEXISTENT_EA_ENTRY;
IoStatus->Information = 0;
}
}
else
{
if (0 != PrevDstBuf)
{
*PEaIndex = EaIndex;
IoStatus->Status = SrcBufEnd > SrcBuf && !ReturnSingleEntry ?
STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
}
else
{
IoStatus->Status = SrcBufBgn == SrcBuf ?
STATUS_NO_EAS_ON_FILE : STATUS_NO_MORE_EAS;
IoStatus->Information = 0;
}
}
}
static VOID FspFsvolQueryEaCopy(
BOOLEAN CasePreservedExtendedAttributes,
PIO_STACK_LOCATION IrpSp,
PFILE_FULL_EA_INFORMATION SrcBufBgn, ULONG SrcSize,
PFILE_FULL_EA_INFORMATION DstBufBgn, ULONG DstSize,
PIO_STATUS_BLOCK IoStatus)
{
PAGED_CODE();
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
BOOLEAN RestartScan = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN);
BOOLEAN IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
PFILE_GET_EA_INFORMATION EaList = IrpSp->Parameters.QueryEa.EaList;
ULONG EaListLength = IrpSp->Parameters.QueryEa.EaListLength;
ULONG EaIndex;
ASSERT(FileNode == FileDesc->FileNode);
if (0 != EaList)
{
FspFsvolQueryEaGetCopy(
CasePreservedExtendedAttributes,
ReturnSingleEntry,
EaList, EaListLength,
SrcBufBgn, SrcSize,
DstBufBgn, DstSize,
IoStatus);
}
else
{
if (!IndexSpecified &&
!RestartScan &&
0 != FileDesc->EaIndex &&
FileNode->EaChangeCount != FileDesc->EaChangeCount)
{
IoStatus->Status = STATUS_EA_CORRUPT_ERROR;
IoStatus->Information = 0;
return;
}
if (IndexSpecified)
EaIndex = IrpSp->Parameters.QueryEa.EaIndex;
else if (RestartScan)
EaIndex = 0;
else
EaIndex = FileDesc->EaIndex;
FspFsvolQueryEaIndexCopy(
CasePreservedExtendedAttributes,
ReturnSingleEntry,
IndexSpecified, &EaIndex,
SrcBufBgn, SrcSize,
DstBufBgn, DstSize,
IoStatus);
if (NT_SUCCESS(IoStatus->Status) || STATUS_BUFFER_OVERFLOW == IoStatus->Status)
{
FileDesc->EaIndex = EaIndex;
FileDesc->EaChangeCount = FileNode->EaChangeCount;
}
}
}
static NTSTATUS FspFsvolQueryEa(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
/* do we support Ea? */
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
/* is this a valid FileObject? */
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
return STATUS_INVALID_DEVICE_REQUEST;
NTSTATUS Result;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
PVOID Buffer = Irp->UserBuffer;
ULONG Length = IrpSp->Parameters.QueryEa.Length;
PVOID EaBuffer;
ULONG EaBufferSize;
FSP_FSCTL_TRANSACT_REQ *Request;
ASSERT(FileNode == FileDesc->FileNode);
FspFileNodeAcquireExclusive(FileNode, Main);
if (FspFileNodeReferenceEa(FileNode, &EaBuffer, &EaBufferSize))
{
FspFsvolQueryEaCopy(
!!FsvolDeviceExtension->VolumeParams.CasePreservedExtendedAttributes,
IrpSp,
EaBuffer, EaBufferSize,
Buffer, Length,
&Irp->IoStatus);
FspFileNodeDereferenceEa(EaBuffer);
FspFileNodeRelease(FileNode, Main);
return Irp->IoStatus.Status;
}
FspFileNodeConvertExclusiveToShared(FileNode, Main);
FspFileNodeAcquireShared(FileNode, Pgio);
Result = FspBufferUserBuffer(Irp, Length, IoWriteAccess);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Full);
return Result;
}
Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolQueryEaRequestFini, &Request);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Full);
return Result;
}
Request->Kind = FspFsctlTransactQueryEaKind;
Request->Req.QueryEa.UserContext = FileNode->UserContext;
Request->Req.QueryEa.UserContext2 = FileDesc->UserContext2;
FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode;
return FSP_STATUS_IOQ_POST;
} }
NTSTATUS FspFsvolQueryEaComplete( NTSTATUS FspFsvolQueryEaComplete(
@ -52,15 +412,155 @@ NTSTATUS FspFsvolQueryEaComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); FSP_ENTER_IOC(PAGED_CODE());
FSP_LEAVE_IOC("%s", ""); if (!NT_SUCCESS(Response->IoStatus.Status))
{
Irp->IoStatus.Information = 0;
Result = Response->IoStatus.Status;
FSP_RETURN();
} }
static NTSTATUS FspFsvolSetEa( PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG Length = IrpSp->Parameters.QueryEa.Length;
PVOID EaBuffer = 0;
ULONG EaBufferSize = 0;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
BOOLEAN Success;
if (0 != FspIopRequestContext(Request, RequestFileNode))
{
/* check that the EA buffer we got back is valid */
if (Response->Buffer + Response->Rsp.QueryEa.Ea.Size >
(PUINT8)Response + Response->Size)
{
Irp->IoStatus.Information = 0;
Result = STATUS_EA_LIST_INCONSISTENT;
FSP_RETURN();
}
Result = FspEaBufferFromFileSystemValidate(
(PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */
Response->Rsp.QueryEa.Ea.Size,
(PULONG)&Irp->IoStatus.Information);
if (!NT_SUCCESS(Result))
FSP_RETURN();
FspIopRequestContext(Request, RequestEaChangeNumber) = (PVOID)
FspFileNodeEaChangeNumber(FileNode);
FspIopRequestContext(Request, RequestFileNode) = 0;
FspFileNodeReleaseOwner(FileNode, Full, Request);
}
Success = DEBUGTEST(90) && FspFileNodeTryAcquireExclusive(FileNode, Main);
if (!Success)
{
FspIopRetryCompleteIrp(Irp, Response, &Result);
FSP_RETURN();
}
Success = !FspFileNodeTrySetEa(FileNode,
Response->Buffer, Response->Rsp.QueryEa.Ea.Size,
(ULONG)(UINT_PTR)FspIopRequestContext(Request, RequestEaChangeNumber));
Success = Success && FspFileNodeReferenceEa(FileNode, &EaBuffer, &EaBufferSize);
if (Success)
{
FspFsvolQueryEaCopy(
!!FsvolDeviceExtension->VolumeParams.CasePreservedExtendedAttributes,
IrpSp,
EaBuffer, EaBufferSize,
Buffer, Length,
&Irp->IoStatus);
FspFileNodeDereferenceEa(EaBuffer);
}
else
{
EaBuffer = (PVOID)Response->Buffer;
EaBufferSize = Response->Rsp.QueryEa.Ea.Size;
FspFsvolQueryEaCopy(
!!FsvolDeviceExtension->VolumeParams.CasePreservedExtendedAttributes,
IrpSp,
EaBuffer, EaBufferSize,
Buffer, Length,
&Irp->IoStatus);
}
FspFileNodeRelease(FileNode, Main);
Result = Irp->IoStatus.Status;
FSP_LEAVE_IOC("FileObject=%p",
IrpSp->FileObject);
}
static VOID FspFsvolQueryEaRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{ {
PAGED_CODE(); PAGED_CODE();
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
if (0 != FileNode)
FspFileNodeReleaseOwner(FileNode, Full, Request);
}
static NTSTATUS FspFsvolSetEa(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
/* do we support Ea? */
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
/* is this a valid FileObject? */
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
return STATUS_INVALID_DEVICE_REQUEST;
NTSTATUS Result;
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
PVOID Buffer;
ULONG Length = IrpSp->Parameters.SetEa.Length;
FSP_FSCTL_TRANSACT_REQ *Request;
ASSERT(FileNode == FileDesc->FileNode);
Result = FspBufferUserBuffer(Irp, Length, IoReadAccess);
if (!NT_SUCCESS(Result))
return Result;
Buffer = Irp->AssociatedIrp.SystemBuffer;
Result = FspEaBufferFromOriginatingProcessValidate(
Buffer, Length, (PULONG)&Irp->IoStatus.Information);
if (!NT_SUCCESS(Result))
return Result;
FspFileNodeAcquireExclusive(FileNode, Full);
Result = FspIopCreateRequestEx(Irp, 0, Length, FspFsvolSetEaRequestFini,
&Request);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Full);
return Result;
}
Request->Kind = FspFsctlTransactSetEaKind;
Request->Req.SetEa.UserContext = FileNode->UserContext;
Request->Req.SetEa.UserContext2 = FileDesc->UserContext2;
Request->Req.SetEa.Ea.Offset = 0;
Request->Req.SetEa.Ea.Size = (UINT16)Length;
RtlCopyMemory(Request->Buffer, Buffer, Length);
FspFileNodeSetOwner(FileNode, Full, Request);
FspIopRequestContext(Request, RequestFileNode) = FileNode;
return FSP_STATUS_IOQ_POST;
} }
NTSTATUS FspFsvolSetEaComplete( NTSTATUS FspFsvolSetEaComplete(
@ -68,7 +568,65 @@ NTSTATUS FspFsvolSetEaComplete(
{ {
FSP_ENTER_IOC(PAGED_CODE()); FSP_ENTER_IOC(PAGED_CODE());
FSP_LEAVE_IOC("%s", ""); if (!NT_SUCCESS(Response->IoStatus.Status))
{
Irp->IoStatus.Information = 0;
Result = Response->IoStatus.Status;
FSP_RETURN();
}
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
BOOLEAN EaValid;
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetEa.FileInfo, FALSE);
EaValid = FALSE;
if (0 < Response->Rsp.SetEa.Ea.Size &&
Response->Buffer + Response->Rsp.SetEa.Ea.Size <=
(PUINT8)Response + Response->Size)
{
Result = FspEaBufferFromFileSystemValidate(
(PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */
Response->Rsp.SetEa.Ea.Size,
(PULONG)&Irp->IoStatus.Information);
EaValid = NT_SUCCESS(Result);
}
if (EaValid)
{
/* if the EA buffer that we got back is valid, update the cached EA */
FspFileNodeSetEa(FileNode,
Response->Buffer, Response->Rsp.SetEa.Ea.Size);
}
else
{
/* if the EA buffer that we got back is not valid, invalidate the cached EA */
FspFileNodeSetEa(FileNode, 0, 0);
}
FileNode->EaChangeCount++;
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_EA, FILE_ACTION_MODIFIED, FALSE);
FspIopRequestContext(Request, RequestFileNode) = 0;
FspFileNodeReleaseOwner(FileNode, Full, Request);
Irp->IoStatus.Information = 0;
Result = STATUS_SUCCESS;
FSP_LEAVE_IOC("FileObject=%p",
IrpSp->FileObject);
}
static VOID FspFsvolSetEaRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
{
PAGED_CODE();
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
if (0 != FileNode)
FspFileNodeReleaseOwner(FileNode, Full, Request);
} }
NTSTATUS FspQueryEa( NTSTATUS FspQueryEa(
@ -84,7 +642,8 @@ NTSTATUS FspQueryEa(
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
} }
FSP_LEAVE_MJ("%s", ""); FSP_LEAVE_MJ("FileObject=%p",
IrpSp->FileObject);
} }
NTSTATUS FspSetEa( NTSTATUS FspSetEa(
@ -100,5 +659,6 @@ NTSTATUS FspSetEa(
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
} }
FSP_LEAVE_MJ("%s", ""); FSP_LEAVE_MJ("FileObject=%p",
IrpSp->FileObject);
} }

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/file.c * @file sys/file.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -61,10 +61,14 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName); VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
BOOLEAN FspFileNodeTryGetFileInfoByName(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
PUNICODE_STRING FileName, FSP_FSCTL_FILE_INFO *FileInfo);
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose); const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose);
BOOLEAN FspFileNodeTrySetFileInfoOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, BOOLEAN FspFileNodeTrySetFileInfoAndSecurityOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose); const FSP_FSCTL_FILE_INFO *FileInfo,
const PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorSize,
BOOLEAN TruncateOnClose);
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber); const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode);
@ -85,6 +89,10 @@ VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size, BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG StreamInfoChangeNumber); ULONG StreamInfoChangeNumber);
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode); VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
BOOLEAN FspFileNodeReferenceEa(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
VOID FspFileNodeSetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
BOOLEAN FspFileNodeTrySetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG EaChangeNumber);
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
BOOLEAN InvalidateCaches); BOOLEAN InvalidateCaches);
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp); NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
@ -136,8 +144,9 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
#pragma alloc_text(PAGE, FspFileNodeRename) #pragma alloc_text(PAGE, FspFileNodeRename)
#pragma alloc_text(PAGE, FspFileNodeGetFileInfo) #pragma alloc_text(PAGE, FspFileNodeGetFileInfo)
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo) #pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfoByName)
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo) #pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
#pragma alloc_text(PAGE, FspFileNodeTrySetFileInfoOnOpen) #pragma alloc_text(PAGE, FspFileNodeTrySetFileInfoAndSecurityOnOpen)
#pragma alloc_text(PAGE, FspFileNodeTrySetFileInfo) #pragma alloc_text(PAGE, FspFileNodeTrySetFileInfo)
#pragma alloc_text(PAGE, FspFileNodeInvalidateFileInfo) #pragma alloc_text(PAGE, FspFileNodeInvalidateFileInfo)
#pragma alloc_text(PAGE, FspFileNodeReferenceSecurity) #pragma alloc_text(PAGE, FspFileNodeReferenceSecurity)
@ -153,6 +162,9 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
// !#pragma alloc_text(PAGE, FspFileNodeSetStreamInfo) // !#pragma alloc_text(PAGE, FspFileNodeSetStreamInfo)
// !#pragma alloc_text(PAGE, FspFileNodeTrySetStreamInfo) // !#pragma alloc_text(PAGE, FspFileNodeTrySetStreamInfo)
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateStreamInfo) // !#pragma alloc_text(PAGE, FspFileNodeInvalidateStreamInfo)
#pragma alloc_text(PAGE, FspFileNodeReferenceEa)
#pragma alloc_text(PAGE, FspFileNodeSetEa)
#pragma alloc_text(PAGE, FspFileNodeTrySetEa)
#pragma alloc_text(PAGE, FspFileNodeNotifyChange) #pragma alloc_text(PAGE, FspFileNodeNotifyChange)
#pragma alloc_text(PAGE, FspFileNodeProcessLockIrp) #pragma alloc_text(PAGE, FspFileNodeProcessLockIrp)
#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp) #pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp)
@ -356,6 +368,7 @@ VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode)
FsRtlTeardownPerStreamContexts(&FileNode->Header); FsRtlTeardownPerStreamContexts(&FileNode->Header);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->EaCache, FileNode->Ea);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, FileNode->NonPaged->StreamInfo); FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, FileNode->NonPaged->StreamInfo);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo); FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, FileNode->NonPaged->DirInfo);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->SecurityCache, FileNode->Security); FspMetaCacheInvalidateItem(FsvolDeviceExtension->SecurityCache, FileNode->Security);
@ -1618,6 +1631,7 @@ VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileIn
FileInfo->LastAccessTime = FileNode->LastAccessTime; FileInfo->LastAccessTime = FileNode->LastAccessTime;
FileInfo->LastWriteTime = FileNode->LastWriteTime; FileInfo->LastWriteTime = FileNode->LastWriteTime;
FileInfo->ChangeTime = FileNode->ChangeTime; FileInfo->ChangeTime = FileNode->ChangeTime;
FileInfo->EaSize = FileNode->EaSize;
} }
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo) BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo)
@ -1640,6 +1654,78 @@ BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *
return TRUE; return TRUE;
} }
BOOLEAN FspFileNodeTryGetFileInfoByName(PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp,
PUNICODE_STRING FileName, FSP_FSCTL_FILE_INFO *FileInfo)
{
PAGED_CODE();
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PACCESS_STATE AccessState = IrpSp->Parameters.Create.SecurityContext->AccessState;
ACCESS_MASK DesiredAccess = AccessState->RemainingDesiredAccess;
ACCESS_MASK GrantedAccess = AccessState->PreviouslyGrantedAccess;
KPROCESSOR_MODE RequestorMode =
FlagOn(IrpSp->Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode;
BOOLEAN HasTraversePrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_TRAVERSE_PRIVILEGE);
FSP_FILE_NODE *FileNode;
PVOID SecurityBuffer;
BOOLEAN Result;
if (UserMode == RequestorMode)
{
/* user mode: allow only FILE_READ_ATTRIBUTES with traverse privilege */
if (FILE_READ_ATTRIBUTES != DesiredAccess || !HasTraversePrivilege)
return FALSE;
}
else
/* kernel mode: anything goes! */
DesiredAccess = 0;
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
FileNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, FileName);
if (0 != FileNode)
FspFileNodeReference(FileNode);
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
Result = FALSE;
if (0 != FileNode)
{
FspFileNodeAcquireShared(FileNode, Main);
if (0 != DesiredAccess)
{
ASSERT(FILE_READ_ATTRIBUTES == DesiredAccess);
if (FspFileNodeReferenceSecurity(FileNode, &SecurityBuffer, 0))
{
NTSTATUS AccessStatus;
Result = SeAccessCheck(
SecurityBuffer,
&AccessState->SubjectSecurityContext,
TRUE,
DesiredAccess,
GrantedAccess,
0,
IoGetFileObjectGenericMapping(),
RequestorMode,
&GrantedAccess,
&AccessStatus);
FspFileNodeDereferenceSecurity(SecurityBuffer);
Result = Result && FspFileNodeTryGetFileInfo(FileNode, FileInfo);
}
}
else
Result = FspFileNodeTryGetFileInfo(FileNode, FileInfo);
FspFileNodeRelease(FileNode, Main);
FspFileNodeDereference(FileNode);
}
return Result;
}
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose) const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose)
{ {
@ -1693,6 +1779,7 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
MainFileNode->LastAccessTime = FileInfo->LastAccessTime; MainFileNode->LastAccessTime = FileInfo->LastAccessTime;
MainFileNode->LastWriteTime = FileInfo->LastWriteTime; MainFileNode->LastWriteTime = FileInfo->LastWriteTime;
MainFileNode->ChangeTime = FileInfo->ChangeTime; MainFileNode->ChangeTime = FileInfo->ChangeTime;
MainFileNode->EaSize = FileInfo->EaSize;
if (0 != CcFileObject) if (0 != CcFileObject)
{ {
@ -1750,8 +1837,10 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
} }
} }
BOOLEAN FspFileNodeTrySetFileInfoOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, BOOLEAN FspFileNodeTrySetFileInfoAndSecurityOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose) const FSP_FSCTL_FILE_INFO *FileInfo,
const PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorSize,
BOOLEAN TruncateOnClose)
{ {
PAGED_CODE(); PAGED_CODE();
@ -1784,6 +1873,8 @@ BOOLEAN FspFileNodeTrySetFileInfoOnOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT Cc
} }
FspFileNodeSetFileInfo(FileNode, CcFileObject, FileInfo, TruncateOnClose); FspFileNodeSetFileInfo(FileNode, CcFileObject, FileInfo, TruncateOnClose);
if (0 != SecurityDescriptor)
FspFileNodeSetSecurity(FileNode, SecurityDescriptor, SecurityDescriptorSize);
return TRUE; return TRUE;
} }
@ -2034,6 +2125,48 @@ VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo); FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
} }
BOOLEAN FspFileNodeReferenceEa(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
{
PAGED_CODE();
if (0 != FileNode->MainFileNode)
FileNode = FileNode->MainFileNode;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
return FspMetaCacheReferenceItemBuffer(FsvolDeviceExtension->EaCache,
FileNode->Ea, PBuffer, PSize);
}
VOID FspFileNodeSetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size)
{
PAGED_CODE();
if (0 != FileNode->MainFileNode)
FileNode = FileNode->MainFileNode;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
FspMetaCacheInvalidateItem(FsvolDeviceExtension->EaCache, FileNode->Ea);
FileNode->Ea = 0 != Buffer ?
FspMetaCacheAddItem(FsvolDeviceExtension->EaCache, Buffer, Size) : 0;
FileNode->EaChangeNumber++;
}
BOOLEAN FspFileNodeTrySetEa(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
ULONG EaChangeNumber)
{
PAGED_CODE();
if (FspFileNodeEaChangeNumber(FileNode) != EaChangeNumber)
return FALSE;
FspFileNodeSetEa(FileNode, Buffer, Size);
return TRUE;
}
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action, VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
BOOLEAN InvalidateCaches) BOOLEAN InvalidateCaches)
{ {

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/fileinfo.c * @file sys/fileinfo.c
* *
* @copyright 2015-2018 Bill Zissimopoulos * @copyright 2015-2019 Bill Zissimopoulos
*/ */
/* /*
* This file is part of WinFsp. * This file is part of WinFsp.
@ -31,7 +31,8 @@ static NTSTATUS FspFsvolQueryBasicInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo); const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd); PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd); PVOID *PBuffer, PVOID BufferEnd);
static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject,
@ -81,6 +82,10 @@ FSP_IOCMPL_DISPATCH FspFsvolSetInformationComplete;
static FSP_IOP_REQUEST_FINI FspFsvolSetInformationRequestFini; static FSP_IOP_REQUEST_FINI FspFsvolSetInformationRequestFini;
FSP_DRIVER_DISPATCH FspQueryInformation; FSP_DRIVER_DISPATCH FspQueryInformation;
FSP_DRIVER_DISPATCH FspSetInformation; FSP_DRIVER_DISPATCH FspSetInformation;
FAST_IO_QUERY_BASIC_INFO FspFastIoQueryBasicInfo;
FAST_IO_QUERY_STANDARD_INFO FspFastIoQueryStandardInfo;
FAST_IO_QUERY_NETWORK_OPEN_INFO FspFastIoQueryNetworkOpenInfo;
FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvolQueryAllInformation) #pragma alloc_text(PAGE, FspFsvolQueryAllInformation)
@ -112,6 +117,10 @@ FSP_DRIVER_DISPATCH FspSetInformation;
#pragma alloc_text(PAGE, FspFsvolSetInformationRequestFini) #pragma alloc_text(PAGE, FspFsvolSetInformationRequestFini)
#pragma alloc_text(PAGE, FspQueryInformation) #pragma alloc_text(PAGE, FspQueryInformation)
#pragma alloc_text(PAGE, FspSetInformation) #pragma alloc_text(PAGE, FspSetInformation)
#pragma alloc_text(PAGE, FspFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, FspFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, FspFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, FspFastIoQueryOpen)
#endif #endif
enum enum
@ -167,7 +176,12 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
Info->InternalInformation.IndexNumber.QuadPart = FileNode->IndexNumber; Info->InternalInformation.IndexNumber.QuadPart = FileNode->IndexNumber;
Info->EaInformation.EaSize = 0; Info->EaInformation.EaSize =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
FileInfo->EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaInformation.EaSize)
Info->EaInformation.EaSize += 4;
Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset; Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset;
@ -228,20 +242,28 @@ static NTSTATUS FspFsvolQueryBasicInformation(PFILE_OBJECT FileObject,
} }
static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryEaInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd) PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo)
{ {
PAGED_CODE(); PAGED_CODE();
PFILE_EA_INFORMATION Info = (PFILE_EA_INFORMATION)*PBuffer; PFILE_EA_INFORMATION Info = (PFILE_EA_INFORMATION)*PBuffer;
if (0 == FileInfo)
{
if ((PVOID)(Info + 1) > BufferEnd) if ((PVOID)(Info + 1) > BufferEnd)
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
/* return STATUS_SUCCESS;
* No EA support currently. We must nevertheless respond to this query }
* or SRV2 gets unhappy. Just tell them that we have 0 EA's.
*/ FSP_FILE_NODE *FileNode = FileObject->FsContext;
Info->EaSize = 0; Info->EaSize =
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)->VolumeParams.ExtendedAttributes ?
FileInfo->EaSize : 0;
/* magic computations are courtesy of NTFS */
if (0 != Info->EaSize)
Info->EaSize += 4;
*PBuffer = (PVOID)(Info + 1); *PBuffer = (PVOID)(Info + 1);
@ -671,9 +693,8 @@ static NTSTATUS FspFsvolQueryInformation(
Result = STATUS_INVALID_PARAMETER; /* no compression support */ Result = STATUS_INVALID_PARAMETER; /* no compression support */
return Result; return Result;
case FileEaInformation: case FileEaInformation:
Result = FspFsvolQueryEaInformation(FileObject, &Buffer, BufferEnd); Result = FspFsvolQueryEaInformation(FileObject, &Buffer, BufferEnd, 0);
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer); break;
return Result;
case FileHardLinkInformation: case FileHardLinkInformation:
Result = STATUS_NOT_SUPPORTED; /* no hard link support */ Result = STATUS_NOT_SUPPORTED; /* no hard link support */
return Result; return Result;
@ -725,6 +746,9 @@ static NTSTATUS FspFsvolQueryInformation(
case FileBasicInformation: case FileBasicInformation:
Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
case FileEaInformation:
Result = FspFsvolQueryEaInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break;
case FileNetworkOpenInformation: case FileNetworkOpenInformation:
Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
@ -832,6 +856,9 @@ NTSTATUS FspFsvolQueryInformationComplete(
case FileBasicInformation: case FileBasicInformation:
Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
case FileEaInformation:
Result = FspFsvolQueryEaInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break;
case FileNetworkOpenInformation: case FileNetworkOpenInformation:
Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
@ -1760,3 +1787,163 @@ NTSTATUS FspSetInformation(
FileInformationClassSym(IrpSp->Parameters.SetFile.FileInformationClass), FileInformationClassSym(IrpSp->Parameters.SetFile.FileInformationClass),
IrpSp->FileObject); IrpSp->FileObject);
} }
BOOLEAN FspFastIoQueryBasicInfo(
PFILE_OBJECT FileObject, BOOLEAN CanWait, PFILE_BASIC_INFORMATION Info,
PIO_STATUS_BLOCK PIoStatus, PDEVICE_OBJECT DeviceObject)
{
FSP_ENTER_BOOL(PAGED_CODE());
#if DBG
if (!DEBUGTEST(50))
FSP_RETURN(Result = FALSE);
#endif
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_FILE_INFO FileInfoBuf;
if (!FspFileNodeIsValid(FileNode))
FSP_RETURN(Result = FALSE);
Result = FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
if (Result)
{
Result = FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf);
FspFileNodeRelease(FileNode, Main);
if (Result)
{
PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info;
NTSTATUS Result0 = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE);
PIoStatus->Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Info);
PIoStatus->Status = Result0;
}
}
FSP_LEAVE_BOOL("FileObject=%p", FileObject);
}
BOOLEAN FspFastIoQueryStandardInfo(
PFILE_OBJECT FileObject, BOOLEAN CanWait, PFILE_STANDARD_INFORMATION Info,
PIO_STATUS_BLOCK PIoStatus, PDEVICE_OBJECT DeviceObject)
{
FSP_ENTER_BOOL(PAGED_CODE());
#if DBG
if (!DEBUGTEST(50))
FSP_RETURN(Result = FALSE);
#endif
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_FILE_INFO FileInfoBuf;
if (!FspFileNodeIsValid(FileNode))
FSP_RETURN(Result = FALSE);
Result = FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
if (Result)
{
Result = FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf);
FspFileNodeRelease(FileNode, Main);
if (Result)
{
PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info;
NTSTATUS Result0 = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE);
PIoStatus->Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Info);
PIoStatus->Status = Result0;
}
}
FSP_LEAVE_BOOL("FileObject=%p", FileObject);
}
BOOLEAN FspFastIoQueryNetworkOpenInfo(
PFILE_OBJECT FileObject, BOOLEAN CanWait, PFILE_NETWORK_OPEN_INFORMATION Info,
PIO_STATUS_BLOCK PIoStatus, PDEVICE_OBJECT DeviceObject)
{
FSP_ENTER_BOOL(PAGED_CODE());
#if DBG
if (!DEBUGTEST(50))
FSP_RETURN(Result = FALSE);
#endif
FSP_FILE_NODE *FileNode = FileObject->FsContext;
FSP_FSCTL_FILE_INFO FileInfoBuf;
if (!FspFileNodeIsValid(FileNode))
FSP_RETURN(Result = FALSE);
Result = FspFileNodeTryAcquireSharedF(FileNode, FspFileNodeAcquireMain, CanWait);
if (Result)
{
Result = FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf);
FspFileNodeRelease(FileNode, Main);
if (Result)
{
PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info;
NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE);
PIoStatus->Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Info);
PIoStatus->Status = Result0;
}
}
FSP_LEAVE_BOOL("FileObject=%p", FileObject);
}
BOOLEAN FspFastIoQueryOpen(
PIRP Irp, PFILE_NETWORK_OPEN_INFORMATION Info, PDEVICE_OBJECT DeviceObject)
{
FSP_ENTER_BOOL(PAGED_CODE());
#if DBG
if (!DEBUGTEST(50))
FSP_RETURN(Result = FALSE);
#endif
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
FSP_FSCTL_FILE_INFO FileInfoBuf;
DeviceObject = IrpSp->DeviceObject;
if (FspFsvolDeviceExtensionKind != FspDeviceExtension(DeviceObject)->Kind)
FSP_RETURN(Result = FALSE);
/* do we allow kernel mode opens? */
if (!FspFsvolDeviceExtension(DeviceObject)->VolumeParams.AllowOpenInKernelMode)
FSP_RETURN(Result = FALSE);
/* is this a relative file open? */
if (0 != FileObject->RelatedFileObject)
FSP_RETURN(Result = FALSE);
Result = FspFileNodeTryGetFileInfoByName(DeviceObject, Irp, &FileObject->FileName, &FileInfoBuf);
if (Result)
{
PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info;
NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE);
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Info);
Irp->IoStatus.Status = Result0;
}
FSP_LEAVE_BOOL("FileObject=%p[%p:\"%wZ\"]",
IoGetCurrentIrpStackLocation(Irp)->FileObject,
IoGetCurrentIrpStackLocation(Irp)->FileObject->RelatedFileObject,
IoGetCurrentIrpStackLocation(Irp)->FileObject->FileName);
}

View File

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

View File

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

View File

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

View File

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

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