Compare commits

..

97 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
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
d2f6ceaf28 Merge branch 'release/1.4' 2018-12-10 09:36:03 -08:00
ab6e07853c Merge branch 'release/1.4' 2018-12-08 13:56:50 -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
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
74df26a28d Merge branch 'release/1.4' 2018-10-09 14:32:42 -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
163 changed files with 4582 additions and 352 deletions

View File

@ -1,7 +1,17 @@
= Changelog = Changelog
v1.4 (2019.2):: 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: 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,10 +16,10 @@
<MyCompanyName>Navimatics Corporation</MyCompanyName> <MyCompanyName>Navimatics Corporation</MyCompanyName>
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright> <MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
<MyCanonicalVersion>1.4</MyCanonicalVersion> <MyCanonicalVersion>1.5</MyCanonicalVersion>
<MyProductVersion>2019.2</MyProductVersion> <MyProductVersion>2019.3 B1</MyProductVersion>
<MyProductStage>Gold</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas> <MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>

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

@ -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.

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.

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

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;
Result = FileSystem->Interface->Create(FileSystem, if (0 != FileSystem->Interface->CreateEx)
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, Result = FileSystem->Interface->CreateEx(FileSystem,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor); 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,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
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,13 +583,24 @@ 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;
Result = FileSystem->Interface->Create(FileSystem, if (0 != FileSystem->Interface->CreateEx)
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, Result = FileSystem->Interface->CreateEx(FileSystem,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor); 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,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, OpenDescriptor, Request->Req.Create.AllocationSize,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
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,10 +717,19 @@ 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;
Result = FileSystem->Interface->Create(FileSystem, if (0 != FileSystem->Interface->CreateEx)
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess, Result = FileSystem->Interface->CreateEx(FileSystem,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize, (PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); 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,
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor); FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -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,16 +937,27 @@ 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);
Result = FileSystem->Interface->Overwrite(FileSystem, if (0 != FileSystem->Interface->OverwriteEx)
(PVOID)ValOfFileContext(Request->Req.Overwrite), Result = FileSystem->Interface->OverwriteEx(FileSystem,
Request->Req.Overwrite.FileAttributes, (PVOID)ValOfFileContext(Request->Req.Overwrite),
Request->Req.Overwrite.Supersede, Request->Req.Overwrite.FileAttributes,
Request->Req.Overwrite.AllocationSize, Request->Req.Overwrite.Supersede,
&FileInfo); 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,
(PVOID)ValOfFileContext(Request->Req.Overwrite),
Request->Req.Overwrite.FileAttributes,
Request->Req.Overwrite.Supersede,
Request->Req.Overwrite.AllocationSize,
&FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
if (0 != FileSystem->Interface->Close) if (0 != FileSystem->Interface->Close)
@ -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);
@ -2173,14 +2221,113 @@ static NTSTATUS fsp_fuse_intf_Control(FSP_FILE_SYSTEM *FileSystem,
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,
@ -2201,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.

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.

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.
@ -92,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.

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.

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.

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.
@ -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>
@ -1343,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)
{ {
@ -1073,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.

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.

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,9 +302,23 @@ 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)
return STATUS_EAS_NOT_SUPPORTED; {
/* does the file system support EA? */
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
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))
@ -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.

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;

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();
return STATUS_INVALID_DEVICE_REQUEST; 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;
/* 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();
}
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
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 NTSTATUS FspFsvolSetEa( static VOID FspFsvolQueryEaRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[4])
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
PAGED_CODE(); PAGED_CODE();
return STATUS_INVALID_DEVICE_REQUEST; 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;
/* 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 ((PVOID)(Info + 1) > BufferEnd) if (0 == FileInfo)
return STATUS_BUFFER_TOO_SMALL; {
if ((PVOID)(Info + 1) > BufferEnd)
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.

View File

@ -1,7 +1,7 @@
/** /**
* @file sys/lockctl.c * @file sys/lockctl.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