Compare commits
329 Commits
Author | SHA1 | Date | |
---|---|---|---|
6f22828060 | |||
7c2de68892 | |||
4656e8ed26 | |||
be98326bbb | |||
52acc3bc48 | |||
f68bc75255 | |||
029942bbac | |||
cb0c7def54 | |||
5fbd75926b | |||
bc9bcefc62 | |||
a57325e8af | |||
466922787d | |||
9dc8aca710 | |||
88aeb83211 | |||
a7cee1eafe | |||
eb0816db56 | |||
51833751d0 | |||
155344ea61 | |||
3874e2a6b5 | |||
c5740029f7 | |||
9973c4c963 | |||
6cfda75447 | |||
c7d6fc355b | |||
b062f8683c | |||
cec5f0be08 | |||
40b61f7667 | |||
7c383654bd | |||
9e4e7d4bcf | |||
638e5a20b6 | |||
95bbb584eb | |||
1d8241cba7 | |||
460726df83 | |||
b5cefc59e9 | |||
e9ca1a8996 | |||
8c0f609a93 | |||
23eabe5939 | |||
eecca688bc | |||
23d2083d8f | |||
8d379a4c8b | |||
830985d331 | |||
6b37e2ef12 | |||
62dbaf56e3 | |||
d301164609 | |||
ada3e1b0e5 | |||
13d6ec3638 | |||
2210561b65 | |||
1713ce9c9e | |||
8f25dd6cab | |||
c9485ff214 | |||
5ce1a722b3 | |||
27315c1111 | |||
bd38a39dbd | |||
766734a8e3 | |||
b242a449b8 | |||
c6a6fdfc36 | |||
843d3f0362 | |||
5190923c9a | |||
2f8ac3765d | |||
e4b4e6a1f9 | |||
fa54898c64 | |||
2f82d91e1f | |||
7574c39ffb | |||
bdc02c8ab5 | |||
15c16d7070 | |||
ba312de59b | |||
5824a24bf4 | |||
f0a0787f6b | |||
c17b84cff2 | |||
168acb1a1f | |||
c8206751d2 | |||
bec91873fe | |||
9bf0d5d46d | |||
2d85c7bf73 | |||
ff3436718c | |||
69f6f661ba | |||
6e52def53c | |||
2212d021e1 | |||
7b94f2bebf | |||
c897ddd864 | |||
8d6314e2db | |||
eec63332e0 | |||
04186ea834 | |||
3adcf70748 | |||
33e8b5df04 | |||
154933ecab | |||
c760cf9563 | |||
245bba0a17 | |||
3008575bdf | |||
2ce434efbd | |||
94ea4f65f7 | |||
c780912810 | |||
299605b8fc | |||
86bccd763c | |||
856d3bdefe | |||
104c830437 | |||
f35a93d1f7 | |||
2d9b1b80fa | |||
f1ee19d8dc | |||
671c0c12ab | |||
6eb2879374 | |||
1e03c1a465 | |||
b55c20b393 | |||
406af6901f | |||
40735c4687 | |||
08c283f2a9 | |||
4fc740588e | |||
54050c7e1d | |||
ff08d63a82 | |||
c37444b0ae | |||
bbb51b4971 | |||
6de998ff98 | |||
4b024ebe74 | |||
418c454a4a | |||
0b61c48cd6 | |||
945509ef93 | |||
3a65ce332b | |||
228f9e2708 | |||
ee3918436b | |||
1bb6d2a0e7 | |||
6d1b9e95db | |||
1d8d72129d | |||
2ad4e30754 | |||
26cba02091 | |||
3697defd16 | |||
69a22f1044 | |||
5a49115a66 | |||
82c8b0d00f | |||
d00b5d88af | |||
6d19176d7c | |||
e231b9c662 | |||
025a74e663 | |||
834adbdc36 | |||
25c687d5c5 | |||
200de2a7f9 | |||
8e7c241f32 | |||
e530e671a5 | |||
d804f5674d | |||
ac6f024715 | |||
a1af8ff921 | |||
f7ca9f0522 | |||
3518d7a8c2 | |||
281d92f2bc | |||
7769a2c062 | |||
595a77bd2e | |||
6860a6986a | |||
63e8cf1090 | |||
7bdca634aa | |||
535babc0d5 | |||
e86dcde1a1 | |||
6e10e0489b | |||
f82cad712a | |||
d12234bb01 | |||
10a8519294 | |||
1b6395fc91 | |||
f1a363b848 | |||
eea1a8fd8b | |||
5444ce7f50 | |||
29c140b9cd | |||
cdfd60877b | |||
e7931e28fd | |||
002a0262f7 | |||
1ffba78a18 | |||
1d3423d5fb | |||
a894e4a2af | |||
b6f084d71f | |||
ca6d0d2dcf | |||
d6d781355f | |||
851a6145cd | |||
aec7b34e13 | |||
38006ba553 | |||
ee469b40e7 | |||
1f385a9ab5 | |||
ba78fbb956 | |||
8f10ba4fc9 | |||
b0a59e42fc | |||
2e089b92c5 | |||
37362cb8cc | |||
127d4cc4eb | |||
ce551d4e0d | |||
53f60a698a | |||
aa23672b01 | |||
e4de0f0513 | |||
8750451e10 | |||
358db2a54f | |||
4294182c1a | |||
f17168f2fa | |||
959d8537c6 | |||
6a48087d5f | |||
0a59c5d685 | |||
5b1b8288c2 | |||
53e2f13e38 | |||
cb6b10385b | |||
f49cf412a8 | |||
764b772731 | |||
7518a6e418 | |||
2772af5478 | |||
f2535484ea | |||
97ee4fa77f | |||
7c34d738b7 | |||
93254bede4 | |||
f3894dbc7b | |||
dc684acd41 | |||
69935525da | |||
6ba6e16851 | |||
d33089331b | |||
74de84aaab | |||
a9b4fd4634 | |||
c6798b3060 | |||
f6e3b8e416 | |||
f05ebd9d20 | |||
e50c9ff649 | |||
fb70eccc9c | |||
7adbd7a56c | |||
55c7384c65 | |||
bc8962d2b6 | |||
2267eadbca | |||
154aa28381 | |||
2d98cda607 | |||
8395b22ddc | |||
809505d8a3 | |||
9df0920de1 | |||
c10c7cc672 | |||
a0cb134bd3 | |||
becfd2e1c5 | |||
1e93f0d10d | |||
adeb847c7e | |||
5a83c68f56 | |||
9d176643c3 | |||
b1d8192d59 | |||
bd3d462bce | |||
aa2d70d8de | |||
31c40d017d | |||
5c8da5518c | |||
a80a9d3d4c | |||
57580e91f5 | |||
1a43619c5e | |||
aae6a15e5a | |||
f54ce6a65d | |||
ab0c2fc25c | |||
fd439add27 | |||
8855a2b896 | |||
7c41ffd64e | |||
621eb63029 | |||
f1b96f8a28 | |||
4512dac0a9 | |||
deee32b743 | |||
5f1b723fab | |||
453f1732dc | |||
8c8d669be8 | |||
53077d990a | |||
c665812d76 | |||
b56379b542 | |||
83c1489b92 | |||
3e3aa7651f | |||
ec2cf5106d | |||
25322059b3 | |||
a255fa11e7 | |||
dbb8b5d3b9 | |||
4c6a61d2c9 | |||
ac4828ec11 | |||
e0f163e9ba | |||
9bcd8dcb8e | |||
096e5b7eb1 | |||
1c85fb94f0 | |||
4417ebcc92 | |||
5fa631339d | |||
26092211a8 | |||
50af8f6444 | |||
ee0031f995 | |||
75ff7f2c01 | |||
3e557e1b65 | |||
79bf651203 | |||
205a59dbc6 | |||
8f54152096 | |||
5e71992153 | |||
dfe45e1be5 | |||
ff7a446194 | |||
17056b4f3f | |||
b19621233a | |||
e07ef0712e | |||
0532cee99c | |||
b072a1f0da | |||
badaf82462 | |||
3f79b2e46d | |||
319e5d4ee6 | |||
66d5fe98df | |||
8abadf94f3 | |||
728c1b3402 | |||
8b31b1018b | |||
310fd23035 | |||
7f2426271c | |||
3cfa4156d2 | |||
23dadcf8a0 | |||
e0b0b1b367 | |||
a525e095d3 | |||
e16dfd8a43 | |||
3bf4140f91 | |||
b194a33406 | |||
0dd452fac1 | |||
df11a7d7ff | |||
51d29c172a | |||
2803a1b0cf | |||
067a0f1b37 | |||
03611b6210 | |||
2ff60e5e98 | |||
488993d22b | |||
3cba22b9a5 | |||
a3e577b091 | |||
9b287fb559 | |||
f642ea57be | |||
cb17b7e2e0 | |||
82a9c8e80f | |||
628dae38d7 | |||
958b5a47a8 | |||
8d38a0dac6 | |||
a653a010ce | |||
31eedbddb3 | |||
5bf913045e | |||
a10a09d4e9 | |||
3e0db6da07 | |||
77df532ac3 | |||
222da362ec | |||
3ed7847d84 | |||
5773c6eab7 | |||
5a5a1008de | |||
32c289fa34 | |||
0534225662 | |||
096b2dabde | |||
5770f2d901 |
@ -1,6 +1,22 @@
|
||||
= Changelog
|
||||
|
||||
|
||||
v1.0RC1::
|
||||
|
||||
This is the WinFsp 2017 Release Candidate 1. It has been tested extensively in a variety of scenarios for stability and correct file system semantics. Some of the more important changes:
|
||||
|
||||
- API has been polished and finalized.
|
||||
- Extensively tested against multiple test suites including Microsoft's IfsTest.
|
||||
- WinFsp I/O Queues (the fundamental WinFsp IPC mechanism) have been improved to work similar to I/O Completion Ports.
|
||||
- Opportunistic locks have been implemented.
|
||||
- File system statistics have been implemented.
|
||||
- Sharing a (disk) file system over the network is supported.
|
||||
- Case insensitive file systems are supported.
|
||||
- Directories are supported as mount points.
|
||||
- Access checks are performed correctly in the absense of the traverse privilege.
|
||||
- Access checks are performed correctly in the presence of the backup and restore privileges.
|
||||
|
||||
|
||||
v0.17::
|
||||
|
||||
This release brings support for named streams.
|
21
README.md
@ -4,15 +4,15 @@
|
||||
|
||||
WinFsp is a set of software components for Windows computers that allows the creation of user mode file systems. In this sense it is similar to FUSE (Filesystem in Userspace), which provides the same functionality on UNIX-like computers.
|
||||
|
||||
Some of the benefits and features of using WinFsp are listed below:
|
||||
Some of the benefits of using WinFsp are listed below:
|
||||
|
||||
* Allows for easy development of file systems in user mode. There are no restrictions on what a process can do in order to implement a file system (other than respond in a timely manner to file system requests).
|
||||
* Support for disk and network based file systems.
|
||||
* Support for NTFS level security and access control.
|
||||
* Support for memory mapped files, cached files and the NT cache manager.
|
||||
* Support for file change notifications.
|
||||
* Support for file locking.
|
||||
* Correct NT semantics with respect to file sharing, file deletion and renaming.
|
||||
* Very well-tested and stable. Read about its [Testing Strategy](doc/WinFsp-Testing.asciidoc).
|
||||
* Very fast. Read about its [Performance](doc/WinFsp-Performance-Testing.asciidoc).
|
||||
* Strives for compatibility with NTFS. Read about its [Compatibility](doc/NTFS-Compatibility.asciidoc ).
|
||||
* Easy to understand but comprehensive API. Consult the [API Reference](http://www.secfs.net/winfsp/apiref/).
|
||||
* FUSE compatibility layer for native Windows and Cygwin. See [fuse.h](inc/fuse/fuse.h).
|
||||
* Signed drivers provided on every release.
|
||||
* Available under the GPLv3.
|
||||
|
||||
To learn more about WinFsp, please visit its website: http://www.secfs.net/winfsp/
|
||||
|
||||
@ -23,7 +23,7 @@ WinFsp consists of a kernel mode FSD (File System Driver) and a user mode DLL (D
|
||||
The project source code is organized as follows:
|
||||
|
||||
* build/VStudio: WinFsp solution and project files.
|
||||
* doc: WinFsp license, contributor agreement and additional documentation. The WinFsp design documents can be found here.
|
||||
* doc: The WinFsp design documents and additional documentation can be found here.
|
||||
* ext/tlib: A small test library originally from the secfs (Secure Cloud File System) project.
|
||||
* ext/test: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
|
||||
* inc/winfsp: Public headers for the WinFsp API.
|
||||
@ -53,6 +53,7 @@ WinFsp is designed to run on Vista and above. It has been tested on the followin
|
||||
* Windows 8 Pro
|
||||
* Windows 10 Pro
|
||||
* Windows Server 2012
|
||||
* Windows Server 2016
|
||||
|
||||
## How to Help
|
||||
|
||||
@ -60,7 +61,7 @@ I am looking for help in the following areas:
|
||||
|
||||
* If you have a file system that runs on FUSE please consider porting it to WinFsp. WinFsp has a native API, but it also has a FUSE (high-level) API.
|
||||
* If you are working with a language other than C/C++ (e.g. Delphi, C#, etc.) and you are interested in porting/wrapping WinFsp I would love to hear from you.
|
||||
* There are a number of outstanding issues listed in the [GitHub repository](https://github.com/billziss-gh/winfsp/issues) ~~[BitBucket repository](https://bitbucket.org/billziss/winfsp/issues?status=new&status=open)~~. Many of these require knowledge of Windows kernel-mode and an understanding of the internals of WinFsp so they are not for the faint of heart. If you decide to tackle any of those please coordinate with me as I am actively working on that issue list.
|
||||
* There are a number of outstanding issues listed in the [GitHub repository](https://github.com/billziss-gh/winfsp/issues). Many of these require knowledge of Windows kernel-mode and an understanding of the internals of WinFsp so they are not for the faint of heart.
|
||||
|
||||
In all cases I can provide ideas and/or support.
|
||||
|
||||
|
60
appveyor.yml
@ -1,23 +1,37 @@
|
||||
version: '{build}'
|
||||
|
||||
environment:
|
||||
CONFIGURATION: Release
|
||||
|
||||
install:
|
||||
- git submodule update --init --recursive
|
||||
- appveyor AddMessage "Change boot configuration and reboot" -Category Information
|
||||
- verifier /standard /driver winfsp-x64.sys
|
||||
- bcdedit /set testsigning on
|
||||
- ps: Restart-Computer -Force
|
||||
- ps: Start-Sleep -s 10
|
||||
|
||||
build_script:
|
||||
- appveyor AddMessage "Reboot complete" -Category Information
|
||||
- bcdedit | findstr /i "testsigning"
|
||||
- tools\build.bat %CONFIGURATION%
|
||||
|
||||
test_script:
|
||||
- for %%f in ("build\VStudio\build\%CONFIGURATION%\winfsp-*.msi") do start /wait msiexec /i %%f /qn INSTALLLEVEL=1000
|
||||
- tools\nmake-ext-test.bat %CONFIGURATION%
|
||||
- tools\run-tests.bat %CONFIGURATION%
|
||||
- verifier /query
|
||||
version: '{build}'
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- CONFIGURATION: Debug
|
||||
TESTING: Func
|
||||
- CONFIGURATION: Release
|
||||
TESTING: Func
|
||||
- CONFIGURATION: Release
|
||||
TESTING: Perf
|
||||
|
||||
install:
|
||||
- git submodule update --init --recursive
|
||||
- appveyor AddMessage "Change boot configuration and reboot" -Category Information
|
||||
- bcdedit /set testsigning on
|
||||
- if %TESTING%==Func verifier /standard /driver winfsp-x64.sys
|
||||
- if exist %SystemRoot%\memory.dmp del %SystemRoot%\memory.dmp
|
||||
- ps: Restart-Computer -Force
|
||||
- ps: Start-Sleep -s 60
|
||||
|
||||
build_script:
|
||||
- appveyor AddMessage "Reboot complete" -Category Information
|
||||
- tools\build.bat %CONFIGURATION%
|
||||
|
||||
test_script:
|
||||
- for %%f in ("build\VStudio\build\%CONFIGURATION%\winfsp-*.msi") do start /wait msiexec /i %%f /qn INSTALLLEVEL=1000
|
||||
- if %TESTING%==Func appveyor DownloadFile http://www.secfs.net/winfsp/resources/Test.Filter.Driver.zip && 7z x Test.Filter.Driver.zip
|
||||
- if %TESTING%==Func start /wait msiexec /i "Test.Filter.Driver\HCK Filter.Driver Content-x86_en-us.msi" /qn
|
||||
- if %TESTING%==Func tools\nmake-ext-test.bat %CONFIGURATION%
|
||||
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION%
|
||||
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% ifstest
|
||||
- if %TESTING%==Perf tools\run-perf-tests.bat %CONFIGURATION% baseline > perf-tests.csv && type perf-tests.csv & appveyor PushArtifact perf-tests.csv
|
||||
- if exist %SystemRoot%\memory.dmp exit 1
|
||||
|
||||
on_finish:
|
||||
- if exist %SystemRoot%\memory.dmp (7z a memory.dmp.zip %SystemRoot%\memory.dmp && appveyor PushArtifact memory.dmp.zip)
|
||||
- verifier /query
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file CustomActions.cpp
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -2,7 +2,7 @@
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product
|
||||
Id="*"
|
||||
Name="$(var.MyProductName)"
|
||||
Name="$(var.MyProductName) $(var.MyProductVersion)"
|
||||
Manufacturer="$(var.MyCompanyName)"
|
||||
Version="$(var.MyVersion)"
|
||||
Language="1033"
|
||||
@ -17,8 +17,8 @@
|
||||
Disallow="yes"
|
||||
AllowDowngrades="no"
|
||||
AllowSameVersionUpgrades="no"
|
||||
DisallowUpgradeErrorMessage="An older version of [ProductName] is already installed. You must uninstall it before you can install this version."
|
||||
DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
DisallowUpgradeErrorMessage="An older version of $(var.MyProductName) is already installed. You must uninstall it before you can install this version."
|
||||
DowngradeErrorMessage="A newer version of $(var.MyProductName) is already installed." />
|
||||
<Media Id="1" Cabinet="WinFsp.cab" EmbedCab="yes" />
|
||||
|
||||
<Property Id="P.LauncherName">$(var.MyProductName).Launcher</Property>
|
||||
@ -155,7 +155,7 @@
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="CommandLine"
|
||||
Value="-u %1 -m %2" />
|
||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="Security"
|
||||
@ -181,7 +181,7 @@
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="CommandLine"
|
||||
Value="-u %1 -m %2" />
|
||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="Security"
|
||||
@ -344,7 +344,7 @@
|
||||
<Feature
|
||||
Id="F.Main"
|
||||
Level="1"
|
||||
Title="$(var.MyProductName) $(var.MyVersion)"
|
||||
Title="$(var.MyProductName) $(var.MyProductVersion)"
|
||||
Description="$(var.MyDescription)"
|
||||
Display="expand"
|
||||
ConfigurableDirectory="INSTALLDIR"
|
||||
@ -378,7 +378,7 @@
|
||||
</Feature>
|
||||
|
||||
<WixVariable Id="WixUIBannerBmp" Value="wixbanner.bmp" />
|
||||
<WixVariable Id="WixUIDialogBmp" Value="wixdialog-$(var.MyDevStage).bmp" />
|
||||
<WixVariable Id="WixUIDialogBmp" Value="wixdialog-$(var.MyProductStage).bmp" />
|
||||
<UI Id="FeatureTree">
|
||||
<UIRef Id="WixUI_FeatureTree" />
|
||||
<!-- skip the license agreement dialog; higher Order takes priority (weird) -->
|
||||
|
@ -16,7 +16,7 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug;MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyDevStage=$(MyDevStage);MyVersion=$(MyVersion)</DefineConstants>
|
||||
<DefineConstants>Debug;MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
|
||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||
<Pedantic>True</Pedantic>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
@ -25,7 +25,7 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
||||
<DefineConstants>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyDevStage=$(MyDevStage);MyVersion=$(MyVersion)</DefineConstants>
|
||||
<DefineConstants>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
|
||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||
<Pedantic>True</Pedantic>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
|
@ -193,10 +193,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\..\src\launcher\launchctl-version.rc">
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -202,10 +202,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\..\src\launcher\launcher-version.rc">
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
187
build/VStudio/testing/fsbench.vcxproj
Normal file
@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>fsbench</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\ext</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\ext\tlib\testsuite.c">
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</SDLCheck>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</SDLCheck>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</SDLCheck>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
<SDLCheck Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</SDLCheck>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\fsbench\fsbench.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
25
build/VStudio/testing/fsbench.vcxproj.filters
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source\tlib">
|
||||
<UniqueIdentifier>{d76fc01e-0f8d-4596-bdef-c2a5d3fede2e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\tst\fsbench\fsbench.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\ext\tlib\testsuite.c">
|
||||
<Filter>Source\tlib</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
||||
<Filter>Source\tlib</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
185
build/VStudio/testing/fscrash.vcxproj
Normal file
@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{10757011-749D-4954-873B-AE38D8145472}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>fscrash</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\tst\memfs;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\tst\memfs;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\tst\memfs;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\tst\memfs;..\..\..\inc</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\tst\fscrash\fscrash-main.c" />
|
||||
<ClCompile Include="..\..\..\tst\fscrash\fscrash.c" />
|
||||
<ClCompile Include="..\..\..\tst\memfs\memfs.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\tst\fscrash\fscrash.h" />
|
||||
<ClInclude Include="..\..\..\tst\memfs\memfs.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\winfsp_dll.vcxproj">
|
||||
<Project>{4a7c0b21-9e10-4c81-92de-1493efcf24eb}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
28
build/VStudio/testing/fscrash.vcxproj.filters
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\tst\fscrash\fscrash-main.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\memfs\memfs.cpp">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\fscrash\fscrash.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\tst\memfs\memfs.h">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\tst\fscrash\fscrash.h">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -107,7 +107,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -124,7 +124,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@ -145,7 +145,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -166,7 +166,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -186,15 +186,17 @@
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\eventlog-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\flush-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\fuse-opt-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\hook.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\lock-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\memfs-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\oplock-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\path-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\posix-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\rdwr-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\reparse-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\resilient.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
||||
|
@ -64,10 +64,16 @@
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\reparse-test.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\hook.c">
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c">
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\resilient.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\tst\winfsp-tests\oplock-test.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
@ -1,19 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<!-- build number: concat 2-digit year with 3-digit day of the year (16-bits until 2066) -->
|
||||
<MyBuildNumber>$([System.DateTime]::Now.ToString(`yy`))$([System.DateTime]::Now.DayOfYear.ToString(`000`))</MyBuildNumber>
|
||||
|
||||
<!-- git revision -->
|
||||
<MyGitRoot>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), .git/HEAD))</MyGitRoot>
|
||||
<MyGitHead>$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/HEAD).Trim())</MyGitHead>
|
||||
<MyGitRevision Condition="$(MyGitHead.StartsWith(ref: ))">$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/$(MyGitHead.Substring(5))).Trim().Substring(0, 7))</MyGitRevision>
|
||||
<MyGitRevision Condition="!$(MyGitHead.StartsWith(ref: ))">$(MyGitHead.Substring(0, 7))</MyGitRevision>
|
||||
|
||||
<MyProductName>WinFsp</MyProductName>
|
||||
<MyDescription>Windows File System Proxy</MyDescription>
|
||||
<MyCompanyName>Navimatics Corporation</MyCompanyName>
|
||||
<MyCopyright>2015-2016 Bill Zissimopoulos</MyCopyright>
|
||||
<MyDevStage>Beta</MyDevStage>
|
||||
<!-- build number: concat 2-digit year with 3-digit day of the year (16-bits until 2066) -->
|
||||
<MyBuildNumber>$([System.DateTime]::Now.ToString(`yy`))$([System.DateTime]::Now.DayOfYear.ToString(`000`))</MyBuildNumber>
|
||||
<MyVersion>0.17.$(MyBuildNumber)</MyVersion>
|
||||
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
|
||||
|
||||
<MyCanonicalVersion>1.0</MyCanonicalVersion>
|
||||
|
||||
<MyProductVersion>2017 RC1</MyProductVersion>
|
||||
<MyProductStage>RC</MyProductStage>
|
||||
|
||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
||||
<MyFullVersion>$(MyCanonicalVersion).$(MyBuildNumber).$(MyGitRevision)</MyFullVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>NTDDI_VERSION=0x06000000;_WIN32_WINNT=0x0600</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25123.0
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winfsp.dll", "winfsp_dll.vcxproj", "{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
@ -45,6 +45,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launchctl", "launcher\launc
|
||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35} = {A5EFD487-0140-4184-8C54-FFAEC2F85E35}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fscrash", "testing\fscrash.vcxproj", "{10757011-749D-4954-873B-AE38D8145472}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB} = {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}
|
||||
{C85C26BA-8C22-4D30-83DA-46C3548E6332} = {C85C26BA-8C22-4D30-83DA-46C3548E6332}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsbench", "testing\fsbench.vcxproj", "{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@ -153,6 +161,38 @@ Global
|
||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x64.Build.0 = Release|x64
|
||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x86.Build.0 = Release|Win32
|
||||
{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|x86.ActiveCfg = Debug|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Debug|x86.Build.0 = Debug|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x64.Build.0 = Debug|x64
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Debug|x86.Build.0 = Debug|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x64.ActiveCfg = Release|x64
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x64.Build.0 = Release|x64
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x86.ActiveCfg = Release|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Installer.Release|x86.Build.0 = Release|Win32
|
||||
{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|x86.ActiveCfg = Release|Win32
|
||||
{10757011-749D-4954-873B-AE38D8145472}.Release|x86.Build.0 = Release|Win32
|
||||
{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|x86.ActiveCfg = Debug|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Debug|x86.Build.0 = Debug|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x64.Build.0 = Debug|x64
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Debug|x86.Build.0 = Debug|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x64.ActiveCfg = Release|x64
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x64.Build.0 = Release|x64
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x86.ActiveCfg = Release|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Installer.Release|x86.Build.0 = Release|Win32
|
||||
{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|x86.ActiveCfg = Release|Win32
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -164,5 +204,7 @@ Global
|
||||
{95C223E6-B5F1-4FD0-9376-41CDBC824445} = {B464EF06-42AE-4674-81BB-FDDE80204822}
|
||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35} = {FD28A504-431E-49B9-BB8C-DCA0E7019F66}
|
||||
{73EAAEDA-557B-48D5-A137-328934720FB4} = {FD28A504-431E-49B9-BB8C-DCA0E7019F66}
|
||||
{10757011-749D-4954-873B-AE38D8145472} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -78,10 +78,10 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\src\dll\eventlog\eventlog.rc" />
|
||||
<ResourceCompile Include="..\..\src\dll\version.rc">
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
@ -173,9 +173,11 @@
|
||||
<ClCompile Include="..\..\src\sys\ioq.c" />
|
||||
<ClCompile Include="..\..\src\sys\lockctl.c" />
|
||||
<ClCompile Include="..\..\src\sys\meta.c" />
|
||||
<ClCompile Include="..\..\src\sys\name.c" />
|
||||
<ClCompile Include="..\..\src\sys\read.c" />
|
||||
<ClCompile Include="..\..\src\sys\security.c" />
|
||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||
<ClCompile Include="..\..\src\sys\statistics.c" />
|
||||
<ClCompile Include="..\..\src\sys\util.c" />
|
||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||
<ClCompile Include="..\..\src\sys\volume.c" />
|
||||
@ -188,12 +190,77 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\src\sys\version.rc">
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\src\sys\driver.inf.in">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set DriverFile=$(TargetFileName)
|
||||
set Provider="$(MyCompanyName)"
|
||||
set CatalogFile=driver-$(PlatformTarget).cat
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
if exist $(OutDir)driver-$(PlatformTarget).inf del $(OutDir)driver-$(PlatformTarget).inf
|
||||
for /f "delims=" %%l in (%(FullPath)) do (
|
||||
set line=%%l
|
||||
echo !line! >>$(OutDir)driver-$(PlatformTarget).inf
|
||||
)
|
||||
|
||||
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName)
|
||||
set Provider="$(MyCompanyName)"
|
||||
set CatalogFile=driver-$(PlatformTarget).cat
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
if exist $(OutDir)driver-$(PlatformTarget).inf del $(OutDir)driver-$(PlatformTarget).inf
|
||||
for /f "delims=" %%l in (%(FullPath)) do (
|
||||
set line=%%l
|
||||
echo !line! >>$(OutDir)driver-$(PlatformTarget).inf
|
||||
)
|
||||
|
||||
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName)
|
||||
set Provider="$(MyCompanyName)"
|
||||
set CatalogFile=driver-$(PlatformTarget).cat
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
if exist $(OutDir)driver-$(PlatformTarget).inf del $(OutDir)driver-$(PlatformTarget).inf
|
||||
for /f "delims=" %%l in (%(FullPath)) do (
|
||||
set line=%%l
|
||||
echo !line! >>$(OutDir)driver-$(PlatformTarget).inf
|
||||
)
|
||||
|
||||
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName)
|
||||
set Provider="$(MyCompanyName)"
|
||||
set CatalogFile=driver-$(PlatformTarget).cat
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
if exist $(OutDir)driver-$(PlatformTarget).inf del $(OutDir)driver-$(PlatformTarget).inf
|
||||
for /f "delims=" %%l in (%(FullPath)) do (
|
||||
set line=%%l
|
||||
echo !line! >>$(OutDir)driver-$(PlatformTarget).inf
|
||||
)
|
||||
|
||||
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
|
||||
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing driver-$(PlatformTarget).inf</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Writing driver-$(PlatformTarget).inf</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Writing driver-$(PlatformTarget).inf</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Writing driver-$(PlatformTarget).inf</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -92,6 +92,12 @@
|
||||
<ClCompile Include="..\..\src\sys\callbacks.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\name.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\statistics.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\sys\driver.h">
|
||||
@ -106,4 +112,9 @@
|
||||
<Filter>Source</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\src\sys\driver.inf.in">
|
||||
<Filter>Source</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
21
doc/Makefile
@ -1,21 +0,0 @@
|
||||
web: \
|
||||
web/winfsp-design.html \
|
||||
web/service-architecture.html \
|
||||
web/sshfs-port-case-study.html \
|
||||
web/winfsp.h.html
|
||||
|
||||
web/winfsp-design.html:
|
||||
mkdir -p web
|
||||
asciidoc -b html4 -a hr= -s -o $@ winfsp-design.adoc
|
||||
|
||||
web/service-architecture.html:
|
||||
mkdir -p web
|
||||
asciidoc -b html4 -a hr= -s -o $@ service-architecture.adoc
|
||||
|
||||
web/sshfs-port-case-study.html:
|
||||
mkdir -p web
|
||||
asciidoc -b html4 -a hr= -s -o $@ sshfs-port-case-study.adoc
|
||||
|
||||
web/winfsp.h.html:
|
||||
mkdir -p web
|
||||
prettydoc -H-O -o web ../inc/winfsp/winfsp.h
|
46
doc/NTFS-Compatibility.asciidoc
Normal file
@ -0,0 +1,46 @@
|
||||
= NTFS Compatibility
|
||||
|
||||
WinFsp enables the creation of user mode file systems that behave similar to NTFS or FAT. Generic Windows applications that access files on a WinFsp file system cannot and should not be able to determine that it is not a native Windows file system. However specialized applications that access NTFS or FAT specific extensions (such as Defrag) will not work properly on WinFsp file systems.
|
||||
|
||||
== Supported features
|
||||
|
||||
WinFsp supports the following NTFS features:
|
||||
|
||||
- Query and set volume information.
|
||||
- Open, create, close, delete files and directories.
|
||||
- Query and set file and directory information.
|
||||
- Query and set security information (ACL's).
|
||||
- Read and write files.
|
||||
- Memory mapped I/O.
|
||||
- Directory change notifications.
|
||||
- Lock and unlock files.
|
||||
- Opportunistic locks.
|
||||
- Open, create, close, delete, query named streams.
|
||||
- Reparse points with special support for symbolic links.
|
||||
|
||||
== Unsupported features
|
||||
|
||||
WinFsp does not support the following NTFS features:
|
||||
|
||||
- Hard links. Rather rarely used on Windows. However it might be worthwhile to implement them for WinFsp.
|
||||
- Extended attributes. Although popular with POSIX file systems, they are severely hampered and rarely used on Windows. They are also not exposed via the Win32 API.
|
||||
- Short file names. Short file names are a relic of the past. WinFsp made a conscious decision not to support them.
|
||||
- Paging files. Providing paging file support via a user mode file system is impossible for a number of reasons.
|
||||
- Object ID's. Opening files by ID (+FILE_OPEN_BY_FILE_ID+) is not supported.
|
||||
- Volume access. Volume handles can be opened and closed, but volumes cannot be read or written. Such an operation makes little sense for most user mode file systems, that do not store information on disks.
|
||||
- Sparse files. A user mode file system is free to implement sparse files. However WinFsp does not support any sparse file related FSCTL or information class codes.
|
||||
- Compressed files. A user mode file system is free to implement compressed files. However WinFsp does not support any compression related FSCTL or information class codes.
|
||||
- Encrypted files. A user mode file system is free to implement encrypted files. However WinFsp does not support any encryption related FSCTL or information class codes.
|
||||
- Quotas.
|
||||
- The Change Journal.
|
||||
- Defragmentation support.
|
||||
|
||||
== Incompatibilities
|
||||
|
||||
This section lists incompatibilites with NTFS in those features that they both support:
|
||||
|
||||
- WinFsp supports case sensitive and case insensitive file systems. However it does not support case sensitive lookups on a case insensitive file system (+SL_CASE_SENSITIVE+).
|
||||
- NTFS updates the file size information in the directory entry when a file is cleaned up. WinFsp file systems do not (and probably should not attempt to) replicate this behavior. [Related article: https://blogs.msdn.microsoft.com/oldnewthing/20111226-00/?p=8813]
|
||||
- NTFS supports change notifications on streams (these are mostly undocumented). WinFsp supports them as well but it differs from NTFS in that it issues a single notification when a file with streams is deleted; NTFS appears to issue one notification per deleted stream.
|
||||
- WinFsp does not support renaming a stream.
|
||||
- NTFS allows for enumeration and change notifications of all reparse points by opening a special NTFS-only "directory" that "contains" all reparse points (+\$Extend\$Reparse:$R:$INDEX_ALLOCATION+). WinFsp does not support this feature.
|
192
doc/WinFsp-Performance-Testing.asciidoc
Normal file
@ -0,0 +1,192 @@
|
||||
= Performance Testing
|
||||
:caption:
|
||||
|
||||
This document discusses performance testing for WinFsp. The goal of this performance testing is to discover optimization opportunities for WinFsp and compare its performance to that of NTFS and Dokany.
|
||||
|
||||
== Executive Summary
|
||||
|
||||
This performance testing shows that WinFsp has excellent performance in all tested scenarios. It outperforms NTFS in most scenarios (an unfair comparison as NTFS is a disk file system and WinFsp is tested with an in-memory file system). It also outperforms Dokany in all scenarios, often by an order of magnitude.
|
||||
|
||||
ifdef::env-browser[chart::bar[data-uri="WinFsp-Performance-Testing/file_tests.csv",file="WinFsp-Performance-Testing/file_tests.png",opt="y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_tests.png[]]
|
||||
|
||||
ifdef::env-browser[chart::bar[data-uri="WinFsp-Performance-Testing/rdwr_tests.csv",file="WinFsp-Performance-Testing/rdwr_tests.png",opt="y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/rdwr_tests.png[]]
|
||||
|
||||
== Fsbench
|
||||
|
||||
All testing was performed using a new performance test suite developed as part of WinFsp, called https://github.com/billziss-gh/winfsp/blob/master/tst/fsbench/fsbench.c[fsbench]. Fsbench was developed because it allows the creation of tests that are important to file system developers; for example, it can answer questions of the type: "how long does it take to delete 1000 files" or "how long does it take to list a directory with 10000 files in it".
|
||||
|
||||
Fsbench is based on the https://github.com/billziss-gh/winfsp/tree/master/ext/tlib[tlib] library, originally from the *secfs* project. Tlib is usually used to develop regression test suites in C/C++, but can be also used to create performance tests.
|
||||
|
||||
Fsbench currently includes the following tests:
|
||||
|
||||
[width="100%",cols="20%,60%,20%",options="header"]
|
||||
|===
|
||||
|Test |Measures performance of |Parameters
|
||||
|file_create_test |CreateFileW(CREATE_NEW) / CloseHandle |file count
|
||||
|file_open_test |CreateFileW(OPEN_EXISTING) / CloseHandle |file count
|
||||
|file_overwrite_test|CreateFileW(CREATE_ALWAYS) / CloseHandle with existing files|file count
|
||||
|file_list_test |FindFirstFileW / FindNextFile / FindClose |iterations
|
||||
|file_delete_test |DeleteFileW |file count
|
||||
|file_mkdir_test |CreateDirectoryW |file count
|
||||
|file_rmdir_test |RemoveDirectoryW |file count
|
||||
|rdwr_cc_write_page_test |WriteFile (1 page; cached) |iterations
|
||||
|rdwr_cc_read_page_test |ReadFile (1 page; cached) |iterations
|
||||
|rdwr_nc_write_page_test |WriteFile (1 page; non-cached) |iterations
|
||||
|rdwr_nc_read_page_test |ReadFile (1 page; non-cached) |iterations
|
||||
|rdwr_cc_write_large_test |WriteFile (16 pages; cached) |iterations
|
||||
|rdwr_cc_read_large_test |ReadFile (16 pages; cached) |iterations
|
||||
|rdwr_nc_write_large_test |WriteFile (16 pages; non-cached) |iterations
|
||||
|rdwr_nc_read_large_test |ReadFile (16 pages; non-cached) |iterations
|
||||
|mmap_write_test |Memory mapped write test |iterations
|
||||
|mmap_write_test |Memory mapped read test |iterations
|
||||
|===
|
||||
|
||||
== Tested File Systems
|
||||
|
||||
=== NTFS
|
||||
|
||||
The comparison to NTFS is very important to establish a baseline. It is also very misleading because NTFS is a disk file system and MEMFS (either the WinFsp or Dokany variants) is an in memory file system. The tests will show that MEMFS is faster than NTFS. This should not be taken to mean that we are trying to make the (obvious) claim that an in memory file system is faster than a disk file system, but to show that the approach of writing a file system in user mode is a valid proposition and can be efficient.
|
||||
|
||||
=== WinFsp/MEMFS
|
||||
|
||||
MEMFS is the file system used to test WinFsp and shipped as a sample bundled with the WinFsp installer. MEMFS is a simple in memory file system and as such is very fast under most conditions. This is desirable because our goal with this performance testing is to measure the speed of the WinFsp system components rather the performance of a complex user mode file system. MEMFS has minimal overhead and is ideal for this purpose.
|
||||
|
||||
WinFsp/MEMFS can be run in different configurations, which enable or disable WinFsp caching features. The tested configurations were:
|
||||
|
||||
- An infinite FileInfoTimeout, which enables caching of metadata and data.
|
||||
- A FileInfoTimeout of 1s (second), which enables caching of metadata but disables caching of data.
|
||||
- A FileInfoTimeout of 0, which completely disables caching.
|
||||
|
||||
The WinFsp git commit at the time of testing was d804f5674d76f11ea86d14f4bcb1157e6e40e719.
|
||||
|
||||
=== Dokany/MEMFS
|
||||
|
||||
To achieve fairness when comparing Dokany to WinFsp the MEMFS file system has been ported to Dokany. Substantial care was taken to ensure that WinFsp/MEMFS and Dokany/MEMFS perform equally well, so that the performance of the Dokany FSD and user-mode components can be measured and compared accurately.
|
||||
|
||||
The Dokany/MEMFS project has its own https://github.com/billziss-gh/memfs-dokany[repository]. The project comes without a license, which means that it may not be used for any purpose other than as a reference.
|
||||
|
||||
The Dokany version used for testing was 1.0.1. The Dokany/MEMFS git commit was 27a678d7c0d5ee2fb3fb2ecc8e38210857ae941c.
|
||||
|
||||
== Test Environment
|
||||
|
||||
Tests were performed on an idle computer/VM. There was a reboot of both the computer and VM before each file system was tested. Each test was run twice and the smaller time value chosen. The assumption is that even in a seemingly idle desktop system there is some activity which will affect the results; the smaller value is the preferred one to use because it reflects the time when there is less or no other activity.
|
||||
|
||||
The test environment was as follows:
|
||||
----
|
||||
MacBook Pro (Retina, 13-inch, Early 2015)
|
||||
3.1 GHz Intel Core i7
|
||||
16 GB 1867 MHz DDR3
|
||||
500 GB SSD
|
||||
|
||||
VirtualBox Version 5.0.20 r106931
|
||||
1 CPU
|
||||
4 GB RAM
|
||||
80 GB Dynamically allocated differencing storage
|
||||
|
||||
Windows 10 (64-bit) Version 1511 (OS Build 10586.420)
|
||||
----
|
||||
|
||||
== Test Results
|
||||
|
||||
In the graphs below we use consistent coloring to quickly identify a file system. Red is used for NTFS, yellow for WinFsp/MEMFS with a FileInfoTimeout of 0, green for WinFsp/MEMFS with a FileInfoTimeout of 1, light blue for WinFsp/MEMFS with an infinite FileInfoTimeout and deep blue for Dokany/MEMFS.
|
||||
|
||||
In all tests lower times are better (the file system is faster).
|
||||
|
||||
=== File Tests
|
||||
|
||||
These tests measure the performance of creating, opening, overwriting and listing files and directories.
|
||||
|
||||
==== file_create_test
|
||||
|
||||
This test measures the performance of CreateFileW(CREATE_NEW) / CloseHandle. WinFsp has the best performance here. Dokany follows and NTFS is last as it has to actually update its data structures on disk.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/file_create_test.csv",file="WinFsp-Performance-Testing/file_create_test.png",opt="x-label=file count,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_create_test.png[]]
|
||||
|
||||
==== file_open_test
|
||||
|
||||
This test measures the performance of CreateFileW(OPEN_EXISTING) / CloseHandle. WinFsp again has the best (although uneven) performance, followed by NTFS and then Dokany.
|
||||
|
||||
WinFsp appears to have very uneven performance here. In particular notice that opening 1000 files is slower than opening 2000 files, which makes no sense! I suspect that the test observes an initial acquisition of resouces when the test first starts, which is not necessary when the test runs for 2000 files at a later time. This uneven performance should probably be investigated in the future.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/file_open_test.csv",file="WinFsp-Performance-Testing/file_open_test.png",opt="x-label=file count,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_open_test.png[]]
|
||||
|
||||
==== file_overwrite_test
|
||||
|
||||
This test measures the performance of CreateFileW(CREATE_ALWAYS) / CloseHandle. WinFsp is fastest, followed by NTFS and then Dokany.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/file_overwrite_test.csv",file="WinFsp-Performance-Testing/file_overwrite_test.png",opt="x-label=file count,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_overwrite_test.png[]]
|
||||
|
||||
==== file_list_test
|
||||
|
||||
This test measures the performance of FindFirstFileW / FindNextFile / FindClose. NTFS wins this scenario, likely because it can satisfy the list operation from cache. WinFsp has overall good performance. Dokany appears to show slightly quadratic performance in this scenario.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/file_list_test.csv",file="WinFsp-Performance-Testing/file_list_test.png",opt="x-label=file count,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_list_test.png[]]
|
||||
|
||||
==== file_delete_test
|
||||
|
||||
This test measures the performance of DeleteFileW. WinFsp has the best performance, followed by Dokany and NTFS with very similar performance.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/file_delete_test.csv",file="WinFsp-Performance-Testing/file_delete_test.png",opt="x-label=file count,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/file_delete_test.png[]]
|
||||
|
||||
=== Read/Write Tests
|
||||
|
||||
These tests measure the performance of cached, non-cached and memory-mapped I/O.
|
||||
|
||||
==== rdwr_cc_write_page_test
|
||||
|
||||
This test measures the performance of cached WriteFile with 1 page writes. NTFS and WinFsp with an infinite FileInfoTimeout have the best performance, with a clear edge to NTFS (likely because of its use of FastIO, which WinFsp does not currently support). WinFsp with a FileInfoTimeout of 0 or 1 performance is next, because WinFsp does not use the NTOS Cache Manager in this scenario. Dokany performance is last.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/rdwr_cc_write_page_test.csv",file="WinFsp-Performance-Testing/rdwr_cc_write_page_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/rdwr_cc_write_page_test.png[]]
|
||||
|
||||
==== rdwr_cc_read_page_test
|
||||
|
||||
This test measures the performance of cached ReadFile with 1 page reads. The results here are very similar to the rdwr_cc_write_page_test case and similar comments apply.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/rdwr_cc_read_page_test.csv",file="WinFsp-Performance-Testing/rdwr_cc_read_page_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/rdwr_cc_read_page_test.png[]]
|
||||
|
||||
==== rdwr_nc_write_page_test
|
||||
|
||||
This test measures the performance of non-cached WriteFile with 1 page writes. WinFsp has the best performance, followed by Dokany. NTFS shows bad performance, which of course make sense as we are asking it to write all data to the disk.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/rdwr_nc_write_page_test.csv",file="WinFsp-Performance-Testing/rdwr_nc_write_page_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/rdwr_nc_write_page_test.png[]]
|
||||
|
||||
==== rdwr_nc_read_page_test
|
||||
|
||||
This test measures the performance of non-cached ReadFile with 1 page reads. The results here are very similar to the rdwr_nc_write_page_test case and similar comments apply.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/rdwr_nc_read_page_test.csv",file="WinFsp-Performance-Testing/rdwr_nc_read_page_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/rdwr_nc_read_page_test.png[]]
|
||||
|
||||
==== mmap_write_test
|
||||
|
||||
This test measures the performance of memory mapped writes. NTFS and WinFsp seem to have identical performance here, which actually makes sense because memory mapped I/O is effectively always cached and most of the actual I/O is done asynchronously by the system.
|
||||
|
||||
There are no results for Dokany as it seems to (still) not support memory mapped files:
|
||||
|
||||
----
|
||||
Y:\>c:\Users\billziss\Projects\winfsp\build\VStudio\build\Release\fsbench-x64.exe --mmap=100 mmap*
|
||||
mmap_write_test........................ KO
|
||||
ASSERT(0 != Mapping) failed at fsbench.c:226:mmap_dotest
|
||||
----
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/mmap_write_test.csv",file="WinFsp-Performance-Testing/mmap_write_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/mmap_write_test.png[]]
|
||||
|
||||
==== mmap_read_test
|
||||
|
||||
This test measures the performance of memory mapped reads. Again NTFS and WinFsp seem to have identical performance here.
|
||||
|
||||
There are no results for Dokany as it faces the same issue as with mmap_write_test.
|
||||
|
||||
ifdef::env-browser[chart::line[data-uri="WinFsp-Performance-Testing/mmap_read_test.csv",file="WinFsp-Performance-Testing/mmap_read_test.png",opt="x-label=iterations,y-label=time"]]
|
||||
ifndef::env-browser[image::WinFsp-Performance-Testing/mmap_read_test.png[]]
|
75
doc/WinFsp-Performance-Testing/ORIG/dokany-1.csv
Normal file
@ -0,0 +1,75 @@
|
||||
file_create_test,1000,0.28
|
||||
file_open_test,1000,0.14
|
||||
file_overwrite_test,1000,0.33
|
||||
file_list_test,1000,0.16
|
||||
file_delete_test,1000,0.17
|
||||
file_mkdir_test,1000,0.08
|
||||
file_rmdir_test,1000,0.14
|
||||
file_create_test,2000,0.67
|
||||
file_open_test,2000,0.27
|
||||
file_overwrite_test,2000,0.69
|
||||
file_list_test,2000,0.36
|
||||
file_delete_test,2000,0.36
|
||||
file_mkdir_test,2000,0.33
|
||||
file_rmdir_test,2000,0.23
|
||||
file_create_test,3000,0.91
|
||||
file_open_test,3000,0.42
|
||||
file_overwrite_test,3000,1.03
|
||||
file_list_test,3000,0.64
|
||||
file_delete_test,3000,0.56
|
||||
file_mkdir_test,3000,0.52
|
||||
file_rmdir_test,3000,0.34
|
||||
file_create_test,4000,1.25
|
||||
file_open_test,4000,0.55
|
||||
file_overwrite_test,4000,1.34
|
||||
file_list_test,4000,0.97
|
||||
file_delete_test,4000,0.72
|
||||
file_mkdir_test,4000,0.66
|
||||
file_rmdir_test,4000,0.47
|
||||
file_create_test,5000,1.87
|
||||
file_open_test,5000,0.67
|
||||
file_overwrite_test,5000,1.64
|
||||
file_list_test,5000,1.38
|
||||
file_delete_test,5000,0.91
|
||||
file_mkdir_test,5000,0.83
|
||||
file_rmdir_test,5000,0.59
|
||||
rdwr_cc_write_page_test,100,2.19
|
||||
rdwr_cc_read_page_test,100,2.31
|
||||
rdwr_cc_write_large_test,100,0.33
|
||||
rdwr_cc_read_large_test,100,0.28
|
||||
rdwr_cc_write_page_test,200,4.33
|
||||
rdwr_cc_read_page_test,200,4.58
|
||||
rdwr_cc_write_large_test,200,0.59
|
||||
rdwr_cc_read_large_test,200,0.59
|
||||
rdwr_cc_write_page_test,300,6.37
|
||||
rdwr_cc_read_page_test,300,7.00
|
||||
rdwr_cc_write_large_test,300,0.91
|
||||
rdwr_cc_read_large_test,300,0.89
|
||||
rdwr_cc_write_page_test,400,8.59
|
||||
rdwr_cc_read_page_test,400,9.34
|
||||
rdwr_cc_write_large_test,400,1.22
|
||||
rdwr_cc_read_large_test,400,1.17
|
||||
rdwr_cc_write_page_test,500,10.70
|
||||
rdwr_cc_read_page_test,500,11.47
|
||||
rdwr_cc_write_large_test,500,1.47
|
||||
rdwr_cc_read_large_test,500,1.45
|
||||
rdwr_nc_write_page_test,100,2.20
|
||||
rdwr_nc_read_page_test,100,2.22
|
||||
rdwr_nc_write_large_test,100,0.36
|
||||
rdwr_nc_read_large_test,100,0.30
|
||||
rdwr_nc_write_page_test,200,4.72
|
||||
rdwr_nc_read_page_test,200,4.48
|
||||
rdwr_nc_write_large_test,200,0.63
|
||||
rdwr_nc_read_large_test,200,0.58
|
||||
rdwr_nc_write_page_test,300,6.53
|
||||
rdwr_nc_read_page_test,300,6.56
|
||||
rdwr_nc_write_large_test,300,0.91
|
||||
rdwr_nc_read_large_test,300,0.84
|
||||
rdwr_nc_write_page_test,400,9.05
|
||||
rdwr_nc_read_page_test,400,8.67
|
||||
rdwr_nc_write_large_test,400,1.22
|
||||
rdwr_nc_read_large_test,400,1.13
|
||||
rdwr_nc_write_page_test,500,11.45
|
||||
rdwr_nc_read_page_test,500,10.86
|
||||
rdwr_nc_write_large_test,500,1.50
|
||||
rdwr_nc_read_large_test,500,1.44
|
|
75
doc/WinFsp-Performance-Testing/ORIG/dokany-2.csv
Normal file
@ -0,0 +1,75 @@
|
||||
file_create_test,1000,0.28
|
||||
file_open_test,1000,0.15
|
||||
file_overwrite_test,1000,0.33
|
||||
file_list_test,1000,0.16
|
||||
file_delete_test,1000,0.19
|
||||
file_mkdir_test,1000,0.08
|
||||
file_rmdir_test,1000,0.13
|
||||
file_create_test,2000,0.69
|
||||
file_open_test,2000,0.27
|
||||
file_overwrite_test,2000,0.67
|
||||
file_list_test,2000,0.37
|
||||
file_delete_test,2000,0.36
|
||||
file_mkdir_test,2000,0.33
|
||||
file_rmdir_test,2000,0.25
|
||||
file_create_test,3000,0.92
|
||||
file_open_test,3000,0.41
|
||||
file_overwrite_test,3000,1.08
|
||||
file_list_test,3000,0.66
|
||||
file_delete_test,3000,0.56
|
||||
file_mkdir_test,3000,0.48
|
||||
file_rmdir_test,3000,0.38
|
||||
file_create_test,4000,1.31
|
||||
file_open_test,4000,0.61
|
||||
file_overwrite_test,4000,1.38
|
||||
file_list_test,4000,1.00
|
||||
file_delete_test,4000,0.73
|
||||
file_mkdir_test,4000,0.66
|
||||
file_rmdir_test,4000,0.53
|
||||
file_create_test,5000,1.64
|
||||
file_open_test,5000,0.67
|
||||
file_overwrite_test,5000,1.67
|
||||
file_list_test,5000,1.38
|
||||
file_delete_test,5000,0.91
|
||||
file_mkdir_test,5000,0.98
|
||||
file_rmdir_test,5000,0.66
|
||||
rdwr_cc_write_page_test,100,2.08
|
||||
rdwr_cc_read_page_test,100,2.23
|
||||
rdwr_cc_write_large_test,100,0.33
|
||||
rdwr_cc_read_large_test,100,0.28
|
||||
rdwr_cc_write_page_test,200,4.23
|
||||
rdwr_cc_read_page_test,200,4.63
|
||||
rdwr_cc_write_large_test,200,0.61
|
||||
rdwr_cc_read_large_test,200,0.58
|
||||
rdwr_cc_write_page_test,300,6.33
|
||||
rdwr_cc_read_page_test,300,6.78
|
||||
rdwr_cc_write_large_test,300,0.92
|
||||
rdwr_cc_read_large_test,300,0.86
|
||||
rdwr_cc_write_page_test,400,8.48
|
||||
rdwr_cc_read_page_test,400,9.02
|
||||
rdwr_cc_write_large_test,400,1.20
|
||||
rdwr_cc_read_large_test,400,1.16
|
||||
rdwr_cc_write_page_test,500,10.33
|
||||
rdwr_cc_read_page_test,500,11.20
|
||||
rdwr_cc_write_large_test,500,1.53
|
||||
rdwr_cc_read_large_test,500,1.47
|
||||
rdwr_nc_write_page_test,100,2.23
|
||||
rdwr_nc_read_page_test,100,2.22
|
||||
rdwr_nc_write_large_test,100,0.31
|
||||
rdwr_nc_read_large_test,100,0.30
|
||||
rdwr_nc_write_page_test,200,4.66
|
||||
rdwr_nc_read_page_test,200,4.34
|
||||
rdwr_nc_write_large_test,200,0.61
|
||||
rdwr_nc_read_large_test,200,0.63
|
||||
rdwr_nc_write_page_test,300,6.44
|
||||
rdwr_nc_read_page_test,300,6.34
|
||||
rdwr_nc_write_large_test,300,0.92
|
||||
rdwr_nc_read_large_test,300,0.84
|
||||
rdwr_nc_write_page_test,400,8.56
|
||||
rdwr_nc_read_page_test,400,8.78
|
||||
rdwr_nc_write_large_test,400,1.26
|
||||
rdwr_nc_read_large_test,400,1.11
|
||||
rdwr_nc_write_page_test,500,10.73
|
||||
rdwr_nc_read_page_test,500,10.59
|
||||
rdwr_nc_write_large_test,500,1.53
|
||||
rdwr_nc_read_large_test,500,1.41
|
|
85
doc/WinFsp-Performance-Testing/ORIG/ntfs-1.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.92
|
||||
file_open_test,1000,0.08
|
||||
file_overwrite_test,1000,0.19
|
||||
file_list_test,1000,0.08
|
||||
file_delete_test,1000,0.19
|
||||
file_mkdir_test,1000,0.16
|
||||
file_rmdir_test,1000,0.11
|
||||
file_create_test,2000,1.45
|
||||
file_open_test,2000,0.17
|
||||
file_overwrite_test,2000,0.38
|
||||
file_list_test,2000,0.16
|
||||
file_delete_test,2000,0.39
|
||||
file_mkdir_test,2000,0.25
|
||||
file_rmdir_test,2000,0.28
|
||||
file_create_test,3000,1.11
|
||||
file_open_test,3000,0.23
|
||||
file_overwrite_test,3000,0.72
|
||||
file_list_test,3000,0.23
|
||||
file_delete_test,3000,0.56
|
||||
file_mkdir_test,3000,0.56
|
||||
file_rmdir_test,3000,0.36
|
||||
file_create_test,4000,1.45
|
||||
file_open_test,4000,0.36
|
||||
file_overwrite_test,4000,0.97
|
||||
file_list_test,4000,0.33
|
||||
file_delete_test,4000,0.77
|
||||
file_mkdir_test,4000,0.48
|
||||
file_rmdir_test,4000,0.47
|
||||
file_create_test,5000,2.47
|
||||
file_open_test,5000,0.45
|
||||
file_overwrite_test,5000,1.23
|
||||
file_list_test,5000,0.41
|
||||
file_delete_test,5000,1.03
|
||||
file_mkdir_test,5000,0.70
|
||||
file_rmdir_test,5000,0.70
|
||||
rdwr_cc_write_page_test,100,0.25
|
||||
rdwr_cc_read_page_test,100,0.19
|
||||
rdwr_cc_write_large_test,100,0.09
|
||||
rdwr_cc_read_large_test,100,0.08
|
||||
rdwr_cc_write_page_test,200,0.47
|
||||
rdwr_cc_read_page_test,200,0.52
|
||||
rdwr_cc_write_large_test,200,0.22
|
||||
rdwr_cc_read_large_test,200,0.16
|
||||
rdwr_cc_write_page_test,300,0.72
|
||||
rdwr_cc_read_page_test,300,0.62
|
||||
rdwr_cc_write_large_test,300,0.30
|
||||
rdwr_cc_read_large_test,300,0.23
|
||||
rdwr_cc_write_page_test,400,0.92
|
||||
rdwr_cc_read_page_test,400,0.88
|
||||
rdwr_cc_write_large_test,400,0.41
|
||||
rdwr_cc_read_large_test,400,0.31
|
||||
rdwr_cc_write_page_test,500,1.20
|
||||
rdwr_cc_read_page_test,500,0.97
|
||||
rdwr_cc_write_large_test,500,0.50
|
||||
rdwr_cc_read_large_test,500,0.39
|
||||
rdwr_nc_write_page_test,100,7.56
|
||||
rdwr_nc_read_page_test,100,10.14
|
||||
rdwr_nc_write_large_test,100,0.88
|
||||
rdwr_nc_read_large_test,100,0.56
|
||||
rdwr_nc_write_page_test,200,14.36
|
||||
rdwr_nc_read_page_test,200,21.39
|
||||
rdwr_nc_write_large_test,200,1.72
|
||||
rdwr_nc_read_large_test,200,1.34
|
||||
rdwr_nc_write_page_test,300,21.86
|
||||
rdwr_nc_read_page_test,300,19.56
|
||||
rdwr_nc_write_large_test,300,2.53
|
||||
rdwr_nc_read_large_test,300,1.64
|
||||
rdwr_nc_write_page_test,400,28.52
|
||||
rdwr_nc_read_page_test,400,26.11
|
||||
rdwr_nc_write_large_test,400,3.42
|
||||
rdwr_nc_read_large_test,400,2.22
|
||||
rdwr_nc_write_page_test,500,35.45
|
||||
rdwr_nc_read_page_test,500,33.05
|
||||
rdwr_nc_write_large_test,500,4.33
|
||||
rdwr_nc_read_large_test,500,2.77
|
||||
mmap_write_test,100,0.16
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.30
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.58
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.72
|
||||
mmap_read_test,500,1.06
|
|
85
doc/WinFsp-Performance-Testing/ORIG/ntfs-2.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.97
|
||||
file_open_test,1000,0.08
|
||||
file_overwrite_test,1000,0.19
|
||||
file_list_test,1000,0.08
|
||||
file_delete_test,1000,0.19
|
||||
file_mkdir_test,1000,0.13
|
||||
file_rmdir_test,1000,0.13
|
||||
file_create_test,2000,1.38
|
||||
file_open_test,2000,0.23
|
||||
file_overwrite_test,2000,0.36
|
||||
file_list_test,2000,0.17
|
||||
file_delete_test,2000,0.41
|
||||
file_mkdir_test,2000,0.25
|
||||
file_rmdir_test,2000,0.36
|
||||
file_create_test,3000,1.34
|
||||
file_open_test,3000,0.28
|
||||
file_overwrite_test,3000,0.78
|
||||
file_list_test,3000,0.27
|
||||
file_delete_test,3000,0.59
|
||||
file_mkdir_test,3000,0.36
|
||||
file_rmdir_test,3000,0.36
|
||||
file_create_test,4000,1.33
|
||||
file_open_test,4000,0.36
|
||||
file_overwrite_test,4000,1.06
|
||||
file_list_test,4000,0.33
|
||||
file_delete_test,4000,0.81
|
||||
file_mkdir_test,4000,0.67
|
||||
file_rmdir_test,4000,0.41
|
||||
file_create_test,5000,1.94
|
||||
file_open_test,5000,0.48
|
||||
file_overwrite_test,5000,1.14
|
||||
file_list_test,5000,0.44
|
||||
file_delete_test,5000,1.06
|
||||
file_mkdir_test,5000,0.87
|
||||
file_rmdir_test,5000,0.59
|
||||
rdwr_cc_write_page_test,100,0.25
|
||||
rdwr_cc_read_page_test,100,0.19
|
||||
rdwr_cc_write_large_test,100,0.11
|
||||
rdwr_cc_read_large_test,100,0.08
|
||||
rdwr_cc_write_page_test,200,0.61
|
||||
rdwr_cc_read_page_test,200,0.42
|
||||
rdwr_cc_write_large_test,200,0.22
|
||||
rdwr_cc_read_large_test,200,0.25
|
||||
rdwr_cc_write_page_test,300,0.69
|
||||
rdwr_cc_read_page_test,300,0.61
|
||||
rdwr_cc_write_large_test,300,0.28
|
||||
rdwr_cc_read_large_test,300,0.22
|
||||
rdwr_cc_write_page_test,400,0.91
|
||||
rdwr_cc_read_page_test,400,0.78
|
||||
rdwr_cc_write_large_test,400,0.38
|
||||
rdwr_cc_read_large_test,400,0.28
|
||||
rdwr_cc_write_page_test,500,1.19
|
||||
rdwr_cc_read_page_test,500,1.03
|
||||
rdwr_cc_write_large_test,500,0.48
|
||||
rdwr_cc_read_large_test,500,0.36
|
||||
rdwr_nc_write_page_test,100,7.55
|
||||
rdwr_nc_read_page_test,100,9.38
|
||||
rdwr_nc_write_large_test,100,0.86
|
||||
rdwr_nc_read_large_test,100,0.58
|
||||
rdwr_nc_write_page_test,200,15.69
|
||||
rdwr_nc_read_page_test,200,21.78
|
||||
rdwr_nc_write_large_test,200,1.73
|
||||
rdwr_nc_read_large_test,200,1.16
|
||||
rdwr_nc_write_page_test,300,21.58
|
||||
rdwr_nc_read_page_test,300,21.92
|
||||
rdwr_nc_write_large_test,300,2.59
|
||||
rdwr_nc_read_large_test,300,1.84
|
||||
rdwr_nc_write_page_test,400,28.91
|
||||
rdwr_nc_read_page_test,400,26.31
|
||||
rdwr_nc_write_large_test,400,3.38
|
||||
rdwr_nc_read_large_test,400,2.20
|
||||
rdwr_nc_write_page_test,500,36.69
|
||||
rdwr_nc_read_page_test,500,33.52
|
||||
rdwr_nc_write_large_test,500,4.36
|
||||
rdwr_nc_read_large_test,500,2.80
|
||||
mmap_write_test,100,0.16
|
||||
mmap_read_test,100,0.19
|
||||
mmap_write_test,200,0.31
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.58
|
||||
mmap_write_test,400,0.59
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.72
|
||||
mmap_read_test,500,1.09
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-t0-1.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.20
|
||||
file_open_test,1000,0.08
|
||||
file_overwrite_test,1000,0.06
|
||||
file_list_test,1000,0.11
|
||||
file_delete_test,1000,0.09
|
||||
file_mkdir_test,1000,0.06
|
||||
file_rmdir_test,1000,0.08
|
||||
file_create_test,2000,0.48
|
||||
file_open_test,2000,0.11
|
||||
file_overwrite_test,2000,0.11
|
||||
file_list_test,2000,0.23
|
||||
file_delete_test,2000,0.19
|
||||
file_mkdir_test,2000,0.09
|
||||
file_rmdir_test,2000,0.14
|
||||
file_create_test,3000,0.61
|
||||
file_open_test,3000,0.30
|
||||
file_overwrite_test,3000,0.17
|
||||
file_list_test,3000,0.33
|
||||
file_delete_test,3000,0.27
|
||||
file_mkdir_test,3000,0.41
|
||||
file_rmdir_test,3000,0.20
|
||||
file_create_test,4000,0.64
|
||||
file_open_test,4000,0.23
|
||||
file_overwrite_test,4000,0.25
|
||||
file_list_test,4000,0.47
|
||||
file_delete_test,4000,0.48
|
||||
file_mkdir_test,4000,0.53
|
||||
file_rmdir_test,4000,0.27
|
||||
file_create_test,5000,1.08
|
||||
file_open_test,5000,0.28
|
||||
file_overwrite_test,5000,0.30
|
||||
file_list_test,5000,0.61
|
||||
file_delete_test,5000,0.52
|
||||
file_mkdir_test,5000,0.66
|
||||
file_rmdir_test,5000,0.39
|
||||
rdwr_cc_write_page_test,100,1.30
|
||||
rdwr_cc_read_page_test,100,1.44
|
||||
rdwr_cc_write_large_test,100,0.17
|
||||
rdwr_cc_read_large_test,100,0.17
|
||||
rdwr_cc_write_page_test,200,2.67
|
||||
rdwr_cc_read_page_test,200,2.97
|
||||
rdwr_cc_write_large_test,200,0.33
|
||||
rdwr_cc_read_large_test,200,0.39
|
||||
rdwr_cc_write_page_test,300,4.00
|
||||
rdwr_cc_read_page_test,300,4.42
|
||||
rdwr_cc_write_large_test,300,0.48
|
||||
rdwr_cc_read_large_test,300,0.50
|
||||
rdwr_cc_write_page_test,400,5.36
|
||||
rdwr_cc_read_page_test,400,5.86
|
||||
rdwr_cc_write_large_test,400,0.63
|
||||
rdwr_cc_read_large_test,400,0.66
|
||||
rdwr_cc_write_page_test,500,6.55
|
||||
rdwr_cc_read_page_test,500,7.05
|
||||
rdwr_cc_write_large_test,500,0.89
|
||||
rdwr_cc_read_large_test,500,0.89
|
||||
rdwr_nc_write_page_test,100,1.33
|
||||
rdwr_nc_read_page_test,100,1.33
|
||||
rdwr_nc_write_large_test,100,0.16
|
||||
rdwr_nc_read_large_test,100,0.16
|
||||
rdwr_nc_write_page_test,200,2.67
|
||||
rdwr_nc_read_page_test,200,2.67
|
||||
rdwr_nc_write_large_test,200,0.31
|
||||
rdwr_nc_read_large_test,200,0.33
|
||||
rdwr_nc_write_page_test,300,4.01
|
||||
rdwr_nc_read_page_test,300,4.06
|
||||
rdwr_nc_write_large_test,300,0.48
|
||||
rdwr_nc_read_large_test,300,0.47
|
||||
rdwr_nc_write_page_test,400,5.44
|
||||
rdwr_nc_read_page_test,400,5.42
|
||||
rdwr_nc_write_large_test,400,0.63
|
||||
rdwr_nc_read_large_test,400,0.66
|
||||
rdwr_nc_write_page_test,500,6.41
|
||||
rdwr_nc_read_page_test,500,6.56
|
||||
rdwr_nc_write_large_test,500,0.83
|
||||
rdwr_nc_read_large_test,500,0.78
|
||||
mmap_write_test,100,0.14
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.30
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.45
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.56
|
||||
mmap_read_test,400,0.83
|
||||
mmap_write_test,500,0.72
|
||||
mmap_read_test,500,1.00
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-t0-2.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.20
|
||||
file_open_test,1000,0.06
|
||||
file_overwrite_test,1000,0.05
|
||||
file_list_test,1000,0.11
|
||||
file_delete_test,1000,0.09
|
||||
file_mkdir_test,1000,0.05
|
||||
file_rmdir_test,1000,0.08
|
||||
file_create_test,2000,0.47
|
||||
file_open_test,2000,0.13
|
||||
file_overwrite_test,2000,0.11
|
||||
file_list_test,2000,0.22
|
||||
file_delete_test,2000,0.19
|
||||
file_mkdir_test,2000,0.11
|
||||
file_rmdir_test,2000,0.14
|
||||
file_create_test,3000,0.59
|
||||
file_open_test,3000,0.27
|
||||
file_overwrite_test,3000,0.17
|
||||
file_list_test,3000,0.34
|
||||
file_delete_test,3000,0.27
|
||||
file_mkdir_test,3000,0.41
|
||||
file_rmdir_test,3000,0.20
|
||||
file_create_test,4000,0.62
|
||||
file_open_test,4000,0.22
|
||||
file_overwrite_test,4000,0.41
|
||||
file_list_test,4000,0.47
|
||||
file_delete_test,4000,0.34
|
||||
file_mkdir_test,4000,0.55
|
||||
file_rmdir_test,4000,0.28
|
||||
file_create_test,5000,1.08
|
||||
file_open_test,5000,0.28
|
||||
file_overwrite_test,5000,0.30
|
||||
file_list_test,5000,0.61
|
||||
file_delete_test,5000,0.45
|
||||
file_mkdir_test,5000,0.67
|
||||
file_rmdir_test,5000,0.34
|
||||
rdwr_cc_write_page_test,100,1.36
|
||||
rdwr_cc_read_page_test,100,1.47
|
||||
rdwr_cc_write_large_test,100,0.17
|
||||
rdwr_cc_read_large_test,100,0.17
|
||||
rdwr_cc_write_page_test,200,2.63
|
||||
rdwr_cc_read_page_test,200,3.00
|
||||
rdwr_cc_write_large_test,200,0.31
|
||||
rdwr_cc_read_large_test,200,0.34
|
||||
rdwr_cc_write_page_test,300,3.91
|
||||
rdwr_cc_read_page_test,300,4.20
|
||||
rdwr_cc_write_large_test,300,0.50
|
||||
rdwr_cc_read_large_test,300,0.52
|
||||
rdwr_cc_write_page_test,400,5.23
|
||||
rdwr_cc_read_page_test,400,5.64
|
||||
rdwr_cc_write_large_test,400,0.72
|
||||
rdwr_cc_read_large_test,400,0.66
|
||||
rdwr_cc_write_page_test,500,6.12
|
||||
rdwr_cc_read_page_test,500,6.83
|
||||
rdwr_cc_write_large_test,500,0.80
|
||||
rdwr_cc_read_large_test,500,0.83
|
||||
rdwr_nc_write_page_test,100,1.30
|
||||
rdwr_nc_read_page_test,100,1.36
|
||||
rdwr_nc_write_large_test,100,0.16
|
||||
rdwr_nc_read_large_test,100,0.20
|
||||
rdwr_nc_write_page_test,200,2.73
|
||||
rdwr_nc_read_page_test,200,2.64
|
||||
rdwr_nc_write_large_test,200,0.31
|
||||
rdwr_nc_read_large_test,200,0.31
|
||||
rdwr_nc_write_page_test,300,3.95
|
||||
rdwr_nc_read_page_test,300,4.06
|
||||
rdwr_nc_write_large_test,300,0.48
|
||||
rdwr_nc_read_large_test,300,0.48
|
||||
rdwr_nc_write_page_test,400,5.33
|
||||
rdwr_nc_read_page_test,400,5.47
|
||||
rdwr_nc_write_large_test,400,0.64
|
||||
rdwr_nc_read_large_test,400,0.64
|
||||
rdwr_nc_write_page_test,500,6.48
|
||||
rdwr_nc_read_page_test,500,6.41
|
||||
rdwr_nc_write_large_test,500,0.81
|
||||
rdwr_nc_read_large_test,500,0.81
|
||||
mmap_write_test,100,0.14
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.30
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.45
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.64
|
||||
mmap_read_test,400,0.77
|
||||
mmap_write_test,500,0.73
|
||||
mmap_read_test,500,1.00
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-t1-1.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.06
|
||||
file_open_test,1000,0.16
|
||||
file_overwrite_test,1000,0.05
|
||||
file_list_test,1000,0.09
|
||||
file_delete_test,1000,0.08
|
||||
file_mkdir_test,1000,0.05
|
||||
file_rmdir_test,1000,0.08
|
||||
file_create_test,2000,0.42
|
||||
file_open_test,2000,0.09
|
||||
file_overwrite_test,2000,0.08
|
||||
file_list_test,2000,0.22
|
||||
file_delete_test,2000,0.14
|
||||
file_mkdir_test,2000,0.09
|
||||
file_rmdir_test,2000,0.13
|
||||
file_create_test,3000,0.58
|
||||
file_open_test,3000,0.22
|
||||
file_overwrite_test,3000,0.25
|
||||
file_list_test,3000,0.36
|
||||
file_delete_test,3000,0.22
|
||||
file_mkdir_test,3000,0.39
|
||||
file_rmdir_test,3000,0.17
|
||||
file_create_test,4000,0.59
|
||||
file_open_test,4000,0.19
|
||||
file_overwrite_test,4000,0.17
|
||||
file_list_test,4000,0.58
|
||||
file_delete_test,4000,0.33
|
||||
file_mkdir_test,4000,0.55
|
||||
file_rmdir_test,4000,0.22
|
||||
file_create_test,5000,0.95
|
||||
file_open_test,5000,0.22
|
||||
file_overwrite_test,5000,0.23
|
||||
file_list_test,5000,0.59
|
||||
file_delete_test,5000,0.34
|
||||
file_mkdir_test,5000,0.66
|
||||
file_rmdir_test,5000,0.28
|
||||
rdwr_cc_write_page_test,100,1.37
|
||||
rdwr_cc_read_page_test,100,1.47
|
||||
rdwr_cc_write_large_test,100,0.16
|
||||
rdwr_cc_read_large_test,100,0.17
|
||||
rdwr_cc_write_page_test,200,2.47
|
||||
rdwr_cc_read_page_test,200,3.00
|
||||
rdwr_cc_write_large_test,200,0.31
|
||||
rdwr_cc_read_large_test,200,0.34
|
||||
rdwr_cc_write_page_test,300,3.89
|
||||
rdwr_cc_read_page_test,300,4.45
|
||||
rdwr_cc_write_large_test,300,0.47
|
||||
rdwr_cc_read_large_test,300,0.50
|
||||
rdwr_cc_write_page_test,400,4.92
|
||||
rdwr_cc_read_page_test,400,5.78
|
||||
rdwr_cc_write_large_test,400,0.61
|
||||
rdwr_cc_read_large_test,400,0.67
|
||||
rdwr_cc_write_page_test,500,6.17
|
||||
rdwr_cc_read_page_test,500,7.33
|
||||
rdwr_cc_write_large_test,500,0.78
|
||||
rdwr_cc_read_large_test,500,0.95
|
||||
rdwr_nc_write_page_test,100,1.30
|
||||
rdwr_nc_read_page_test,100,1.39
|
||||
rdwr_nc_write_large_test,100,0.19
|
||||
rdwr_nc_read_large_test,100,0.17
|
||||
rdwr_nc_write_page_test,200,2.61
|
||||
rdwr_nc_read_page_test,200,2.80
|
||||
rdwr_nc_write_large_test,200,0.31
|
||||
rdwr_nc_read_large_test,200,0.34
|
||||
rdwr_nc_write_page_test,300,3.94
|
||||
rdwr_nc_read_page_test,300,4.23
|
||||
rdwr_nc_write_large_test,300,0.48
|
||||
rdwr_nc_read_large_test,300,0.50
|
||||
rdwr_nc_write_page_test,400,5.36
|
||||
rdwr_nc_read_page_test,400,5.52
|
||||
rdwr_nc_write_large_test,400,0.63
|
||||
rdwr_nc_read_large_test,400,0.69
|
||||
rdwr_nc_write_page_test,500,6.51
|
||||
rdwr_nc_read_page_test,500,7.00
|
||||
rdwr_nc_write_large_test,500,0.81
|
||||
rdwr_nc_read_large_test,500,0.81
|
||||
mmap_write_test,100,0.16
|
||||
mmap_read_test,100,0.19
|
||||
mmap_write_test,200,0.31
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.59
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.73
|
||||
mmap_read_test,500,0.98
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-t1-2.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.08
|
||||
file_open_test,1000,0.16
|
||||
file_overwrite_test,1000,0.05
|
||||
file_list_test,1000,0.11
|
||||
file_delete_test,1000,0.06
|
||||
file_mkdir_test,1000,0.16
|
||||
file_rmdir_test,1000,0.06
|
||||
file_create_test,2000,0.36
|
||||
file_open_test,2000,0.09
|
||||
file_overwrite_test,2000,0.09
|
||||
file_list_test,2000,0.20
|
||||
file_delete_test,2000,0.16
|
||||
file_mkdir_test,2000,0.09
|
||||
file_rmdir_test,2000,0.12
|
||||
file_create_test,3000,0.58
|
||||
file_open_test,3000,0.20
|
||||
file_overwrite_test,3000,0.16
|
||||
file_list_test,3000,0.33
|
||||
file_delete_test,3000,0.22
|
||||
file_mkdir_test,3000,0.41
|
||||
file_rmdir_test,3000,0.17
|
||||
file_create_test,4000,0.58
|
||||
file_open_test,4000,0.17
|
||||
file_overwrite_test,4000,0.20
|
||||
file_list_test,4000,0.44
|
||||
file_delete_test,4000,0.38
|
||||
file_mkdir_test,4000,0.59
|
||||
file_rmdir_test,4000,0.25
|
||||
file_create_test,5000,0.97
|
||||
file_open_test,5000,0.22
|
||||
file_overwrite_test,5000,0.22
|
||||
file_list_test,5000,0.61
|
||||
file_delete_test,5000,0.36
|
||||
file_mkdir_test,5000,0.69
|
||||
file_rmdir_test,5000,0.30
|
||||
rdwr_cc_write_page_test,100,1.30
|
||||
rdwr_cc_read_page_test,100,1.53
|
||||
rdwr_cc_write_large_test,100,0.17
|
||||
rdwr_cc_read_large_test,100,0.17
|
||||
rdwr_cc_write_page_test,200,2.62
|
||||
rdwr_cc_read_page_test,200,3.06
|
||||
rdwr_cc_write_large_test,200,0.31
|
||||
rdwr_cc_read_large_test,200,0.34
|
||||
rdwr_cc_write_page_test,300,3.89
|
||||
rdwr_cc_read_page_test,300,4.50
|
||||
rdwr_cc_write_large_test,300,0.50
|
||||
rdwr_cc_read_large_test,300,0.59
|
||||
rdwr_cc_write_page_test,400,5.14
|
||||
rdwr_cc_read_page_test,400,5.94
|
||||
rdwr_cc_write_large_test,400,0.62
|
||||
rdwr_cc_read_large_test,400,0.70
|
||||
rdwr_cc_write_page_test,500,6.25
|
||||
rdwr_cc_read_page_test,500,7.33
|
||||
rdwr_cc_write_large_test,500,0.81
|
||||
rdwr_cc_read_large_test,500,0.83
|
||||
rdwr_nc_write_page_test,100,1.34
|
||||
rdwr_nc_read_page_test,100,1.38
|
||||
rdwr_nc_write_large_test,100,0.19
|
||||
rdwr_nc_read_large_test,100,0.16
|
||||
rdwr_nc_write_page_test,200,2.67
|
||||
rdwr_nc_read_page_test,200,2.78
|
||||
rdwr_nc_write_large_test,200,0.38
|
||||
rdwr_nc_read_large_test,200,0.33
|
||||
rdwr_nc_write_page_test,300,3.98
|
||||
rdwr_nc_read_page_test,300,4.44
|
||||
rdwr_nc_write_large_test,300,0.52
|
||||
rdwr_nc_read_large_test,300,0.50
|
||||
rdwr_nc_write_page_test,400,5.36
|
||||
rdwr_nc_read_page_test,400,5.69
|
||||
rdwr_nc_write_large_test,400,0.66
|
||||
rdwr_nc_read_large_test,400,0.67
|
||||
rdwr_nc_write_page_test,500,6.66
|
||||
rdwr_nc_read_page_test,500,6.94
|
||||
rdwr_nc_write_large_test,500,0.81
|
||||
rdwr_nc_read_large_test,500,0.81
|
||||
mmap_write_test,100,0.14
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.31
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.59
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.75
|
||||
mmap_read_test,500,0.98
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-tinf-1.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.06
|
||||
file_open_test,1000,0.17
|
||||
file_overwrite_test,1000,0.05
|
||||
file_list_test,1000,0.11
|
||||
file_delete_test,1000,0.06
|
||||
file_mkdir_test,1000,0.05
|
||||
file_rmdir_test,1000,0.06
|
||||
file_create_test,2000,0.44
|
||||
file_open_test,2000,0.08
|
||||
file_overwrite_test,2000,0.09
|
||||
file_list_test,2000,0.22
|
||||
file_delete_test,2000,0.14
|
||||
file_mkdir_test,2000,0.09
|
||||
file_rmdir_test,2000,0.14
|
||||
file_create_test,3000,0.56
|
||||
file_open_test,3000,0.20
|
||||
file_overwrite_test,3000,0.14
|
||||
file_list_test,3000,0.33
|
||||
file_delete_test,3000,0.20
|
||||
file_mkdir_test,3000,0.41
|
||||
file_rmdir_test,3000,0.16
|
||||
file_create_test,4000,0.59
|
||||
file_open_test,4000,0.16
|
||||
file_overwrite_test,4000,0.19
|
||||
file_list_test,4000,0.47
|
||||
file_delete_test,4000,0.31
|
||||
file_mkdir_test,4000,0.66
|
||||
file_rmdir_test,4000,0.23
|
||||
file_create_test,5000,0.98
|
||||
file_open_test,5000,0.22
|
||||
file_overwrite_test,5000,0.22
|
||||
file_list_test,5000,0.59
|
||||
file_delete_test,5000,0.36
|
||||
file_mkdir_test,5000,0.66
|
||||
file_rmdir_test,5000,0.31
|
||||
rdwr_cc_write_page_test,100,0.34
|
||||
rdwr_cc_read_page_test,100,0.28
|
||||
rdwr_cc_write_large_test,100,0.11
|
||||
rdwr_cc_read_large_test,100,0.08
|
||||
rdwr_cc_write_page_test,200,0.67
|
||||
rdwr_cc_read_page_test,200,0.58
|
||||
rdwr_cc_write_large_test,200,0.22
|
||||
rdwr_cc_read_large_test,200,0.22
|
||||
rdwr_cc_write_page_test,300,1.01
|
||||
rdwr_cc_read_page_test,300,0.88
|
||||
rdwr_cc_write_large_test,300,0.34
|
||||
rdwr_cc_read_large_test,300,0.25
|
||||
rdwr_cc_write_page_test,400,1.38
|
||||
rdwr_cc_read_page_test,400,1.12
|
||||
rdwr_cc_write_large_test,400,0.42
|
||||
rdwr_cc_read_large_test,400,0.33
|
||||
rdwr_cc_write_page_test,500,1.70
|
||||
rdwr_cc_read_page_test,500,1.48
|
||||
rdwr_cc_write_large_test,500,0.64
|
||||
rdwr_cc_read_large_test,500,0.44
|
||||
rdwr_nc_write_page_test,100,1.31
|
||||
rdwr_nc_read_page_test,100,1.36
|
||||
rdwr_nc_write_large_test,100,0.17
|
||||
rdwr_nc_read_large_test,100,0.16
|
||||
rdwr_nc_write_page_test,200,2.56
|
||||
rdwr_nc_read_page_test,200,2.81
|
||||
rdwr_nc_write_large_test,200,0.33
|
||||
rdwr_nc_read_large_test,200,0.31
|
||||
rdwr_nc_write_page_test,300,3.86
|
||||
rdwr_nc_read_page_test,300,3.95
|
||||
rdwr_nc_write_large_test,300,0.47
|
||||
rdwr_nc_read_large_test,300,0.48
|
||||
rdwr_nc_write_page_test,400,5.11
|
||||
rdwr_nc_read_page_test,400,5.19
|
||||
rdwr_nc_write_large_test,400,0.64
|
||||
rdwr_nc_read_large_test,400,0.64
|
||||
rdwr_nc_write_page_test,500,6.42
|
||||
rdwr_nc_read_page_test,500,6.58
|
||||
rdwr_nc_write_large_test,500,0.78
|
||||
rdwr_nc_read_large_test,500,0.78
|
||||
mmap_write_test,100,0.16
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.30
|
||||
mmap_read_test,200,0.39
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.59
|
||||
mmap_write_test,400,0.59
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.75
|
||||
mmap_read_test,500,1.03
|
|
85
doc/WinFsp-Performance-Testing/ORIG/winfsp-tinf-2.csv
Normal file
@ -0,0 +1,85 @@
|
||||
file_create_test,1000,0.06
|
||||
file_open_test,1000,0.16
|
||||
file_overwrite_test,1000,0.05
|
||||
file_list_test,1000,0.11
|
||||
file_delete_test,1000,0.06
|
||||
file_mkdir_test,1000,0.05
|
||||
file_rmdir_test,1000,0.06
|
||||
file_create_test,2000,0.44
|
||||
file_open_test,2000,0.08
|
||||
file_overwrite_test,2000,0.09
|
||||
file_list_test,2000,0.20
|
||||
file_delete_test,2000,0.16
|
||||
file_mkdir_test,2000,0.09
|
||||
file_rmdir_test,2000,0.13
|
||||
file_create_test,3000,0.58
|
||||
file_open_test,3000,0.22
|
||||
file_overwrite_test,3000,0.13
|
||||
file_list_test,3000,0.34
|
||||
file_delete_test,3000,0.22
|
||||
file_mkdir_test,3000,0.39
|
||||
file_rmdir_test,3000,0.17
|
||||
file_create_test,4000,0.61
|
||||
file_open_test,4000,0.17
|
||||
file_overwrite_test,4000,0.19
|
||||
file_list_test,4000,0.44
|
||||
file_delete_test,4000,0.27
|
||||
file_mkdir_test,4000,0.67
|
||||
file_rmdir_test,4000,0.22
|
||||
file_create_test,5000,0.97
|
||||
file_open_test,5000,0.20
|
||||
file_overwrite_test,5000,0.23
|
||||
file_list_test,5000,0.61
|
||||
file_delete_test,5000,0.33
|
||||
file_mkdir_test,5000,0.67
|
||||
file_rmdir_test,5000,0.28
|
||||
rdwr_cc_write_page_test,100,0.36
|
||||
rdwr_cc_read_page_test,100,0.30
|
||||
rdwr_cc_write_large_test,100,0.12
|
||||
rdwr_cc_read_large_test,100,0.08
|
||||
rdwr_cc_write_page_test,200,0.69
|
||||
rdwr_cc_read_page_test,200,0.58
|
||||
rdwr_cc_write_large_test,200,0.30
|
||||
rdwr_cc_read_large_test,200,0.23
|
||||
rdwr_cc_write_page_test,300,1.02
|
||||
rdwr_cc_read_page_test,300,0.87
|
||||
rdwr_cc_write_large_test,300,0.34
|
||||
rdwr_cc_read_large_test,300,0.23
|
||||
rdwr_cc_write_page_test,400,1.41
|
||||
rdwr_cc_read_page_test,400,1.14
|
||||
rdwr_cc_write_large_test,400,0.47
|
||||
rdwr_cc_read_large_test,400,0.33
|
||||
rdwr_cc_write_page_test,500,1.73
|
||||
rdwr_cc_read_page_test,500,1.50
|
||||
rdwr_cc_write_large_test,500,0.53
|
||||
rdwr_cc_read_large_test,500,0.41
|
||||
rdwr_nc_write_page_test,100,1.33
|
||||
rdwr_nc_read_page_test,100,1.44
|
||||
rdwr_nc_write_large_test,100,0.17
|
||||
rdwr_nc_read_large_test,100,0.17
|
||||
rdwr_nc_write_page_test,200,2.75
|
||||
rdwr_nc_read_page_test,200,2.94
|
||||
rdwr_nc_write_large_test,200,0.38
|
||||
rdwr_nc_read_large_test,200,0.33
|
||||
rdwr_nc_write_page_test,300,3.94
|
||||
rdwr_nc_read_page_test,300,4.17
|
||||
rdwr_nc_write_large_test,300,0.48
|
||||
rdwr_nc_read_large_test,300,0.56
|
||||
rdwr_nc_write_page_test,400,5.25
|
||||
rdwr_nc_read_page_test,400,5.58
|
||||
rdwr_nc_write_large_test,400,0.63
|
||||
rdwr_nc_read_large_test,400,0.64
|
||||
rdwr_nc_write_page_test,500,6.52
|
||||
rdwr_nc_read_page_test,500,6.78
|
||||
rdwr_nc_write_large_test,500,0.80
|
||||
rdwr_nc_read_large_test,500,0.80
|
||||
mmap_write_test,100,0.17
|
||||
mmap_read_test,100,0.20
|
||||
mmap_write_test,200,0.30
|
||||
mmap_read_test,200,0.41
|
||||
mmap_write_test,300,0.44
|
||||
mmap_read_test,300,0.61
|
||||
mmap_write_test,400,0.61
|
||||
mmap_read_test,400,0.78
|
||||
mmap_write_test,500,0.73
|
||||
mmap_read_test,500,0.98
|
|
30
doc/WinFsp-Performance-Testing/file_create_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
1000,0.92
|
||||
2000,1.38
|
||||
3000,1.11
|
||||
4000,1.33
|
||||
5000,1.94
|
||||
//winfsp-t0
|
||||
1000,0.20
|
||||
2000,0.47
|
||||
3000,0.59
|
||||
4000,0.62
|
||||
5000,1.08
|
||||
//winfsp-t1
|
||||
1000,0.06
|
||||
2000,0.36
|
||||
3000,0.58
|
||||
4000,0.58
|
||||
5000,0.95
|
||||
//winfsp-tinf
|
||||
1000,0.06
|
||||
2000,0.44
|
||||
3000,0.56
|
||||
4000,0.59
|
||||
5000,0.97
|
||||
//dokany
|
||||
1000,0.28
|
||||
2000,0.67
|
||||
3000,0.91
|
||||
4000,1.25
|
||||
5000,1.64
|
|
BIN
doc/WinFsp-Performance-Testing/file_create_test.png
Normal file
After Width: | Height: | Size: 60 KiB |
30
doc/WinFsp-Performance-Testing/file_delete_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
1000,0.19
|
||||
2000,0.39
|
||||
3000,0.56
|
||||
4000,0.77
|
||||
5000,1.03
|
||||
//winfsp-t0
|
||||
1000,0.09
|
||||
2000,0.19
|
||||
3000,0.27
|
||||
4000,0.34
|
||||
5000,0.45
|
||||
//winfsp-t1
|
||||
1000,0.06
|
||||
2000,0.14
|
||||
3000,0.22
|
||||
4000,0.33
|
||||
5000,0.34
|
||||
//winfsp-tinf
|
||||
1000,0.06
|
||||
2000,0.14
|
||||
3000,0.20
|
||||
4000,0.27
|
||||
5000,0.33
|
||||
//dokany
|
||||
1000,0.17
|
||||
2000,0.36
|
||||
3000,0.56
|
||||
4000,0.72
|
||||
5000,0.91
|
|
BIN
doc/WinFsp-Performance-Testing/file_delete_test.png
Normal file
After Width: | Height: | Size: 59 KiB |
30
doc/WinFsp-Performance-Testing/file_list_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
1000,0.08
|
||||
2000,0.16
|
||||
3000,0.23
|
||||
4000,0.33
|
||||
5000,0.41
|
||||
//winfsp-t0
|
||||
1000,0.11
|
||||
2000,0.22
|
||||
3000,0.33
|
||||
4000,0.47
|
||||
5000,0.61
|
||||
//winfsp-t1
|
||||
1000,0.09
|
||||
2000,0.20
|
||||
3000,0.33
|
||||
4000,0.44
|
||||
5000,0.59
|
||||
//winfsp-tinf
|
||||
1000,0.11
|
||||
2000,0.20
|
||||
3000,0.33
|
||||
4000,0.44
|
||||
5000,0.59
|
||||
//dokany
|
||||
1000,0.16
|
||||
2000,0.36
|
||||
3000,0.64
|
||||
4000,0.97
|
||||
5000,1.38
|
|
BIN
doc/WinFsp-Performance-Testing/file_list_test.png
Normal file
After Width: | Height: | Size: 49 KiB |
30
doc/WinFsp-Performance-Testing/file_open_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
1000,0.08
|
||||
2000,0.17
|
||||
3000,0.23
|
||||
4000,0.36
|
||||
5000,0.45
|
||||
//winfsp-t0
|
||||
1000,0.06
|
||||
2000,0.11
|
||||
3000,0.27
|
||||
4000,0.22
|
||||
5000,0.28
|
||||
//winfsp-t1
|
||||
1000,0.16
|
||||
2000,0.09
|
||||
3000,0.20
|
||||
4000,0.17
|
||||
5000,0.22
|
||||
//winfsp-tinf
|
||||
1000,0.16
|
||||
2000,0.08
|
||||
3000,0.20
|
||||
4000,0.16
|
||||
5000,0.20
|
||||
//dokany
|
||||
1000,0.14
|
||||
2000,0.27
|
||||
3000,0.41
|
||||
4000,0.55
|
||||
5000,0.67
|
|
BIN
doc/WinFsp-Performance-Testing/file_open_test.png
Normal file
After Width: | Height: | Size: 55 KiB |
30
doc/WinFsp-Performance-Testing/file_overwrite_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
1000,0.19
|
||||
2000,0.36
|
||||
3000,0.72
|
||||
4000,0.97
|
||||
5000,1.14
|
||||
//winfsp-t0
|
||||
1000,0.05
|
||||
2000,0.11
|
||||
3000,0.17
|
||||
4000,0.25
|
||||
5000,0.30
|
||||
//winfsp-t1
|
||||
1000,0.05
|
||||
2000,0.08
|
||||
3000,0.16
|
||||
4000,0.17
|
||||
5000,0.22
|
||||
//winfsp-tinf
|
||||
1000,0.05
|
||||
2000,0.09
|
||||
3000,0.13
|
||||
4000,0.19
|
||||
5000,0.22
|
||||
//dokany
|
||||
1000,0.33
|
||||
2000,0.67
|
||||
3000,1.03
|
||||
4000,1.34
|
||||
5000,1.64
|
|
BIN
doc/WinFsp-Performance-Testing/file_overwrite_test.png
Normal file
After Width: | Height: | Size: 50 KiB |
30
doc/WinFsp-Performance-Testing/file_tests.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
file_create_test,1.94
|
||||
file_open_test,0.45
|
||||
file_overwrite_test,1.14
|
||||
file_list_test,0.41
|
||||
file_delete_test,1.03
|
||||
//winfsp-t0
|
||||
file_create_test,1.08
|
||||
file_open_test,0.28
|
||||
file_overwrite_test,0.30
|
||||
file_list_test,0.61
|
||||
file_delete_test,0.45
|
||||
//winfsp-t1
|
||||
file_create_test,0.95
|
||||
file_open_test,0.22
|
||||
file_overwrite_test,0.22
|
||||
file_list_test,0.59
|
||||
file_delete_test,0.34
|
||||
//winfsp-tinf
|
||||
file_create_test,0.97
|
||||
file_open_test,0.20
|
||||
file_overwrite_test,0.22
|
||||
file_list_test,0.59
|
||||
file_delete_test,0.33
|
||||
//dokany
|
||||
file_create_test,1.64
|
||||
file_open_test,0.67
|
||||
file_overwrite_test,1.64
|
||||
file_list_test,1.38
|
||||
file_delete_test,0.91
|
|
BIN
doc/WinFsp-Performance-Testing/file_tests.png
Normal file
After Width: | Height: | Size: 55 KiB |
24
doc/WinFsp-Performance-Testing/mmap_read_test.csv
Normal file
@ -0,0 +1,24 @@
|
||||
//ntfs
|
||||
100,0.19
|
||||
200,0.39
|
||||
300,0.58
|
||||
400,0.78
|
||||
500,1.06
|
||||
//winfsp-t0
|
||||
100,0.20
|
||||
200,0.39
|
||||
300,0.59
|
||||
400,0.77
|
||||
500,1.00
|
||||
//winfsp-t1
|
||||
100,0.19
|
||||
200,0.39
|
||||
300,0.59
|
||||
400,0.78
|
||||
500,0.98
|
||||
//winfsp-tinf
|
||||
100,0.20
|
||||
200,0.39
|
||||
300,0.59
|
||||
400,0.78
|
||||
500,0.98
|
|
BIN
doc/WinFsp-Performance-Testing/mmap_read_test.png
Normal file
After Width: | Height: | Size: 44 KiB |
24
doc/WinFsp-Performance-Testing/mmap_write_test.csv
Normal file
@ -0,0 +1,24 @@
|
||||
//ntfs
|
||||
100,0.16
|
||||
200,0.30
|
||||
300,0.44
|
||||
400,0.58
|
||||
500,0.72
|
||||
//winfsp-t0
|
||||
100,0.14
|
||||
200,0.30
|
||||
300,0.45
|
||||
400,0.56
|
||||
500,0.72
|
||||
//winfsp-t1
|
||||
100,0.14
|
||||
200,0.31
|
||||
300,0.44
|
||||
400,0.59
|
||||
500,0.73
|
||||
//winfsp-tinf
|
||||
100,0.16
|
||||
200,0.30
|
||||
300,0.44
|
||||
400,0.59
|
||||
500,0.73
|
|
BIN
doc/WinFsp-Performance-Testing/mmap_write_test.png
Normal file
After Width: | Height: | Size: 39 KiB |
74
doc/WinFsp-Performance-Testing/munge.py
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# usage: ./munge.py ORIG/*.csv
|
||||
# munge CSV files into a format that asciidocFX understands
|
||||
|
||||
import csv, os, sys
|
||||
|
||||
snames = ["ntfs", "winfsp-t0", "winfsp-t1", "winfsp-tinf", "dokany"]
|
||||
file_tnames = [
|
||||
"file_create_test",
|
||||
"file_open_test",
|
||||
"file_overwrite_test",
|
||||
"file_list_test",
|
||||
"file_delete_test"]
|
||||
#"file_mkdir_test",
|
||||
#"file_rmdir_test"]
|
||||
rdwr_tnames = [
|
||||
"rdwr_cc_read_page_test",
|
||||
"rdwr_cc_write_page_test",
|
||||
"rdwr_nc_read_page_test",
|
||||
"rdwr_nc_write_page_test",
|
||||
"mmap_read_test",
|
||||
"mmap_write_test"]
|
||||
tnames = file_tnames + rdwr_tnames
|
||||
aggregate = min
|
||||
|
||||
tests = {}
|
||||
for arg in sys.argv[1:]:
|
||||
name = os.path.splitext(os.path.basename(arg))[0]
|
||||
if name[-1].isdigit() and name[-2] == '-':
|
||||
name = name[:-2]
|
||||
with open(arg, "r") as fin:
|
||||
for row in csv.reader(fin):
|
||||
tests.\
|
||||
setdefault(row[0], {}).\
|
||||
setdefault(name, {}).\
|
||||
setdefault(int(row[1]), []).\
|
||||
append(float(row[2]))
|
||||
|
||||
if False:
|
||||
for tname in (tnames if tnames else sorted(tests.keys())):
|
||||
print "%s:" % tname
|
||||
test = tests[tname]
|
||||
for sname in (snames if snames else sorted(test.keys())):
|
||||
if sname not in test:
|
||||
continue
|
||||
print " %s:" % sname
|
||||
series = test[sname]
|
||||
for param in sorted(series.keys()):
|
||||
print " %s: %s -> %.2f" % (param, series[param], aggregate(series[param]))
|
||||
else:
|
||||
for tname in (tnames if tnames else sorted(tests.keys())):
|
||||
with open(tname + ".csv", "w") as fout:
|
||||
test = tests[tname]
|
||||
for sname in (snames if snames else sorted(test.keys())):
|
||||
if sname not in test:
|
||||
continue
|
||||
fout.write("//%s\r\n" % sname)
|
||||
series = test[sname]
|
||||
for param in sorted(series.keys()):
|
||||
fout.write("%s,%.2f\r\n" % (param, aggregate(series[param])))
|
||||
def master_write(fname, tnames):
|
||||
with open(fname + ".csv", "w") as fout:
|
||||
for sname in snames:
|
||||
fout.write("//%s\r\n" % sname)
|
||||
for tname in (tnames if tnames else sorted(tests.keys())):
|
||||
test = tests[tname]
|
||||
if sname not in test:
|
||||
continue
|
||||
series = test[sname]
|
||||
param = max(series.keys())
|
||||
fout.write("%s,%.2f\r\n" % (tname, aggregate(series[param])))
|
||||
master_write("file_tests", file_tnames)
|
||||
master_write("rdwr_tests", rdwr_tnames)
|
30
doc/WinFsp-Performance-Testing/rdwr_cc_read_page_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
100,0.19
|
||||
200,0.42
|
||||
300,0.61
|
||||
400,0.78
|
||||
500,0.97
|
||||
//winfsp-t0
|
||||
100,1.44
|
||||
200,2.97
|
||||
300,4.20
|
||||
400,5.64
|
||||
500,6.83
|
||||
//winfsp-t1
|
||||
100,1.47
|
||||
200,3.00
|
||||
300,4.45
|
||||
400,5.78
|
||||
500,7.33
|
||||
//winfsp-tinf
|
||||
100,0.28
|
||||
200,0.58
|
||||
300,0.87
|
||||
400,1.12
|
||||
500,1.48
|
||||
//dokany
|
||||
100,2.23
|
||||
200,4.58
|
||||
300,6.78
|
||||
400,9.02
|
||||
500,11.20
|
|
BIN
doc/WinFsp-Performance-Testing/rdwr_cc_read_page_test.png
Normal file
After Width: | Height: | Size: 55 KiB |
30
doc/WinFsp-Performance-Testing/rdwr_cc_write_page_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
100,0.25
|
||||
200,0.47
|
||||
300,0.69
|
||||
400,0.91
|
||||
500,1.19
|
||||
//winfsp-t0
|
||||
100,1.30
|
||||
200,2.63
|
||||
300,3.91
|
||||
400,5.23
|
||||
500,6.12
|
||||
//winfsp-t1
|
||||
100,1.30
|
||||
200,2.47
|
||||
300,3.89
|
||||
400,4.92
|
||||
500,6.17
|
||||
//winfsp-tinf
|
||||
100,0.34
|
||||
200,0.67
|
||||
300,1.01
|
||||
400,1.38
|
||||
500,1.70
|
||||
//dokany
|
||||
100,2.08
|
||||
200,4.23
|
||||
300,6.33
|
||||
400,8.48
|
||||
500,10.33
|
|
BIN
doc/WinFsp-Performance-Testing/rdwr_cc_write_page_test.png
Normal file
After Width: | Height: | Size: 53 KiB |
30
doc/WinFsp-Performance-Testing/rdwr_nc_read_page_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
100,9.38
|
||||
200,21.39
|
||||
300,19.56
|
||||
400,26.11
|
||||
500,33.05
|
||||
//winfsp-t0
|
||||
100,1.33
|
||||
200,2.64
|
||||
300,4.06
|
||||
400,5.42
|
||||
500,6.41
|
||||
//winfsp-t1
|
||||
100,1.38
|
||||
200,2.78
|
||||
300,4.23
|
||||
400,5.52
|
||||
500,6.94
|
||||
//winfsp-tinf
|
||||
100,1.36
|
||||
200,2.81
|
||||
300,3.95
|
||||
400,5.19
|
||||
500,6.58
|
||||
//dokany
|
||||
100,2.22
|
||||
200,4.34
|
||||
300,6.34
|
||||
400,8.67
|
||||
500,10.59
|
|
BIN
doc/WinFsp-Performance-Testing/rdwr_nc_read_page_test.png
Normal file
After Width: | Height: | Size: 50 KiB |
30
doc/WinFsp-Performance-Testing/rdwr_nc_write_page_test.csv
Normal file
@ -0,0 +1,30 @@
|
||||
//ntfs
|
||||
100,7.55
|
||||
200,14.36
|
||||
300,21.58
|
||||
400,28.52
|
||||
500,35.45
|
||||
//winfsp-t0
|
||||
100,1.30
|
||||
200,2.67
|
||||
300,3.95
|
||||
400,5.33
|
||||
500,6.41
|
||||
//winfsp-t1
|
||||
100,1.30
|
||||
200,2.61
|
||||
300,3.94
|
||||
400,5.36
|
||||
500,6.51
|
||||
//winfsp-tinf
|
||||
100,1.31
|
||||
200,2.56
|
||||
300,3.86
|
||||
400,5.11
|
||||
500,6.42
|
||||
//dokany
|
||||
100,2.20
|
||||
200,4.66
|
||||
300,6.44
|
||||
400,8.56
|
||||
500,10.73
|
|
BIN
doc/WinFsp-Performance-Testing/rdwr_nc_write_page_test.png
Normal file
After Width: | Height: | Size: 48 KiB |
33
doc/WinFsp-Performance-Testing/rdwr_tests.csv
Normal file
@ -0,0 +1,33 @@
|
||||
//ntfs
|
||||
rdwr_cc_read_page_test,0.97
|
||||
rdwr_cc_write_page_test,1.19
|
||||
rdwr_nc_read_page_test,33.05
|
||||
rdwr_nc_write_page_test,35.45
|
||||
mmap_read_test,1.06
|
||||
mmap_write_test,0.72
|
||||
//winfsp-t0
|
||||
rdwr_cc_read_page_test,6.83
|
||||
rdwr_cc_write_page_test,6.12
|
||||
rdwr_nc_read_page_test,6.41
|
||||
rdwr_nc_write_page_test,6.41
|
||||
mmap_read_test,1.00
|
||||
mmap_write_test,0.72
|
||||
//winfsp-t1
|
||||
rdwr_cc_read_page_test,7.33
|
||||
rdwr_cc_write_page_test,6.17
|
||||
rdwr_nc_read_page_test,6.94
|
||||
rdwr_nc_write_page_test,6.51
|
||||
mmap_read_test,0.98
|
||||
mmap_write_test,0.73
|
||||
//winfsp-tinf
|
||||
rdwr_cc_read_page_test,1.48
|
||||
rdwr_cc_write_page_test,1.70
|
||||
rdwr_nc_read_page_test,6.58
|
||||
rdwr_nc_write_page_test,6.42
|
||||
mmap_read_test,0.98
|
||||
mmap_write_test,0.73
|
||||
//dokany
|
||||
rdwr_cc_read_page_test,11.20
|
||||
rdwr_cc_write_page_test,10.33
|
||||
rdwr_nc_read_page_test,10.59
|
||||
rdwr_nc_write_page_test,10.73
|
|
BIN
doc/WinFsp-Performance-Testing/rdwr_tests.png
Normal file
After Width: | Height: | Size: 68 KiB |
130
doc/WinFsp-Testing.asciidoc
Normal file
@ -0,0 +1,130 @@
|
||||
= WinFsp Testing Strategy
|
||||
|
||||
WinFsp maintains quality through rigorous testing under a variety of scenarios. This document discusses its testing strategy.
|
||||
|
||||
== Importance of Testing
|
||||
|
||||
A file system is a fundamental block of an OS. It provides the primary means for storing persistent information and capturing system state. A file system must not only be reliable and stable when the computer is running, it must also store data in a manner as to eliminate data loss or data corruption. Furthermore a file system must provide semantics that closely adhere to existing standards and conventions for its OS to avoid confusion or even accidental corruption from programs that use it. For these reasons rigorous and extensive testing of a file system is of paramount importance.
|
||||
|
||||
WinFsp enables the creation of user mode file systems that fully integrate with the Windows OS. WinFsp is a system component and the user mode file systems that integrate with it also become system components. The need for thorough testing of WinFsp becomes apparent.
|
||||
|
||||
== Test Suites
|
||||
|
||||
WinFsp currently has the following test suites:
|
||||
|
||||
- *Winfsp-tests*: This test suite provides comprehensive testing of WinFsp's capabilities under various scenarios. This includes general Win32 (and NTDLL) file API testing, but also includes WinFsp specific tests, such as incorrectly functioning user mode file systems. The non-WinFsp specific tests are verified against NTFS.
|
||||
+
|
||||
This test suite is developed together with WinFsp. It is written in C/C++ and provides a form of gray box testing.
|
||||
|
||||
- *Winfstest*: This is another test suite that verifies general file system functionality. It is not WinFsp specific and all its tests pass on NTFS.
|
||||
+
|
||||
This test suite is written in Python and C and was originally developed for the secfs.test collection of file system test programs by the WinFsp author. It provides a form of black box testing.
|
||||
|
||||
- *IfsTest*: This is Microsoft's Installable File System Test Suite. It is used to verify that WinFsp behavior closely resembles that of NTFS.
|
||||
+
|
||||
This test suite is part of the Windows Hardware Lab Kit (HLK). It provides a form of black box testing.
|
||||
|
||||
- *FSX*: This is Apple's FSX ported to Windows by the WinFsp author. FSX is very good at finding problems with read/write and memory-mapped I/O.
|
||||
|
||||
- *Fscrash*: This is a tool that simulates a faulty or crashing user mode file system. It is used to test the fault tolerance of WinFsp.
|
||||
+
|
||||
This test is developed together with WinFsp. It is written in C/C++.
|
||||
|
||||
- *Fsbench*: This is a tool that can be used to test the performance of Windows file systems under different scenarios. It can work with any Windows file system and is not specific to WinFsp.
|
||||
+
|
||||
This tool is currently developed together with WinFsp. It is written in C.
|
||||
|
||||
These test suites and a few smaller tests are run through Continuous Integration testing every time a push is made into the WinFsp repository.
|
||||
|
||||
=== Test File System
|
||||
|
||||
WinFsp includes a test user mode file system called *MEMFS*. This is a simple in memory file system written in C/C++. MEMFS implements all file system features that WinFsp supports. MEMFS also performs various user mode file system checks during testing, for example, it checks that the buffer received during WRITE calls is read-only.
|
||||
|
||||
== Tested Scenarios
|
||||
|
||||
The combined test suites exercise the majority of Win32 file API's and a few NTDLL ones. The tested API's include:
|
||||
|
||||
- API's to create, open, close files/streams.
|
||||
- API's to perform file/stream I/O in cached, non-cached, write-through, overlapped, etc. modes.
|
||||
- API's to perform memory mapped I/O.
|
||||
- API's to get or set file/stream metadata and security.
|
||||
- API's to rename or delete files/streams.
|
||||
- API's to enumerate directories and streams.
|
||||
- API's that act on reparse points and symbolic links.
|
||||
|
||||
These tests are run under a variety of conditions:
|
||||
|
||||
- When the file system is a "disk" file system (+FILE_DEVICE_DISK_FILE_SYSTEM+).
|
||||
- When the file system is a "network" file system (+FILE_DEVICE_NETWORK_FILE_SYSTEM+).
|
||||
- When the file system is a "disk" file system exposed as a network share (+NetShareAdd+).
|
||||
- When the file system is mapped as a drive (+DefineDosDeviceW+).
|
||||
- When the file system is mounted on a directory (using junctions).
|
||||
- When the file system is case-sensitive or case-insensitive.
|
||||
- When the process making the API calls lacks the traverse privilege (+SE_CHANGE_NOTIFY_NAME+).
|
||||
- When the process making the API calls has the backup or restore privilege (+SE_BACKUP_NAME+, +SE_RESTORE_NAME+).
|
||||
|
||||
Not all tests apply to all conditions. The test suites will disable/skip tests that do not apply to a particular scenario.
|
||||
|
||||
In addition the tests are run both on Debug and Release builds. Debug builds includes numerous ASSERT() statements that test various conditions within the WinFsp code.
|
||||
|
||||
=== Coverage
|
||||
|
||||
Windows File System Drivers (FSD) run in a variety of conditions that are not always easy to replicate during testing. For example, an FSD may not be able to get locks to perform an operation, in which case it may retry the operation later. Or it may be unable to allocate memory for a MustSucceed task, in which case it may wait a bit and retry.
|
||||
|
||||
Such situations may not arise during normal testing. For this reason, WinFsp uses the +DEBUGTEST()+ macro, which takes a single +Percent+ argument. In Release builds this macro always evaluates to +TRUE+. In Debug builds this macro may evaluate to +TRUE+ or +FALSE+ depending on the value of the +Percent+ argument, which specifies the percentage of times that +DEBUGTEST()+ should evaluate to +TRUE+. For example, a +DEBUGTEST(90)+ means that 90% of the time the macro should evaluate to +TRUE+ and 10% of the time it should evaluate to +FALSE+.
|
||||
|
||||
The WinFsp FSD uses the +DEBUGTEST()+ macro in various places where an operation may have to be retried. For example, here is how it handles deferred writes:
|
||||
|
||||
----
|
||||
/* should we defer the write? */
|
||||
Success = DEBUGTEST(90) && CcCanIWrite(FileObject, WriteLength, CanWait, Retrying);
|
||||
if (!Success)
|
||||
{
|
||||
Result = FspWqCreateIrpWorkItem(Irp, FspFsvolWriteCached, 0);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
CcDeferWrite(FileObject, FspFsvolWriteCachedDeferred, Irp, 0, WriteLength, Retrying);
|
||||
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
/* if we are unable to defer we will go ahead and (try to) service the IRP now! */
|
||||
}
|
||||
----
|
||||
|
||||
In Release builds the +DEBUGTEST(90)+ macro will evaluate to +TRUE+ and the Cache Manager will be asked directly via +CcCanIWrite+ whether a WRITE should be deferred. In Debug builds the +DEBUGTEST(90)+ macro will evaluate to +FALSE+ sometimes (10% of the time) and the WRITE will be deferred, thus allowing us to test the retry code path.
|
||||
|
||||
== Compatibility Testing
|
||||
|
||||
WinFsp allows the creation of user mode file systems that exhibit behavior similar to NTFS. This means that Windows applications that use such a file system should not be able to tell the difference between NTFS and the WinFsp-based file system. OTOH specialized applications (such as Defrag) will not work properly on WinFsp file systems.
|
||||
|
||||
WinFsp uses the winfsp-tests, winfstest and ifstest test suites for compatibility testing. These test suites verify that WinFsp and NTFS have very similar behavior. There is a separate document that examines the differences between WinFsp and NTFS in more detail.
|
||||
|
||||
== Fault Tolerance Testing
|
||||
|
||||
User mode file systems are normal user mode processes and as such they may fail in a variety of conditions. For example, a user mode file system may trigger an access violation while servicing a file operation. As another example, the developer of a user mode file system may terminate the file system process forcefully from within a debugger.
|
||||
|
||||
In such cases WinFsp is able to recover gracefully and clean up its resources and data structures. This is a fundamental capability of WinFsp and one that must be tested thoroughly.
|
||||
|
||||
For this purpose WinFsp is tested using the fscrash tool. Fscrash includes a special version of MEMFS, where file operations can potentially cause a crash. Fscrash also includes a simple test that is run in a loop until the included file system crashes. When the OS kills the process, the WinFsp FSD steps in and cleans up all resources used by the faulty file system. The intent of the test is to verify that WinFsp handles the crash properly, without leaving any leaks and without crashing the OS.
|
||||
|
||||
== Verifier
|
||||
|
||||
All development and testing of WinFsp is done under the Driver Verifier with standard settings enabled. The Driver Verifier is an invaluable tool for Windows Driver development. It has caught numerous issues within WinFsp, in most cases immediately after the faulty code was written and run for the first time.
|
||||
|
||||
=== Leak Testing
|
||||
|
||||
One of the most important aspects of the Driver Verifier is that it can track the pool (memory) usage of WinFsp. The WinFsp master test driver uses this to confirm that the WinFsp FSD does not leak memory. At the end of the tests the master test driver unmounts any remaining WinFsp file systems and then verifies that there are zero pool allocations for the WinFsp FSD.
|
||||
|
||||
== Performance Testing
|
||||
|
||||
The goal of performance testing is to evaluate and understand how software behaves under certain workloads. Performance testing can help identify cases where the software requires too much time or resources. It is also useful to establish a performance baseline to ensure that software performance does not degrade over time.
|
||||
|
||||
WinFsp uses a tool called fsbench for this purpose. Fsbench is able to test specific scenarios, for example: "how long does it take to delete 1000 files?" Fsbench has been very useful for WinFsp and has helped improve its performance: in one situation it helped identify quadratic behavior with the MEMFS ReadDirectory operation, in another situation it helped fine tune the performance of the WinFsp I/O Queue.
|
||||
|
||||
== Code Analysis
|
||||
|
||||
WinFsp is regularly run under the Visual Studio's Code Analyzer. Any issues found are examined and if necessary acted upon.
|
||||
|
||||
WinFsp compiles cleanly without any warnings.
|
180
doc/WinFsp-as-an-IPC-Mechanism.asciidoc
Normal file
@ -0,0 +1,180 @@
|
||||
= WinFsp as an IPC Mechanism
|
||||
|
||||
WinFsp enables the creation of user mode file systems for Windows. At its core WinFsp is also an Inter-Process Communication (IPC) mechanism that uses the familiar file system interface for communication. This document discusses WinFsp from that viewpoint.
|
||||
|
||||
== Single File API Request
|
||||
|
||||
When a process uses the familiar file API to access a file on Windows, this API request gets packaged into an I/O Request Packet (IRP) and gets routed to the relevant File System Driver (FSD). The usual FSD's in Windows (NTFS, FastFat, etc.) will process the IRP and return a response to the process. For the remainder of this discussion, we will call this process the Originating Process (OP).
|
||||
|
||||
In the WinFsp case things are more complicated. WinFsp will forward IRP's to another process, which implements a user mode file system. This process will process the IRP and return a response, which WinFsp will eventually forward to the OP. We will call the process that implements the user mode file system, the File System process (FS).
|
||||
|
||||
In the following we will also use the notation [U] to denote user mode processing and [K] to denote kernel mode processing. Additionally because a Context Switch always goes through kernel mode, we will simplify the diagrams and omit this detail when it is not important.
|
||||
|
||||
Consider then what happens when an OP issues a synchronous (non-overlapped), non-cached (non-buffered) WriteFile call.
|
||||
|
||||
ifdef::env-browser[]
|
||||
[uml,file="WinFsp-as-an-IPC-Mechanism/synchronous.png"]
|
||||
--
|
||||
hide footbox
|
||||
|
||||
participant "OP[U]" as OPU
|
||||
participant "OP[K]" as OPK
|
||||
participant "FS[K]" as FSK
|
||||
participant "FS[U]" as FSU
|
||||
|
||||
activate OPU
|
||||
OPU ->OPK: WriteFile
|
||||
deactivate OPU
|
||||
activate OPK #Salmon
|
||||
OPK-->FSK: Context Switch
|
||||
deactivate OPK
|
||||
activate FSK #Salmon
|
||||
FSK ->FSU: TRANSACT Req
|
||||
deactivate FSK
|
||||
activate FSU #Salmon
|
||||
FSU ->FSU: Process
|
||||
activate FSU
|
||||
deactivate FSU
|
||||
FSU ->FSK: TRANSACT Rsp
|
||||
deactivate FSU
|
||||
activate FSK #Salmon
|
||||
FSK-->OPU: Context Switch and Return
|
||||
deactivate FSK
|
||||
activate OPU
|
||||
note over FSK, FSU #Salmon
|
||||
Salmon color denotes WinFsp processing.
|
||||
end note
|
||||
--
|
||||
endif::env-browser[]
|
||||
ifndef::env-browser[image::WinFsp-as-an-IPC-Mechanism/synchronous.png[]]
|
||||
|
||||
Let us now consider what happens when an OP issues an asynchronous (overlapped), non-cached (non-buffered) WriteFile call. This scenario does not show how the OP receives the WriteFile result.
|
||||
|
||||
ifdef::env-browser[]
|
||||
[uml,file="WinFsp-as-an-IPC-Mechanism/asynchronous.png"]
|
||||
--
|
||||
hide footbox
|
||||
|
||||
participant "OP[U]" as OPU
|
||||
participant "OP[K]" as OPK
|
||||
participant "FS[K]" as FSK
|
||||
participant "FS[U]" as FSU
|
||||
|
||||
activate OPU
|
||||
OPU ->OPK: WriteFile
|
||||
deactivate OPU
|
||||
activate OPK #Salmon
|
||||
OPK ->OPU: Return
|
||||
deactivate OPK
|
||||
activate OPU
|
||||
OPU ->OPU: Process
|
||||
activate OPU
|
||||
deactivate OPU
|
||||
OPU-->FSK: Context Switch
|
||||
deactivate OPU
|
||||
activate FSK #Salmon
|
||||
FSK ->FSU: TRANSACT Req
|
||||
deactivate FSK
|
||||
activate FSU #Salmon
|
||||
FSU ->FSU: Process
|
||||
activate FSU
|
||||
deactivate FSU
|
||||
FSU ->FSK: TRANSACT Rsp
|
||||
deactivate FSU
|
||||
activate FSK #Salmon
|
||||
FSK-->OPU: Context Switch
|
||||
deactivate FSK
|
||||
activate OPU
|
||||
note over FSK, FSU #Salmon
|
||||
Salmon color denotes WinFsp processing.
|
||||
end note
|
||||
--
|
||||
endif::env-browser[]
|
||||
ifndef::env-browser[image::WinFsp-as-an-IPC-Mechanism/asynchronous.png[]]
|
||||
|
||||
It should be noted that from the WinFsp perspective both cases look similar. WinFsp processing occurs:
|
||||
|
||||
- At *OP[K]* time immediately after receipt of an IRP. An IRP is said to be in the _Pending_ stage at this point.
|
||||
- At *FS[K]* time after a context switch, but before the TRANSACT call. An IRP is said to be in the _Prepare_ stage at this point.
|
||||
- At *FS[K]* time after the TRANSACT call. An IRP is said to be in the _Complete_ stage at this point. Upon completion of this stage the IRP will be completed and relinquished to the OS.
|
||||
- AT *FS[U]* time between the two TRANSACT calls.
|
||||
|
||||
The TRANSACT calls are DeviceIoControl requests that the FS issues to WinFsp. A single TRANSACT call can be used to communicate a file system response and retrieve the next file system request.
|
||||
|
||||
## Multiple File API Requests
|
||||
|
||||
Let us now consider what may happen with two simultaneous API Requests from two different processes. For example, two WriteFile requests for different files.
|
||||
|
||||
ifdef::env-browser[]
|
||||
[uml,file="WinFsp-as-an-IPC-Mechanism/multiple.png"]
|
||||
--
|
||||
hide footbox
|
||||
|
||||
participant "OP<sub>1</sub>[U]" as OP1U
|
||||
participant "OP<sub>1</sub>[K]" as OP1K
|
||||
participant "OP<sub>2</sub>[U]" as OP2U
|
||||
participant "OP<sub>2</sub>[K]" as OP2K
|
||||
participant "FS[K]" as FSK
|
||||
participant "FS[U]" as FSU
|
||||
|
||||
activate OP1U
|
||||
OP1U ->OP1K: WriteFile
|
||||
deactivate OP1U
|
||||
activate OP1K #Salmon
|
||||
OP1K-->OP2U: Context Switch
|
||||
deactivate OP1K
|
||||
activate OP2U
|
||||
OP2U ->OP2K: WriteFile
|
||||
deactivate OP2U
|
||||
activate OP2K #Salmon
|
||||
OP2K-->FSK: Context Switch
|
||||
deactivate OP2K
|
||||
activate FSK #Salmon
|
||||
FSK ->FSU: TRANSACT\nReq<sub>1</sub>
|
||||
deactivate FSK
|
||||
activate FSU #Salmon
|
||||
FSU ->FSU: Process
|
||||
activate FSU
|
||||
deactivate FSU
|
||||
FSU ->FSK: TRANSACT\nRsp<sub>1</sub>
|
||||
deactivate FSU
|
||||
activate FSK #Salmon
|
||||
FSK ->FSU: TRANSACT\nReq<sub>2</sub>
|
||||
deactivate FSK
|
||||
activate FSU #Salmon
|
||||
FSU ->FSU: Process
|
||||
activate FSU
|
||||
deactivate FSU
|
||||
FSU ->FSK: TRANSACT\nRsp<sub>2</sub>
|
||||
deactivate FSU
|
||||
activate FSK #Salmon
|
||||
FSK-->OP1U: Context Switch and Return
|
||||
deactivate FSK
|
||||
activate OP1U
|
||||
OP1U ->OP1U: Process
|
||||
activate OP1U
|
||||
deactivate OP1U
|
||||
OP1U-->OP2U: Context Switch and Return
|
||||
deactivate OP1U
|
||||
activate OP2U
|
||||
note over FSK, FSU #Salmon
|
||||
Salmon color denotes WinFsp processing.
|
||||
end note
|
||||
--
|
||||
endif::env-browser[]
|
||||
ifndef::env-browser[image::WinFsp-as-an-IPC-Mechanism/multiple.png[]]
|
||||
|
||||
Notice that it is possible for the FS to process multiple file system requests without context switching.
|
||||
|
||||
## I/O Queues and Performance
|
||||
|
||||
I/O Queues are the fundamental IPC mechanism in WinFsp. The purpose of the I/O Queue is to forward an IRP from the OP to the FS and when FS processing is complete to forward the response back to the OP. I/O Queues are discussed in detail in the WinFsp design document.
|
||||
|
||||
WinFsp owes its excellent performance primarily to the design of the I/O Queues. I/O Queues borrow heavily from the design of I/O completion ports and schedule threads in a similar manner:
|
||||
|
||||
- They have a Last-In First-Out (LIFO) wait discipline.
|
||||
- They limit the number of threads that can be satisfied concurrently to the number of processors.
|
||||
|
||||
The first property ensures that when an FS thread finishes processing a file system request, it will very likely pick up the next one from the I/O Queue without blocking and context switching to another FS thread. Minimizing context switches results in better performance.
|
||||
|
||||
The second property ensures that even if there are multiple file system requests waiting to be serviced in the I/O Queue, it will not schedule more thread than the number of processors. Having more than one threads scheduled on each processor is counter-productive.
|
BIN
doc/WinFsp-as-an-IPC-Mechanism/asynchronous.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
doc/WinFsp-as-an-IPC-Mechanism/multiple.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
doc/WinFsp-as-an-IPC-Mechanism/synchronous.png
Normal file
After Width: | Height: | Size: 37 KiB |
1817
doc/winfsp.h.markdown
Normal file
2
ext/test
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/callstack.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/callstack.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/callstack.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injected/allfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injected/curlfunc.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injected/curlfunc.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injected/curlfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injected/stdfunc.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injected/stdfunc.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injected/stdfunc.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injection.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/injection.h>
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/injection.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
/* NOTE: This header may usefully be included multiple times.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/testsuite.c
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#include <tlib/testsuite.h>
|
||||
@ -54,10 +54,19 @@ static char assert_buf[256];
|
||||
static void test_printf(const char *fmt, ...);
|
||||
static double run_test(struct test *test)
|
||||
{
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
unsigned long __stdcall timeGetTime(void);
|
||||
unsigned long t0 = timeGetTime();
|
||||
test->fn();
|
||||
unsigned long t1 = timeGetTime();
|
||||
return (t1 - t0) / 1000.0;
|
||||
#else
|
||||
time_t t0 = time(0);
|
||||
test->fn();
|
||||
time_t t1 = time(0);
|
||||
return difftime(t1, t0);
|
||||
#endif
|
||||
}
|
||||
static void do_test_default(struct test *test, int testno)
|
||||
{
|
||||
@ -73,7 +82,7 @@ static void do_test_default(struct test *test, int testno)
|
||||
dispname[sizeof dispname - 1] = '\0';
|
||||
test_printf("%s ", dispname);
|
||||
double d = run_test(test);
|
||||
test_printf("OK %.0fs\n", d);
|
||||
test_printf("OK %.2fs\n", d);
|
||||
}
|
||||
else
|
||||
test_printf("--- COMPLETE ---\n");
|
||||
@ -131,6 +140,11 @@ void tlib_run_tests(int argc, char *argv[])
|
||||
no_abort = 1;
|
||||
else if (0 == strcmp("--repeat-forever", a))
|
||||
repeat = ULONG_MAX;
|
||||
else if ('-' == a[1])
|
||||
{
|
||||
fprintf(stderr, "tlib_run_tests: unknown option %s\n", a);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
match_any = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file tlib/testsuite.h
|
||||
*
|
||||
* @copyright 2014-2015 Bill Zissimopoulos
|
||||
* @copyright 2014-2017 Bill Zissimopoulos
|
||||
*/
|
||||
|
||||
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
||||
|
@ -6,7 +6,7 @@
|
||||
* FUSE: Filesystem in Userspace
|
||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -6,7 +6,7 @@
|
||||
* FUSE: Filesystem in Userspace
|
||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -6,7 +6,7 @@
|
||||
* FUSE: Filesystem in Userspace
|
||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @file fuse/winfsp_fuse.h
|
||||
* WinFsp FUSE compatible API.
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file winfsp/fsctl.h
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -28,7 +28,7 @@ extern "C" {
|
||||
#if defined(WINFSP_SYS_INTERNAL) || defined(WINFSP_DLL_INTERNAL)
|
||||
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(e,m)
|
||||
#else
|
||||
#define FSP_FSCTL_STATIC_ASSERT(e,m)
|
||||
#define FSP_FSCTL_STATIC_ASSERT(e,m) static_assert(1,"")
|
||||
#endif
|
||||
|
||||
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
||||
@ -78,8 +78,6 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR),
|
||||
#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024)
|
||||
#define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX
|
||||
|
||||
#define FSP_FSCTL_TRANSACT_USERCONTEXT(s,i) (((PUINT64)&(s).UserContext)[i])
|
||||
|
||||
/* marshalling */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4200) /* zero-sized array in struct/union */
|
||||
@ -148,11 +146,12 @@ typedef struct
|
||||
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */
|
||||
UINT32 ReadOnlyVolume:1;
|
||||
/* kernel-mode flags */
|
||||
UINT32 PostCleanupOnDeleteOnly:1; /* post Cleanup when deleting a file only */
|
||||
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */
|
||||
UINT32 KmReservedFlags:5;
|
||||
/* user-mode flags */
|
||||
UINT32 UmFileNodeIsUserContext2:1; /* user mode: FileNode parameter is UserContext2 */
|
||||
UINT32 UmReservedFlags:15;
|
||||
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
||||
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
|
||||
UINT32 UmReservedFlags:14;
|
||||
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */
|
||||
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
|
||||
} FSP_FSCTL_VOLUME_PARAMS;
|
||||
@ -174,13 +173,20 @@ typedef struct
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
UINT64 IndexNumber;
|
||||
UINT32 HardLinks; /* unimplemented: set to 0 */
|
||||
} FSP_FSCTL_FILE_INFO;
|
||||
typedef struct
|
||||
{
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
PWSTR NormalizedName;
|
||||
UINT16 NormalizedNameSize;
|
||||
} FSP_FSCTL_OPEN_FILE_INFO;
|
||||
typedef struct
|
||||
{
|
||||
UINT16 Size;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
UINT64 NextOffset;
|
||||
UINT8 Padding[24];
|
||||
UINT8 Padding[16];
|
||||
/* make struct as big as FILE_ID_BOTH_DIR_INFORMATION; allows for in-place copying */
|
||||
WCHAR FileNameBuf[];
|
||||
} FSP_FSCTL_DIR_INFO;
|
||||
@ -192,6 +198,11 @@ typedef struct
|
||||
WCHAR StreamNameBuf[];
|
||||
} FSP_FSCTL_STREAM_INFO;
|
||||
typedef struct
|
||||
{
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
} FSP_FSCTL_TRANSACT_FULL_CONTEXT;
|
||||
typedef struct
|
||||
{
|
||||
UINT16 Offset;
|
||||
UINT16 Size;
|
||||
@ -212,13 +223,17 @@ typedef struct
|
||||
UINT64 AllocationSize; /* initial allocation size */
|
||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
||||
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
|
||||
FSP_FSCTL_TRANSACT_BUF Ea; /* reserved; not currently implemented */
|
||||
UINT32 UserMode:1; /* request originated in user mode */
|
||||
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
|
||||
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
|
||||
UINT32 HasRestorePrivilege:1; /* requestor has TOKEN_HAS_RESTORE_PRIVILEGE */
|
||||
UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */
|
||||
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
||||
UINT32 ReservedFlags:28;
|
||||
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
|
||||
UINT32 ReservedFlags:25;
|
||||
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
|
||||
} Create;
|
||||
struct
|
||||
@ -226,6 +241,7 @@ typedef struct
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
UINT32 FileAttributes; /* file attributes for overwritten/superseded files */
|
||||
UINT64 AllocationSize; /* allocation size for overwritten/superseded files */
|
||||
UINT32 Supersede:1; /* 0: FILE_OVERWRITE operation, 1: FILE_SUPERSEDE operation */
|
||||
} Overwrite;
|
||||
struct
|
||||
@ -233,6 +249,11 @@ typedef struct
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
UINT32 Delete:1; /* file must be deleted */
|
||||
UINT32 SetAllocationSize:1;
|
||||
UINT32 SetArchiveBit:1;
|
||||
UINT32 SetLastAccessTime:1;
|
||||
UINT32 SetLastWriteTime:1;
|
||||
UINT32 SetChangeTime:1;
|
||||
} Cleanup;
|
||||
struct
|
||||
{
|
||||
@ -280,6 +301,7 @@ typedef struct
|
||||
UINT64 CreationTime;
|
||||
UINT64 LastAccessTime;
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
} Basic;
|
||||
struct
|
||||
{
|
||||
@ -320,6 +342,7 @@ typedef struct
|
||||
UINT64 Offset;
|
||||
UINT32 Length;
|
||||
FSP_FSCTL_TRANSACT_BUF Pattern;
|
||||
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
||||
} QueryDirectory;
|
||||
struct
|
||||
{
|
||||
@ -339,7 +362,6 @@ typedef struct
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
UINT32 SecurityInformation;
|
||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
|
||||
} SetSecurity;
|
||||
struct
|
||||
@ -348,7 +370,8 @@ typedef struct
|
||||
UINT64 UserContext2;
|
||||
} QueryStreamInformation;
|
||||
} Req;
|
||||
FSP_FSCTL_TRANSACT_BUF FileName; /* {Create,Cleanup,SetInformation/{...},QueryDirectory} */
|
||||
FSP_FSCTL_TRANSACT_BUF FileName;
|
||||
/* Create,Cleanup,SetInformation{Disposition,Rename},FileSystemControl{ReparsePoint} */
|
||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||
} FSP_FSCTL_TRANSACT_REQ;
|
||||
typedef struct
|
||||
@ -373,6 +396,8 @@ typedef struct
|
||||
UINT64 UserContext2; /* user context associated with file descriptor (handle) */
|
||||
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_BUF FileName;
|
||||
UINT32 DisableCache:1;
|
||||
} Opened;
|
||||
/* IoStatus.Status == STATUS_REPARSE */
|
||||
struct
|
||||
@ -397,6 +422,10 @@ typedef struct
|
||||
FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */
|
||||
} SetInformation;
|
||||
struct
|
||||
{
|
||||
FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */
|
||||
} FlushBuffers;
|
||||
struct
|
||||
{
|
||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||
} QueryVolumeInformation;
|
||||
@ -424,6 +453,9 @@ typedef struct
|
||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||
} FSP_FSCTL_TRANSACT_RSP;
|
||||
#pragma warning(pop)
|
||||
FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX > FSP_FSCTL_TRANSACT_PATH_SIZEMAX,
|
||||
"FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX must be greater than FSP_FSCTL_TRANSACT_PATH_SIZEMAX "
|
||||
"to detect when a normalized name has been set during a Create/Open request.");
|
||||
static inline BOOLEAN FspFsctlTransactCanProduceRequest(
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, PVOID RequestBufEnd)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
* In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h>
|
||||
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -122,12 +122,49 @@ typedef enum
|
||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0,
|
||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE,
|
||||
} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY;
|
||||
enum
|
||||
{
|
||||
FspCleanupDelete = 0x01,
|
||||
FspCleanupSetAllocationSize = 0x02,
|
||||
FspCleanupSetArchiveBit = 0x10,
|
||||
FspCleanupSetLastAccessTime = 0x20,
|
||||
FspCleanupSetLastWriteTime = 0x40,
|
||||
FspCleanupSetChangeTime = 0x80,
|
||||
};
|
||||
/**
|
||||
* @class FSP_FILE_SYSTEM
|
||||
* File system interface.
|
||||
*
|
||||
* The operations in this interface must be implemented by the user mode
|
||||
* file system.
|
||||
* file system. Not all operations need be implemented. For example,
|
||||
* a user mode file system that does not wish to support reparse points,
|
||||
* need not implement the reparse point operations.
|
||||
*
|
||||
* Most of the operations accept a FileContext parameter. This parameter
|
||||
* has different meanings depending on the value of the FSP_FSCTL_VOLUME_PARAMS
|
||||
* flags UmFileContextIsUserContext2 and UmFileContextIsFullContext.
|
||||
*
|
||||
* There are three cases to consider:
|
||||
* <ul>
|
||||
* <li>When both of these flags are unset (default), the FileContext parameter
|
||||
* represents the file node. The file node is a void pointer (or an integer
|
||||
* that can fit in a pointer) that is used to uniquely identify an open file.
|
||||
* Opening the same file name should always yield the same file node value
|
||||
* for as long as the file with that name remains open anywhere in the system.
|
||||
* </li>
|
||||
* <li>When the UmFileContextIsUserContext2 is set, the FileContext parameter
|
||||
* represents the file descriptor. The file descriptor is a void pointer (or
|
||||
* an integer that can fit in a pointer) that is used to identify an open
|
||||
* instance of a file. Opening the same file name may yield a different file
|
||||
* descriptor.
|
||||
* </li>
|
||||
* <li>When the UmFileContextIsFullContext is set, the FileContext parameter
|
||||
* is a pointer to a FSP_FSCTL_TRANSACT_FULL_CONTEXT. This allows a user mode
|
||||
* file system to access the low-level UserContext and UserContext2 values.
|
||||
* The UserContext is used to store the file node and the UserContext2 is
|
||||
* used to store the file descriptor for an open file.
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
{
|
||||
@ -136,8 +173,6 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param VolumeInfo [out]
|
||||
* Pointer to a structure that will receive the volume information on successful return
|
||||
* from this call.
|
||||
@ -145,15 +180,12 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
/**
|
||||
* Set volume label.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param VolumeLabel
|
||||
* The new label for the volume.
|
||||
* @param VolumeInfo [out]
|
||||
@ -163,7 +195,6 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*SetVolumeLabel)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR VolumeLabel,
|
||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
/**
|
||||
@ -202,13 +233,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileName
|
||||
* The name of the file or directory to be created.
|
||||
* @param CaseSensitive
|
||||
* Whether to treat the FileName as case-sensitive or case-insensitive. Case-sensitive
|
||||
* file systems always treat FileName as case-sensitive regardless of this parameter.
|
||||
* @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
|
||||
@ -216,20 +242,22 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* 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.
|
||||
* Windows GetSecurityDescriptorLength API. Will be NULL for named streams.
|
||||
* @param AllocationSize
|
||||
* Allocation size for the newly created file.
|
||||
* @param PFileNode [out]
|
||||
* Pointer that will receive the file node on successful return from this call. The file
|
||||
* node is a void pointer (or an integer that can fit in a pointer) that is used to
|
||||
* uniquely identify an open file. Opening the same file name should always return the same
|
||||
* file node value for as long as the file with that name remains open anywhere in the
|
||||
* system. The file system can place any value it needs here.
|
||||
* @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.
|
||||
@ -237,34 +265,30 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*Create)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Open a file or directory.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileName
|
||||
* The name of the file or directory to be opened.
|
||||
* @param CaseSensitive
|
||||
* Whether to treat the FileName as case-sensitive or case-insensitive. Case-sensitive
|
||||
* file systems always treat FileName as case-sensitive regardless of this parameter.
|
||||
* @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 typically
|
||||
* do not need to do anything special with respect to this parameter. 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 PFileNode [out]
|
||||
* Pointer that will receive the file node on successful return from this call. The file
|
||||
* node is a void pointer (or an integer that can fit in a pointer) that is used to
|
||||
* uniquely identify an open file. Opening the same file name should always return the same
|
||||
* file node value for as long as the file with that name remains open anywhere in the
|
||||
* system. The file system can place any value it needs here.
|
||||
* @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 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.
|
||||
@ -272,23 +296,22 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*Open)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Overwrite a file.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file to overwrite.
|
||||
* @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 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.
|
||||
@ -296,8 +319,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*Overwrite)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes,
|
||||
PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Cleanup a file.
|
||||
@ -309,60 +331,72 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* the system sends a Cleanup request to the file system.
|
||||
*
|
||||
* There will be a Cleanup operation for every Create or Open operation posted to the user mode
|
||||
* file system. However the Cleanup operation is <b>not</b> the final close operation on a file. The
|
||||
* file system must be ready to receive additional operations until close time. This is true
|
||||
* file system. However the Cleanup operation is <b>not</b> the final close operation on a file.
|
||||
* The file system must be ready to receive additional operations until close time. This is true
|
||||
* even when the file is being deleted!
|
||||
*
|
||||
* The Flags parameter contains information about the cleanup operation:
|
||||
* <ul>
|
||||
* <li>FspCleanupDelete -
|
||||
* An important function of the Cleanup operation is to complete a delete operation. Deleting
|
||||
* a file or directory in Windows is a three-stage process where the file is first opened, then
|
||||
* tested to see if the delete can proceed and if the answer is positive the file is then
|
||||
* deleted during Cleanup.
|
||||
*
|
||||
* When this flag is set, this is the last outstanding cleanup for this particular file node.
|
||||
* </li>
|
||||
* <li>FspCleanupSetAllocationSize -
|
||||
* The NTFS and FAT file systems reset a file's allocation size when they receive the last
|
||||
* outstanding cleanup for a particular file node. User mode file systems that implement
|
||||
* allocation size and wish to duplicate the NTFS and FAT behavior can use this flag.
|
||||
* </li>
|
||||
* <li>
|
||||
* FspCleanupSetArchiveBit -
|
||||
* File systems that support the archive bit should set the file node's archive bit when this
|
||||
* flag is set.
|
||||
* </li>
|
||||
* <li>FspCleanupSetLastAccessTime, FspCleanupSetLastWriteTime, FspCleanupSetChangeTime - File
|
||||
* systems should set the corresponding file time when each one of these flags is set. Note that
|
||||
* updating the last access time is expensive and a file system may choose to not implement it.
|
||||
* </ul>
|
||||
*
|
||||
* There is no way to report failure of this operation. This is a Windows limitation.
|
||||
*
|
||||
* As an optimization a file system may specify the FSP_FSCTL_VOLUME_PARAMS ::
|
||||
* PostCleanupOnDeleteOnly flag. In this case the FSD will only post Cleanup requests when a
|
||||
* file is being deleted.
|
||||
* PostCleanupWhenModifiedOnly flag. In this case the FSD will only post Cleanup requests when
|
||||
* the file was modified/deleted.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to cleanup.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to cleanup.
|
||||
* @param FileName
|
||||
* The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
||||
* @param Delete
|
||||
* Determines whether to delete the file. Note that there is no way to report failure of
|
||||
* this operation. Also note that when this parameter is TRUE this is the last outstanding
|
||||
* cleanup for this particular file node.
|
||||
* @param Flags
|
||||
* These flags determine whether the file was modified and whether to delete the file.
|
||||
* @see
|
||||
* Close
|
||||
* CanDelete
|
||||
*/
|
||||
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PWSTR FileName, BOOLEAN Delete);
|
||||
PVOID FileContext, PWSTR FileName, ULONG Flags);
|
||||
/**
|
||||
* Close a file.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to be closed.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to be closed.
|
||||
*/
|
||||
VOID (*Close)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode);
|
||||
PVOID FileContext);
|
||||
/**
|
||||
* Read a file.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file to be read.
|
||||
* @param FileContext
|
||||
* The file context of the file to be read.
|
||||
* @param Buffer
|
||||
* Pointer to a buffer that will receive the results of the read operation.
|
||||
* @param Offset
|
||||
@ -376,18 +410,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* operation.
|
||||
*/
|
||||
NTSTATUS (*Read)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PULONG PBytesTransferred);
|
||||
/**
|
||||
* Write a file.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file to be written.
|
||||
* @param FileContext
|
||||
* The file context of the file to be written.
|
||||
* @param Buffer
|
||||
* Pointer to a buffer that contains the data to write.
|
||||
* @param Offset
|
||||
@ -409,8 +440,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* operation.
|
||||
*/
|
||||
NTSTATUS (*Write)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
|
||||
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
@ -420,25 +450,25 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file to be flushed. When NULL the whole volume is being flushed.
|
||||
* @param FileContext
|
||||
* The file context of the file to be flushed. When NULL the whole volume is being flushed.
|
||||
* @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. Used when
|
||||
* flushing file (not volume).
|
||||
* @return
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode);
|
||||
PVOID FileContext,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Get file or directory information.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to get information for.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to get information for.
|
||||
* @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.
|
||||
@ -446,18 +476,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*GetFileInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Set file or directory basic information.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to set information for.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to set information for.
|
||||
* @param FileAttributes
|
||||
* File attributes to apply to the file or directory. If the value INVALID_FILE_ATTRIBUTES
|
||||
* is sent, the file attributes should not be changed.
|
||||
@ -470,6 +497,9 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* @param LastWriteTime
|
||||
* Last write time to apply to the file or directory. If the value 0 is sent, the last
|
||||
* write time should not be changed.
|
||||
* @param ChangeTime
|
||||
* Change time to apply to the file or directory. If the value 0 is sent, the change time
|
||||
* should not be changed.
|
||||
* @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.
|
||||
@ -477,9 +507,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT32 FileAttributes,
|
||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
|
||||
PVOID FileContext, UINT32 FileAttributes,
|
||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Set file/allocation size.
|
||||
@ -503,10 +532,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file to set the file/allocation size for.
|
||||
* @param FileContext
|
||||
* The file context of the file to set the file/allocation size for.
|
||||
* @param NewSize
|
||||
* New file/allocation size to apply to the file.
|
||||
* @param SetAllocationSize
|
||||
@ -518,8 +545,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*SetFileSize)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT64 NewSize, BOOLEAN SetAllocationSize,
|
||||
PVOID FileContext, UINT64 NewSize, BOOLEAN SetAllocationSize,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||
/**
|
||||
* Determine whether a file or directory can be deleted.
|
||||
@ -529,17 +555,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* directories, etc.
|
||||
*
|
||||
* This function should <b>NEVER</b> delete the file or directory in question. Deletion should
|
||||
* happen during Cleanup with Delete==TRUE.
|
||||
* happen during Cleanup with the FspCleanupDelete flag set.
|
||||
*
|
||||
* This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
|
||||
* It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to test for deletion.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to test for deletion.
|
||||
* @param FileName
|
||||
* The name of the file or directory to test for deletion.
|
||||
* @return
|
||||
@ -548,15 +572,12 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* Cleanup
|
||||
*/
|
||||
NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PWSTR FileName);
|
||||
PVOID FileContext, PWSTR FileName);
|
||||
/**
|
||||
* Renames a file or directory.
|
||||
*
|
||||
* The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
||||
* <ul>
|
||||
* <li>A file cannot be renamed if it has any open handles, other than the one used to perform
|
||||
* the rename.</li>
|
||||
* <li>A file cannot be renamed if a file with the same name exists and has open handles.</li>
|
||||
* <li>A directory cannot be renamed if it or any of its subdirectories contains a file that
|
||||
* has open handles.</li>
|
||||
@ -564,10 +585,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to be renamed.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to be renamed.
|
||||
* @param FileName
|
||||
* The current name of the file or directory to rename.
|
||||
* @param NewFileName
|
||||
@ -578,16 +597,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*Rename)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists);
|
||||
/**
|
||||
* Get file or directory security descriptor.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to get the security descriptor for.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to get the security descriptor for.
|
||||
* @param SecurityDescriptor
|
||||
* Pointer to a buffer that will receive the file security descriptor on successful return
|
||||
* from this call. May be NULL.
|
||||
@ -599,44 +617,54 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize);
|
||||
/**
|
||||
* Set file or directory security descriptor.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to set the security descriptor for.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to set the security descriptor for.
|
||||
* @param SecurityInformation
|
||||
* Indicates what part of the file or directory security descriptor to change.
|
||||
* @param SecurityDescriptor
|
||||
* Security descriptor to apply to the file or directory. This security descriptor will
|
||||
* always be in self-relative format.
|
||||
* Describes what parts of the file or directory security descriptor should
|
||||
* be modified.
|
||||
* @param ModificationDescriptor
|
||||
* Describes the modifications to apply to the file or directory security descriptor.
|
||||
* @return
|
||||
* STATUS_SUCCESS or error code.
|
||||
* @see
|
||||
* FspSetSecurityDescriptor
|
||||
* FspDeleteSecurityDescriptor
|
||||
*/
|
||||
NTSTATUS (*SetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||
PVOID FileContext,
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor);
|
||||
/**
|
||||
* Read a directory.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the directory to be read.
|
||||
* @param FileContext
|
||||
* The file context of the directory to be read.
|
||||
* @param Buffer
|
||||
* Pointer to a buffer that will receive the results of the read operation.
|
||||
* @param Offset
|
||||
* Offset within the directory to read from. The kernel does not interpret this value
|
||||
* which is used solely by the file system to locate directory entries. However the
|
||||
* special value 0 indicates that the read should start from the first entries. The first
|
||||
* two entries returned by ReadDirectory should always be the "." and ".." entries.
|
||||
* two entries returned by ReadDirectory should always be the "." and ".." entries,
|
||||
* except for the root directory which does not have these entries.
|
||||
*
|
||||
* This parameter is used by the WinFsp FSD to break directory listings into chunks.
|
||||
* In this case all 64-bits of the Offset are valid. In some cases the Windows kernel
|
||||
* (NTOS) may also use this parameter. In this case only the lower 32-bits of this
|
||||
* parameter will be valid. This is an unfortunate limitation of Windows (for more
|
||||
* information see the documentation for IRP_MJ_DIRECTORY_CONTROL and the flag
|
||||
* SL_INDEX_SPECIFIED).
|
||||
*
|
||||
* In practice this means that you should only rely on the lower 32-bits of this value
|
||||
* to be valid.
|
||||
* @param Length
|
||||
* Length of data to read.
|
||||
* @param Pattern
|
||||
@ -652,8 +680,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* FspFileSystemAddDirInfo
|
||||
*/
|
||||
NTSTATUS (*ReadDirectory)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PVOID FileContext, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PWSTR Pattern,
|
||||
PULONG PBytesTransferred);
|
||||
/**
|
||||
@ -705,10 +732,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the reparse point.
|
||||
* @param FileContext
|
||||
* The file context of the reparse point.
|
||||
* @param FileName
|
||||
* The file name of the reparse point.
|
||||
* @param Buffer
|
||||
@ -723,18 +748,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* SetReparsePoint
|
||||
*/
|
||||
NTSTATUS (*GetReparsePoint)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
PWSTR FileName, PVOID Buffer, PSIZE_T PSize);
|
||||
/**
|
||||
* Set reparse point.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the reparse point.
|
||||
* @param FileContext
|
||||
* The file context of the reparse point.
|
||||
* @param FileName
|
||||
* The file name of the reparse point.
|
||||
* @param Buffer
|
||||
@ -748,18 +770,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* GetReparsePoint
|
||||
*/
|
||||
NTSTATUS (*SetReparsePoint)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
PWSTR FileName, PVOID Buffer, SIZE_T Size);
|
||||
/**
|
||||
* Delete reparse point.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the reparse point.
|
||||
* @param FileContext
|
||||
* The file context of the reparse point.
|
||||
* @param FileName
|
||||
* The file name of the reparse point.
|
||||
* @param Buffer
|
||||
@ -770,18 +789,15 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* STATUS_SUCCESS or error code.
|
||||
*/
|
||||
NTSTATUS (*DeleteReparsePoint)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PVOID FileContext,
|
||||
PWSTR FileName, PVOID Buffer, SIZE_T Size);
|
||||
/**
|
||||
* Get named streams information.
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system on which this request is posted.
|
||||
* @param Request
|
||||
* The request posted by the kernel mode FSD.
|
||||
* @param FileNode
|
||||
* The file node of the file or directory to get stream information for.
|
||||
* @param FileContext
|
||||
* The file context of the file or directory to get stream information for.
|
||||
* @param Buffer
|
||||
* Pointer to a buffer that will receive the stream information.
|
||||
* @param Length
|
||||
@ -794,8 +810,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
||||
* FspFileSystemAddStreamInfo
|
||||
*/
|
||||
NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, ULONG Length,
|
||||
PVOID FileContext, PVOID Buffer, ULONG Length,
|
||||
PULONG PBytesTransferred);
|
||||
|
||||
/*
|
||||
@ -823,8 +838,13 @@ typedef struct _FSP_FILE_SYSTEM
|
||||
UINT32 DebugLog;
|
||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
|
||||
SRWLOCK OpGuardLock;
|
||||
BOOLEAN UmFileNodeIsUserContext2;
|
||||
BOOLEAN UmFileContextIsUserContext2, UmFileContextIsFullContext;
|
||||
} FSP_FILE_SYSTEM;
|
||||
typedef struct _FSP_FILE_SYSTEM_OPERATION_CONTEXT
|
||||
{
|
||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||
FSP_FSCTL_TRANSACT_RSP *Response;
|
||||
} FSP_FILE_SYSTEM_OPERATION_CONTEXT;
|
||||
/**
|
||||
* Create a file system object.
|
||||
*
|
||||
@ -855,9 +875,13 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem);
|
||||
/**
|
||||
* Set the mount point for a file system.
|
||||
*
|
||||
* This function currently only supports drive letters (X:) as mount points. Refer to the
|
||||
* documentation of the DefineDosDevice Windows API to better understand how drive letters are
|
||||
* created.
|
||||
* This function supports drive letters (X:) or directories as mount points:
|
||||
* <ul>
|
||||
* <li>Drive letters: Refer to the documentation of the DefineDosDevice Windows API
|
||||
* to better understand how they are created.</li>
|
||||
* <li>Directories: They can be used as mount points for disk based file systems. They cannot
|
||||
* be used for network file systems. This is a limitation that Windows imposes on junctions.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param FileSystem
|
||||
* The file system object.
|
||||
@ -920,6 +944,17 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem);
|
||||
*/
|
||||
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_RSP *Response);
|
||||
/**
|
||||
* Get the current operation context.
|
||||
*
|
||||
* This function may be used only when servicing one of the FSP_FILE_SYSTEM_INTERFACE operations.
|
||||
* The current operation context is stored in thread local storage. It allows access to the
|
||||
* Request and Response associated with this operation.
|
||||
*
|
||||
* @return
|
||||
* The current operation context.
|
||||
*/
|
||||
FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID);
|
||||
static inline
|
||||
PWSTR FspFileSystemMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||
{
|
||||
@ -996,6 +1031,14 @@ VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
FileSystem->DebugLog = DebugLog;
|
||||
}
|
||||
static inline
|
||||
BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
|
||||
{
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request;
|
||||
return
|
||||
FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive ||
|
||||
FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive;
|
||||
}
|
||||
|
||||
/*
|
||||
* Operations
|
||||
@ -1040,6 +1083,54 @@ FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSyst
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
/**
|
||||
* Get open information buffer.
|
||||
*
|
||||
* This is a helper for implementing the Create and Open operations. It cannot be used with
|
||||
* any other operations.
|
||||
*
|
||||
* The FileInfo parameter to Create and Open is typed as pointer to FSP_FSCTL_FILE_INFO. The
|
||||
* true type of this parameter is pointer to FSP_FSCTL_OPEN_FILE_INFO. This simple function
|
||||
* converts from one type to the other.
|
||||
*
|
||||
* The FSP_FSCTL_OPEN_FILE_INFO type contains a FSP_FSCTL_FILE_INFO as well as the fields
|
||||
* NormalizedName and NormalizedNameSize. These fields can be used for file name normalization.
|
||||
* File name normalization is used to ensure that the FSD and the OS know the correct case
|
||||
* of a newly opened file name.
|
||||
*
|
||||
* For case-sensitive file systems this functionality should be ignored. The FSD will always
|
||||
* assume that the normalized file name is the same as the file name used to open the file.
|
||||
*
|
||||
* For case-insensitive file systems this functionality may be ignored. In this case the FSD
|
||||
* will assume that the normalized file name is the upper case version of the file name used
|
||||
* to open the file. The file system will work correctly and the only way an application will
|
||||
* be able to tell that the file system does not preserve case in normalized file names is by
|
||||
* issuing a GetFinalPathNameByHandle API call (or NtQueryInformationFile with
|
||||
* FileNameInformation/FileNormalizedNameInformation).
|
||||
*
|
||||
* For case-insensitive file systems this functionality may also be used. In this case the
|
||||
* user mode file system may use the NormalizedName and NormalizedNameSize parameters to
|
||||
* report to the FSD the normalized file name. It should be noted that the normalized file
|
||||
* name may only differ in case from the file name used to open the file. The NormalizedName
|
||||
* field will point to a buffer that can receive the normalized file name. The
|
||||
* NormalizedNameSize field will contain the size of the normalized file name buffer. On
|
||||
* completion of the Create or Open operation it should contain the actual size of the
|
||||
* normalized file name copied into the normalized file name buffer. The normalized file name
|
||||
* should not contain a terminating zero.
|
||||
*
|
||||
* @param FileInfo
|
||||
* The FileInfo parameter as passed to Create or Open operation.
|
||||
* @return
|
||||
* A pointer to the open information buffer for this Create or Open operation.
|
||||
* @see
|
||||
* Create
|
||||
* Open
|
||||
*/
|
||||
static inline
|
||||
FSP_FSCTL_OPEN_FILE_INFO *FspFileSystemGetOpenFileInfo(FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
return (FSP_FSCTL_OPEN_FILE_INFO *)FileInfo;
|
||||
}
|
||||
/**
|
||||
* Add directory information to a buffer.
|
||||
*
|
||||
@ -1214,10 +1305,49 @@ FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||
FSP_API NTSTATUS FspSetSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
/**
|
||||
* Modify security descriptor.
|
||||
*
|
||||
* This is a helper for implementing the SetSecurity operation.
|
||||
*
|
||||
* @param InputDescriptor
|
||||
* The input security descriptor to be modified.
|
||||
* @param SecurityInformation
|
||||
* Describes what parts of the InputDescriptor should be modified. This should contain
|
||||
* the same value passed to the SetSecurity SecurityInformation parameter.
|
||||
* @param ModificationDescriptor
|
||||
* Describes the modifications to apply to the InputDescriptor. This should contain
|
||||
* the same value passed to the SetSecurity ModificationDescriptor parameter.
|
||||
* @param PSecurityDescriptor [out]
|
||||
* Pointer to a memory location that will receive the resulting security descriptor.
|
||||
* This security descriptor can be later freed using FspDeleteSecurityDescriptor.
|
||||
* @return
|
||||
* STATUS_SUCCESS or error code.
|
||||
* @see
|
||||
* SetSecurity
|
||||
* FspDeleteSecurityDescriptor
|
||||
*/
|
||||
FSP_API NTSTATUS FspSetSecurityDescriptor(
|
||||
PSECURITY_DESCRIPTOR InputDescriptor,
|
||||
SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR ModificationDescriptor,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||
/**
|
||||
* Delete security descriptor.
|
||||
*
|
||||
* This is a helper for implementing the SetSecurity operation.
|
||||
*
|
||||
* @param SecurityDescriptor
|
||||
* The security descriptor to be deleted.
|
||||
* @param CreateFunc
|
||||
* Function used to create the security descriptor. This parameter should be
|
||||
* set to FspSetSecurityDescriptor for the public API.
|
||||
* @return
|
||||
* STATUS_SUCCESS or error code.
|
||||
* @see
|
||||
* SetSecurity
|
||||
* FspSetSecurityDescriptor
|
||||
*/
|
||||
FSP_API VOID FspDeleteSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||
NTSTATUS (*CreateFunc)());
|
||||
static inline
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file cygfuse/cygfuse.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/debug.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -299,12 +299,16 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
||||
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
|
||||
&Sddl, 0);
|
||||
FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c] \"%S\", "
|
||||
FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c%c%c] \"%S\", "
|
||||
"%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, "
|
||||
"AllocationSize=%lx:%lx, AccessToken=%p, DesiredAccess=%lx, ShareAccess=%lx\n",
|
||||
"AllocationSize=%lx:%lx, "
|
||||
"AccessToken=%p, DesiredAccess=%lx, GrantedAccess=%lx, "
|
||||
"ShareAccess=%lx\n",
|
||||
FspDiagIdent(), GetCurrentThreadId(), Request->Hint,
|
||||
Request->Req.Create.UserMode ? 'U' : 'K',
|
||||
Request->Req.Create.HasTraversePrivilege ? 'T' : '-',
|
||||
Request->Req.Create.HasBackupPrivilege ? 'B' : '-',
|
||||
Request->Req.Create.HasRestorePrivilege ? 'R' : '-',
|
||||
Request->Req.Create.OpenTargetDirectory ? 'D' : '-',
|
||||
Request->Req.Create.CaseSensitive ? 'C' : '-',
|
||||
(PWSTR)Request->Buffer,
|
||||
@ -317,6 +321,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
||||
MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize),
|
||||
(PVOID)Request->Req.Create.AccessToken,
|
||||
Request->Req.Create.DesiredAccess,
|
||||
Request->Req.Create.GrantedAccess,
|
||||
Request->Req.Create.ShareAccess);
|
||||
LocalFree(Sddl);
|
||||
break;
|
||||
@ -598,7 +603,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
||||
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
|
||||
&Sddl, 0);
|
||||
FspDebugLog("%S[TID=%04lx]: %p: >>SetSecurity %s%S%s%s, "
|
||||
"SecurityInformation=%lx, AccessToken=%p, Security=%s%s%s\n",
|
||||
"SecurityInformation=%lx, Security=%s%s%s\n",
|
||||
FspDiagIdent(), GetCurrentThreadId(), Request->Hint,
|
||||
Request->FileName.Size ? "\"" : "",
|
||||
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
|
||||
@ -607,12 +612,21 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
||||
Request->Req.SetSecurity.UserContext, Request->Req.SetSecurity.UserContext2,
|
||||
UserContextBuf),
|
||||
Request->Req.SetSecurity.SecurityInformation,
|
||||
(PVOID)Request->Req.SetSecurity.AccessToken,
|
||||
Sddl ? "\"" : "",
|
||||
Sddl ? Sddl : "NULL",
|
||||
Sddl ? "\"" : "");
|
||||
LocalFree(Sddl);
|
||||
break;
|
||||
case FspFsctlTransactQueryStreamInformationKind:
|
||||
FspDebugLog("%S[TID=%04lx]: %p: >>QueryStreamInformation %s%S%s%s\n",
|
||||
FspDiagIdent(), GetCurrentThreadId(), Request->Hint,
|
||||
Request->FileName.Size ? "\"" : "",
|
||||
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
|
||||
Request->FileName.Size ? "\", " : "",
|
||||
FspDebugLogUserContextString(
|
||||
Request->Req.QueryStreamInformation.UserContext, Request->Req.QueryStreamInformation.UserContext2,
|
||||
UserContextBuf));
|
||||
break;
|
||||
default:
|
||||
FspDebugLogRequestVoid(Request, "INVALID");
|
||||
break;
|
||||
@ -815,6 +829,9 @@ FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
LocalFree(Sddl);
|
||||
}
|
||||
break;
|
||||
case FspFsctlTransactQueryStreamInformationKind:
|
||||
FspDebugLogResponseStatus(Response, "QueryStreamInformation");
|
||||
break;
|
||||
default:
|
||||
FspDebugLogResponseStatus(Response, "INVALID");
|
||||
break;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/eventlog.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
268
src/dll/fs.c
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fs.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -25,6 +25,7 @@ enum
|
||||
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
|
||||
|
||||
static INIT_ONCE FspFileSystemInitOnce = INIT_ONCE_STATIC_INIT;
|
||||
static DWORD FspFileSystemTlsKey = TLS_OUT_OF_INDEXES;
|
||||
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
|
||||
PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
|
||||
static NTSTATUS (NTAPI *FspNtMakeTemporaryObject)(
|
||||
@ -37,6 +38,8 @@ static BOOL WINAPI FspFileSystemInitialize(
|
||||
{
|
||||
HANDLE Handle;
|
||||
|
||||
FspFileSystemTlsKey = TlsAlloc();
|
||||
|
||||
Handle = GetModuleHandleW(L"ntdll.dll");
|
||||
if (0 != Handle)
|
||||
{
|
||||
@ -55,6 +58,20 @@ static BOOL WINAPI FspFileSystemInitialize(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID FspFileSystemFinalize(BOOLEAN Dynamic)
|
||||
{
|
||||
/*
|
||||
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
|
||||
* finalization tasks to a minimum.
|
||||
*
|
||||
* We must free our TLS key (if any). We only do so if the library
|
||||
* is being explicitly unloaded (rather than the process exiting).
|
||||
*/
|
||||
|
||||
if (Dynamic && TLS_OUT_OF_INDEXES != FspFileSystemTlsKey)
|
||||
TlsFree(FspFileSystemTlsKey);
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||
const FSP_FILE_SYSTEM_INTERFACE *Interface,
|
||||
@ -65,10 +82,16 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||
|
||||
*PFileSystem = 0;
|
||||
|
||||
if (VolumeParams->UmFileContextIsUserContext2 &&
|
||||
VolumeParams->UmFileContextIsFullContext)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (0 == Interface)
|
||||
Interface = &FspFileSystemNullInterface;
|
||||
|
||||
InitOnceExecuteOnce(&FspFileSystemInitOnce, FspFileSystemInitialize, 0, 0);
|
||||
if (TLS_OUT_OF_INDEXES == FspFileSystemTlsKey)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
FileSystem = MemAlloc(sizeof *FileSystem);
|
||||
if (0 == FileSystem)
|
||||
@ -107,7 +130,8 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
||||
FileSystem->EnterOperation = FspFileSystemOpEnter;
|
||||
FileSystem->LeaveOperation = FspFileSystemOpLeave;
|
||||
|
||||
FileSystem->UmFileNodeIsUserContext2 = !!VolumeParams->UmFileNodeIsUserContext2;
|
||||
FileSystem->UmFileContextIsUserContext2 = !!VolumeParams->UmFileContextIsUserContext2;
|
||||
FileSystem->UmFileContextIsFullContext = !!VolumeParams->UmFileContextIsFullContext;
|
||||
|
||||
*PFileSystem = FileSystem;
|
||||
|
||||
@ -121,6 +145,168 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
|
||||
MemFree(FileSystem);
|
||||
}
|
||||
|
||||
static NTSTATUS FspFileSystemSetMountPoint_CreateDirectory(PWSTR MountPoint, PWSTR VolumeName)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
HANDLE DirHandle;
|
||||
BOOL Success;
|
||||
DWORD Backslashes, Bytes;
|
||||
USHORT VolumeNameLength, BackslashLength, ReparseDataLength;
|
||||
PREPARSE_DATA_BUFFER ReparseData = 0;
|
||||
PWSTR P, PathBuffer;
|
||||
|
||||
/*
|
||||
* Windows does not allow mount points (junctions) to point to network file systems.
|
||||
*
|
||||
* Count how many backslashes our VolumeName. If it is 3 or more this is a network
|
||||
* file system. Preemptively return STATUS_NETWORK_ACCESS_DENIED.
|
||||
*/
|
||||
for (P = VolumeName, Backslashes = 0; *P; P++)
|
||||
if (L'\\' == *P)
|
||||
if (3 == ++Backslashes)
|
||||
{
|
||||
Result = STATUS_NETWORK_ACCESS_DENIED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!CreateDirectoryW(MountPoint, 0))
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DirHandle = CreateFileW(MountPoint,
|
||||
FILE_WRITE_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
||||
0);
|
||||
if (INVALID_HANDLE_VALUE == DirHandle)
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto rmdir_and_exit;
|
||||
}
|
||||
|
||||
VolumeNameLength = (USHORT)lstrlenW(VolumeName);
|
||||
BackslashLength = 0 == VolumeNameLength || L'\\' != VolumeName[VolumeNameLength - 1];
|
||||
VolumeNameLength *= sizeof(WCHAR);
|
||||
BackslashLength *= sizeof(WCHAR);
|
||||
|
||||
ReparseDataLength = (USHORT)(
|
||||
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) -
|
||||
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)) +
|
||||
2 * (VolumeNameLength + BackslashLength + sizeof(WCHAR));
|
||||
ReparseData = MemAlloc(REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataLength);
|
||||
if (0 == ReparseData)
|
||||
{
|
||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto rmdir_and_exit;
|
||||
}
|
||||
|
||||
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
ReparseData->ReparseDataLength = ReparseDataLength;
|
||||
ReparseData->Reserved = 0;
|
||||
ReparseData->MountPointReparseBuffer.SubstituteNameOffset = 0;
|
||||
ReparseData->MountPointReparseBuffer.SubstituteNameLength =
|
||||
VolumeNameLength + BackslashLength;
|
||||
ReparseData->MountPointReparseBuffer.PrintNameOffset =
|
||||
ReparseData->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
|
||||
ReparseData->MountPointReparseBuffer.PrintNameLength =
|
||||
VolumeNameLength + BackslashLength;
|
||||
|
||||
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer;
|
||||
memcpy(PathBuffer, VolumeName, VolumeNameLength);
|
||||
if (BackslashLength)
|
||||
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
|
||||
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer +
|
||||
(ReparseData->MountPointReparseBuffer.PrintNameOffset) / sizeof(WCHAR);
|
||||
memcpy(PathBuffer, VolumeName, VolumeNameLength);
|
||||
if (BackslashLength)
|
||||
PathBuffer[VolumeNameLength / sizeof(WCHAR)] = L'\\';
|
||||
PathBuffer[(VolumeNameLength + BackslashLength) / sizeof(WCHAR)] = L'\0';
|
||||
|
||||
Success = DeviceIoControl(DirHandle, FSCTL_SET_REPARSE_POINT,
|
||||
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
|
||||
0, 0,
|
||||
&Bytes, 0);
|
||||
CloseHandle(DirHandle);
|
||||
if (!Success)
|
||||
{
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
goto rmdir_and_exit;
|
||||
}
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
MemFree(ReparseData);
|
||||
return Result;
|
||||
|
||||
rmdir_and_exit:
|
||||
RemoveDirectoryW(MountPoint);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFileSystemSetMountPoint_MakeTemporary(PWSTR MountPoint, PHANDLE PMountHandle)
|
||||
{
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
HANDLE MountHandle = 0;
|
||||
|
||||
if (FspPathIsDrive(MountPoint))
|
||||
{
|
||||
if (0 != FspNtOpenSymbolicLinkObject)
|
||||
{
|
||||
WCHAR SymlinkBuf[6];
|
||||
UNICODE_STRING Symlink;
|
||||
OBJECT_ATTRIBUTES Obja;
|
||||
|
||||
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||
SymlinkBuf[4] = MountPoint[0];
|
||||
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||
Symlink.Buffer = SymlinkBuf;
|
||||
|
||||
memset(&Obja, 0, sizeof Obja);
|
||||
Obja.Length = sizeof Obja;
|
||||
Obja.ObjectName = &Symlink;
|
||||
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
|
||||
Result = FspNtOpenSymbolicLinkObject(&MountHandle, DELETE, &Obja);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
Result = FspNtMakeTemporaryObject(MountHandle);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspNtClose(MountHandle);
|
||||
MountHandle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* open the directory for DELETE_ON_CLOSE; closing it will remove the directory */
|
||||
MountHandle = CreateFileW(MountPoint,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
0);
|
||||
if (INVALID_HANDLE_VALUE == MountHandle)
|
||||
{
|
||||
MountHandle = 0;
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
*PMountHandle = MountHandle;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR MountPoint)
|
||||
{
|
||||
if (0 != FileSystem->MountPoint)
|
||||
@ -163,9 +349,7 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
||||
PWSTR P;
|
||||
ULONG L;
|
||||
|
||||
for (P = MountPoint; *P; P++)
|
||||
;
|
||||
L = (ULONG)((P - MountPoint + 1) * sizeof(WCHAR));
|
||||
L = (ULONG)((lstrlenW(MountPoint) + 1) * sizeof(WCHAR));
|
||||
|
||||
P = MemAlloc(L);
|
||||
if (0 == P)
|
||||
@ -173,46 +357,23 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M
|
||||
memcpy(P, MountPoint, L);
|
||||
MountPoint = P;
|
||||
|
||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
||||
Result = STATUS_SUCCESS;
|
||||
if (FspPathIsDrive(MountPoint))
|
||||
{
|
||||
if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName))
|
||||
Result = STATUS_SUCCESS;
|
||||
else
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
else
|
||||
Result = FspNtStatusFromWin32(GetLastError());
|
||||
Result = FspFileSystemSetMountPoint_CreateDirectory(MountPoint, FileSystem->VolumeName);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (NT_SUCCESS(Result) && 0 != FspNtOpenSymbolicLinkObject)
|
||||
{
|
||||
WCHAR SymlinkBuf[6];
|
||||
UNICODE_STRING Symlink;
|
||||
OBJECT_ATTRIBUTES Obja;
|
||||
|
||||
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||
SymlinkBuf[4] = MountPoint[0];
|
||||
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||
Symlink.Buffer = SymlinkBuf;
|
||||
|
||||
memset(&Obja, 0, sizeof Obja);
|
||||
Obja.Length = sizeof Obja;
|
||||
Obja.ObjectName = &Symlink;
|
||||
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
|
||||
Result = FspNtOpenSymbolicLinkObject(&MountHandle, DELETE, &Obja);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
Result = FspNtMakeTemporaryObject(MountHandle);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspNtClose(MountHandle);
|
||||
MountHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* this path always considered successful regardless if we made symlink temporary */
|
||||
Result = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileSystemSetMountPoint_MakeTemporary(MountPoint, &MountHandle);
|
||||
/* ignore result; this path always considered successful */
|
||||
|
||||
FileSystem->MountPoint = MountPoint;
|
||||
FileSystem->MountHandle = MountHandle;
|
||||
}
|
||||
@ -224,17 +385,29 @@ exit:
|
||||
|
||||
FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||
{
|
||||
BOOLEAN IsDrive;
|
||||
|
||||
if (0 == FileSystem->MountPoint)
|
||||
return;
|
||||
|
||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
||||
IsDrive = FspPathIsDrive(FileSystem->MountPoint);
|
||||
if (IsDrive)
|
||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||
FileSystem->MountPoint, FileSystem->VolumeName);
|
||||
else
|
||||
/* nothing to do! directory will be deleted when the MountHandle is closed */;
|
||||
|
||||
MemFree(FileSystem->MountPoint);
|
||||
FileSystem->MountPoint = 0;
|
||||
|
||||
if (0 != FileSystem->MountHandle)
|
||||
{
|
||||
FspNtClose(FileSystem->MountHandle);
|
||||
if (IsDrive)
|
||||
FspNtClose(FileSystem->MountHandle);
|
||||
else
|
||||
/* CloseHandle really calls NtClose, but I like being defensive when programming */
|
||||
CloseHandle(FileSystem->MountHandle);
|
||||
|
||||
FileSystem->MountHandle = 0;
|
||||
}
|
||||
}
|
||||
@ -246,6 +419,7 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
||||
SIZE_T RequestSize, ResponseSize;
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = 0;
|
||||
FSP_FSCTL_TRANSACT_RSP *Response = 0;
|
||||
FSP_FILE_SYSTEM_OPERATION_CONTEXT OperationContext;
|
||||
HANDLE DispatcherThread = 0;
|
||||
|
||||
Request = MemAlloc(FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN);
|
||||
@ -267,6 +441,10 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
||||
}
|
||||
}
|
||||
|
||||
OperationContext.Request = Request;
|
||||
OperationContext.Response = Response;
|
||||
TlsSetValue(FspFileSystemTlsKey, &OperationContext);
|
||||
|
||||
memset(Response, 0, sizeof *Response);
|
||||
for (;;)
|
||||
{
|
||||
@ -330,6 +508,7 @@ static DWORD WINAPI FspFileSystemDispatcherThread(PVOID FileSystem0)
|
||||
}
|
||||
|
||||
exit:
|
||||
TlsSetValue(FspFileSystemTlsKey, 0);
|
||||
MemFree(Response);
|
||||
MemFree(Request);
|
||||
|
||||
@ -407,3 +586,8 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
||||
FspFsctlStop(FileSystem->VolumeHandle);
|
||||
}
|
||||
}
|
||||
|
||||
FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID)
|
||||
{
|
||||
return (FSP_FILE_SYSTEM_OPERATION_CONTEXT *)TlsGetValue(FspFileSystemTlsKey);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fsctl.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
389
src/dll/fsop.c
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fsop.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -17,8 +17,28 @@
|
||||
|
||||
#include <dll/library.h>
|
||||
|
||||
#define USERCONTEXT(s) \
|
||||
FSP_FSCTL_TRANSACT_USERCONTEXT(s, FileSystem->UmFileNodeIsUserContext2)
|
||||
#define AddrOfFileContext(s) \
|
||||
( \
|
||||
(PVOID)&(((PUINT64)&(s).UserContext)[FileSystem->UmFileContextIsUserContext2])\
|
||||
)
|
||||
#define ValOfFileContext(s) \
|
||||
( \
|
||||
FileSystem->UmFileContextIsFullContext ?\
|
||||
(PVOID)(&(s)) : \
|
||||
(PVOID)(((PUINT64)&(s).UserContext)[FileSystem->UmFileContextIsUserContext2])\
|
||||
)
|
||||
#define SetFileContext(t, s) \
|
||||
( \
|
||||
FileSystem->UmFileContextIsFullContext ?\
|
||||
(VOID)( \
|
||||
(t).UserContext = (s).UserContext,\
|
||||
(t).UserContext2 = (s).UserContext2\
|
||||
) : \
|
||||
(VOID)( \
|
||||
((PUINT64)&(t).UserContext)[FileSystem->UmFileContextIsUserContext2] =\
|
||||
((PUINT64)&(s).UserContext)[FileSystem->UmFileContextIsUserContext2]\
|
||||
) \
|
||||
)
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
@ -28,6 +48,7 @@ FSP_API NTSTATUS FspFileSystemOpEnter(FSP_FILE_SYSTEM *FileSystem,
|
||||
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||
FspFsctlTransactOverwriteKind == Request->Kind ||
|
||||
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||
Request->Req.Cleanup.Delete) ||
|
||||
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||
@ -66,6 +87,7 @@ FSP_API NTSTATUS FspFileSystemOpLeave(FSP_FILE_SYSTEM *FileSystem,
|
||||
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||
FspFsctlTransactOverwriteKind == Request->Kind ||
|
||||
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||
Request->Req.Cleanup.Delete) ||
|
||||
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||
@ -137,7 +159,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
|
||||
{
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
UINT32 ParentDesiredAccess, GrantedAccess;
|
||||
|
||||
/*
|
||||
* CreateCheck does different checks depending on whether we are
|
||||
@ -161,27 +183,43 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
|
||||
if (!Request->Req.Create.NamedStream)
|
||||
{
|
||||
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||
(Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE) ?
|
||||
FILE_ADD_SUBDIRECTORY : FILE_ADD_FILE,
|
||||
&GrantedAccess, PSecurityDescriptor);
|
||||
if (Request->Req.Create.HasRestorePrivilege)
|
||||
ParentDesiredAccess = 0;
|
||||
else if (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE)
|
||||
ParentDesiredAccess = FILE_ADD_SUBDIRECTORY;
|
||||
else
|
||||
ParentDesiredAccess = FILE_ADD_FILE;
|
||||
if (Request->Req.Create.HasTrailingBackslash &&
|
||||
!(Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE))
|
||||
Result = STATUS_OBJECT_NAME_INVALID;
|
||||
else if ((Request->Req.Create.FileAttributes & FILE_ATTRIBUTE_READONLY) &&
|
||||
(Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE))
|
||||
Result = STATUS_CANNOT_DELETE;
|
||||
else
|
||||
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||
ParentDesiredAccess,
|
||||
&GrantedAccess, PSecurityDescriptor);
|
||||
if (STATUS_REPARSE == Result)
|
||||
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
||||
else if (NT_SUCCESS(Result))
|
||||
{
|
||||
*PGrantedAccess = (MAXIMUM_ALLOWED & Request->Req.Create.DesiredAccess) ?
|
||||
FspGetFileGenericMapping()->GenericAll : Request->Req.Create.DesiredAccess;
|
||||
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*PSecurityDescriptor = 0;
|
||||
|
||||
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||
Request->Req.Create.DesiredAccess |
|
||||
FILE_WRITE_DATA |
|
||||
((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0),
|
||||
&GrantedAccess, 0);
|
||||
if (Request->Req.Create.HasTrailingBackslash)
|
||||
Result = STATUS_OBJECT_NAME_INVALID;
|
||||
else
|
||||
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||
Request->Req.Create.DesiredAccess |
|
||||
FILE_WRITE_DATA |
|
||||
((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0),
|
||||
&GrantedAccess, 0);
|
||||
if (STATUS_REPARSE == Result)
|
||||
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
||||
else if (NT_SUCCESS(Result))
|
||||
@ -190,6 +228,7 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
||||
*PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) |
|
||||
(Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA));
|
||||
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,6 +264,7 @@ NTSTATUS FspFileSystemOpenCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
*PGrantedAccess = GrantedAccess;
|
||||
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
||||
*PGrantedAccess &= ~DELETE | (Request->Req.Create.DesiredAccess & DELETE);
|
||||
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
|
||||
}
|
||||
|
||||
return Result;
|
||||
@ -263,6 +303,7 @@ NTSTATUS FspFileSystemOverwriteCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == (Request->Req.Create.DesiredAccess & MAXIMUM_ALLOWED))
|
||||
*PGrantedAccess &= ~(DELETE | FILE_WRITE_DATA) |
|
||||
(Request->Req.Create.DesiredAccess & (DELETE | FILE_WRITE_DATA));
|
||||
*PGrantedAccess |= Request->Req.Create.GrantedAccess;
|
||||
}
|
||||
|
||||
return Result;
|
||||
@ -286,7 +327,7 @@ NTSTATUS FspFileSystemOpenTargetDirectoryCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (STATUS_REPARSE == Result)
|
||||
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
||||
else if (NT_SUCCESS(Result))
|
||||
*PGrantedAccess = GrantedAccess;
|
||||
*PGrantedAccess = GrantedAccess | Request->Req.Create.GrantedAccess;
|
||||
|
||||
return Result;
|
||||
}
|
||||
@ -352,8 +393,8 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
|
||||
Result = FspFileSystemCreateCheck(FileSystem, Request, Response, TRUE,
|
||||
&GrantedAccess, &ParentDescriptor);
|
||||
@ -365,20 +406,31 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = FILE_CREATED;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -387,25 +439,36 @@ static NTSTATUS FspFileSystemOpCreate_FileOpen(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
|
||||
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
&FileNode, &FileInfo);
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Open(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = FILE_OPENED;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -415,8 +478,8 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
BOOLEAN Create = FALSE;
|
||||
|
||||
Result = FspFileSystemOpenCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||
@ -429,11 +492,14 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
|
||||
if (!Create)
|
||||
{
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
&FileNode, &FileInfo);
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Open(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||
@ -454,21 +520,32 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OPENED;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -477,26 +554,36 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
|
||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
&FileNode, &FileInfo);
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Open(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
Response->IoStatus.Information = Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = FILE_OVERWRITTEN;
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -506,8 +593,9 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
NTSTATUS Result;
|
||||
UINT32 GrantedAccess;
|
||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||
BOOLEAN Create = FALSE;
|
||||
|
||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||
@ -520,11 +608,14 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
|
||||
if (!Create)
|
||||
{
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
&FileNode, &FileInfo);
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Open(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||
@ -545,21 +636,33 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Create(FileSystem, Request,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->Create(FileSystem,
|
||||
(PWSTR)Request->Buffer, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
Request->Req.Create.FileAttributes, ObjectDescriptor, Request->Req.Create.AllocationSize,
|
||||
&FileNode, &FileInfo);
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
FspDeleteSecurityDescriptor(ObjectDescriptor, FspCreateSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OVERWRITTEN;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = Create ? FILE_CREATED :
|
||||
(Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN);
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -570,20 +673,23 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
||||
WCHAR Root[2] = L"\\";
|
||||
PWSTR Parent, Suffix;
|
||||
UINT32 GrantedAccess;
|
||||
PVOID FileNode;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||
UINT32 Information;
|
||||
|
||||
Result = FspFileSystemOpenTargetDirectoryCheck(FileSystem, Request, Response, &GrantedAccess);
|
||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||
return Result;
|
||||
|
||||
FileNode = 0;
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
FullContext.UserContext = 0;
|
||||
FullContext.UserContext2 = 0;
|
||||
memset(&OpenFileInfo, 0, sizeof OpenFileInfo);
|
||||
OpenFileInfo.NormalizedName = (PVOID)Response->Buffer;
|
||||
OpenFileInfo.NormalizedNameSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
FspPathSuffix((PWSTR)Request->Buffer, &Parent, &Suffix, Root);
|
||||
Result = FileSystem->Interface->Open(FileSystem, Request,
|
||||
Parent, Request->Req.Create.CaseSensitive, Request->Req.Create.CreateOptions,
|
||||
&FileNode, &FileInfo);
|
||||
Result = FileSystem->Interface->Open(FileSystem,
|
||||
Parent, Request->Req.Create.CreateOptions, GrantedAccess,
|
||||
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
|
||||
FspPathCombine((PWSTR)Request->Buffer, Suffix);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
@ -595,10 +701,18 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenTargetDirectory(FSP_FILE_SYSTEM *F
|
||||
Information = NT_SUCCESS(Result) ? FILE_EXISTS : FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX >= OpenFileInfo.NormalizedNameSize)
|
||||
{
|
||||
Response->Size = (UINT16)(sizeof *Response + OpenFileInfo.NormalizedNameSize);
|
||||
Response->Rsp.Create.Opened.FileName.Offset = 0;
|
||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||
}
|
||||
|
||||
Response->IoStatus.Information = Information;
|
||||
USERCONTEXT(Response->Rsp.Create.Opened) = (UINT_PTR)FileNode;
|
||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||
&OpenFileInfo.FileInfo, sizeof OpenFileInfo.FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -713,10 +827,10 @@ FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
||||
Result = FspFileSystemOpCreate_FileOpenIf(FileSystem, Request, Response);
|
||||
break;
|
||||
case FILE_OVERWRITE:
|
||||
case FILE_SUPERSEDE:
|
||||
Result = FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, Response);
|
||||
break;
|
||||
case FILE_OVERWRITE_IF:
|
||||
case FILE_SUPERSEDE:
|
||||
Result = FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request, Response);
|
||||
break;
|
||||
default:
|
||||
@ -742,16 +856,17 @@ FSP_API NTSTATUS FspFileSystemOpOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->Overwrite(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Overwrite),
|
||||
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 (0 != FileSystem->Interface->Close)
|
||||
FileSystem->Interface->Close(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Overwrite));
|
||||
FileSystem->Interface->Close(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.Overwrite));
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -763,10 +878,15 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
if (0 != FileSystem->Interface->Cleanup)
|
||||
FileSystem->Interface->Cleanup(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Cleanup),
|
||||
FileSystem->Interface->Cleanup(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.Cleanup),
|
||||
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
|
||||
0 != Request->Req.Cleanup.Delete);
|
||||
(0 != Request->Req.Cleanup.Delete ? FspCleanupDelete : 0) |
|
||||
(0 != Request->Req.Cleanup.SetAllocationSize ? FspCleanupSetAllocationSize : 0) |
|
||||
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
|
||||
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
|
||||
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
|
||||
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@ -775,8 +895,8 @@ FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
if (0 != FileSystem->Interface->Close)
|
||||
FileSystem->Interface->Close(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Close));
|
||||
FileSystem->Interface->Close(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.Close));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@ -791,8 +911,8 @@ FSP_API NTSTATUS FspFileSystemOpRead(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
BytesTransferred = 0;
|
||||
Result = FileSystem->Interface->Read(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Read),
|
||||
Result = FileSystem->Interface->Read(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.Read),
|
||||
(PVOID)Request->Req.Read.Address,
|
||||
Request->Req.Read.Offset,
|
||||
Request->Req.Read.Length,
|
||||
@ -817,8 +937,8 @@ FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
BytesTransferred = 0;
|
||||
Result = FileSystem->Interface->Write(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.Write),
|
||||
Result = FileSystem->Interface->Write(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.Write),
|
||||
(PVOID)Request->Req.Write.Address,
|
||||
Request->Req.Write.Offset,
|
||||
Request->Req.Write.Length,
|
||||
@ -841,11 +961,21 @@ FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||
{
|
||||
if (0 == FileSystem->Interface->Flush)
|
||||
return STATUS_SUCCESS; /* liar! */
|
||||
NTSTATUS Result;
|
||||
FSP_FSCTL_FILE_INFO FileInfo;
|
||||
|
||||
return FileSystem->Interface->Flush(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.FlushBuffers));
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
if (0 == FileSystem->Interface->Flush)
|
||||
Result = FileSystem->Interface->GetFileInfo(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.FlushBuffers), &FileInfo);
|
||||
else
|
||||
Result = FileSystem->Interface->Flush(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.FlushBuffers), &FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
memcpy(&Response->Rsp.FlushBuffers.FileInfo, &FileInfo, sizeof FileInfo);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||
@ -858,8 +988,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
memset(&FileInfo, 0, sizeof FileInfo);
|
||||
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.QueryInformation), &FileInfo);
|
||||
Result = FileSystem->Interface->GetFileInfo(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.QueryInformation), &FileInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
@ -879,33 +1009,34 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||
{
|
||||
case 4/*FileBasicInformation*/:
|
||||
if (0 != FileSystem->Interface->SetBasicInfo)
|
||||
Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation),
|
||||
Result = FileSystem->Interface->SetBasicInfo(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation),
|
||||
Request->Req.SetInformation.Info.Basic.FileAttributes,
|
||||
Request->Req.SetInformation.Info.Basic.CreationTime,
|
||||
Request->Req.SetInformation.Info.Basic.LastAccessTime,
|
||||
Request->Req.SetInformation.Info.Basic.LastWriteTime,
|
||||
Request->Req.SetInformation.Info.Basic.ChangeTime,
|
||||
&FileInfo);
|
||||
break;
|
||||
case 19/*FileAllocationInformation*/:
|
||||
if (0 != FileSystem->Interface->SetFileSize)
|
||||
Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation),
|
||||
Result = FileSystem->Interface->SetFileSize(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation),
|
||||
Request->Req.SetInformation.Info.Allocation.AllocationSize, TRUE,
|
||||
&FileInfo);
|
||||
break;
|
||||
case 20/*FileEndOfFileInformation*/:
|
||||
if (0 != FileSystem->Interface->SetFileSize)
|
||||
Result = FileSystem->Interface->SetFileSize(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation),
|
||||
Result = FileSystem->Interface->SetFileSize(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation),
|
||||
Request->Req.SetInformation.Info.EndOfFile.FileSize, FALSE,
|
||||
&FileInfo);
|
||||
break;
|
||||
case 13/*FileDispositionInformation*/:
|
||||
if (0 != FileSystem->Interface->GetFileInfo)
|
||||
{
|
||||
Result = FileSystem->Interface->GetFileInfo(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation), &FileInfo);
|
||||
Result = FileSystem->Interface->GetFileInfo(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation), &FileInfo);
|
||||
if (NT_SUCCESS(Result) && 0 != (FileInfo.FileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
{
|
||||
Result = STATUS_CANNOT_DELETE;
|
||||
@ -914,8 +1045,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
if (0 != FileSystem->Interface->CanDelete)
|
||||
if (Request->Req.SetInformation.Info.Disposition.Delete)
|
||||
Result = FileSystem->Interface->CanDelete(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation),
|
||||
Result = FileSystem->Interface->CanDelete(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation),
|
||||
(PWSTR)Request->Buffer);
|
||||
else
|
||||
Result = STATUS_SUCCESS;
|
||||
@ -931,8 +1062,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||
STATUS_OBJECT_NAME_NOT_FOUND != Result)
|
||||
break;
|
||||
}
|
||||
Result = FileSystem->Interface->Rename(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetInformation),
|
||||
Result = FileSystem->Interface->Rename(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetInformation),
|
||||
(PWSTR)Request->Buffer,
|
||||
(PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
|
||||
0 != Request->Req.SetInformation.Info.Rename.AccessToken);
|
||||
@ -957,7 +1088,7 @@ FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSyst
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
memset(&VolumeInfo, 0, sizeof VolumeInfo);
|
||||
Result = FileSystem->Interface->GetVolumeInfo(FileSystem, Request, &VolumeInfo);
|
||||
Result = FileSystem->Interface->GetVolumeInfo(FileSystem, &VolumeInfo);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
@ -977,7 +1108,7 @@ FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem
|
||||
{
|
||||
case 2/*FileFsLabelInformation*/:
|
||||
if (0 != FileSystem->Interface->SetVolumeLabel)
|
||||
Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request,
|
||||
Result = FileSystem->Interface->SetVolumeLabel(FileSystem,
|
||||
(PWSTR)Request->Buffer,
|
||||
&VolumeInfo);
|
||||
break;
|
||||
@ -1000,8 +1131,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
BytesTransferred = 0;
|
||||
Result = FileSystem->Interface->ReadDirectory(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.QueryDirectory),
|
||||
Result = FileSystem->Interface->ReadDirectory(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.QueryDirectory),
|
||||
(PVOID)Request->Req.QueryDirectory.Address,
|
||||
Request->Req.QueryDirectory.Offset,
|
||||
Request->Req.QueryDirectory.Length,
|
||||
@ -1034,8 +1165,8 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
||||
memset(ReparseData, 0, sizeof *ReparseData);
|
||||
|
||||
Size = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->GetReparsePoint(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.FileSystemControl),
|
||||
Result = FileSystem->Interface->GetReparsePoint(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.FileSystemControl),
|
||||
(PWSTR)Request->Buffer, ReparseData, &Size);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
@ -1051,8 +1182,8 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
||||
ReparseData = (PREPARSE_DATA_BUFFER)
|
||||
(Request->Buffer + Request->Req.FileSystemControl.Buffer.Offset);
|
||||
|
||||
Result = FileSystem->Interface->SetReparsePoint(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.FileSystemControl),
|
||||
Result = FileSystem->Interface->SetReparsePoint(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.FileSystemControl),
|
||||
(PWSTR)Request->Buffer,
|
||||
ReparseData,
|
||||
Request->Req.FileSystemControl.Buffer.Size);
|
||||
@ -1064,8 +1195,8 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
||||
ReparseData = (PREPARSE_DATA_BUFFER)
|
||||
(Request->Buffer + Request->Req.FileSystemControl.Buffer.Offset);
|
||||
|
||||
Result = FileSystem->Interface->DeleteReparsePoint(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.FileSystemControl),
|
||||
Result = FileSystem->Interface->DeleteReparsePoint(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.FileSystemControl),
|
||||
(PWSTR)Request->Buffer,
|
||||
ReparseData,
|
||||
Request->Req.FileSystemControl.Buffer.Size);
|
||||
@ -1086,8 +1217,8 @@ FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
SecurityDescriptorSize = FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX;
|
||||
Result = FileSystem->Interface->GetSecurity(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.QuerySecurity),
|
||||
Result = FileSystem->Interface->GetSecurity(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.QuerySecurity),
|
||||
Response->Buffer, &SecurityDescriptorSize);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return STATUS_BUFFER_OVERFLOW != Result ? Result : STATUS_INVALID_SECURITY_DESCR;
|
||||
@ -1104,8 +1235,8 @@ FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == FileSystem->Interface->SetSecurity)
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
return FileSystem->Interface->SetSecurity(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.SetSecurity),
|
||||
return FileSystem->Interface->SetSecurity(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.SetSecurity),
|
||||
Request->Req.SetSecurity.SecurityInformation,
|
||||
(PSECURITY_DESCRIPTOR)Request->Buffer);
|
||||
}
|
||||
@ -1120,8 +1251,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryStreamInformation(FSP_FILE_SYSTEM *FileSyst
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
BytesTransferred = 0;
|
||||
Result = FileSystem->Interface->GetStreamInfo(FileSystem, Request,
|
||||
(PVOID)USERCONTEXT(Request->Req.QueryStreamInformation),
|
||||
Result = FileSystem->Interface->GetStreamInfo(FileSystem,
|
||||
(PVOID)ValOfFileContext(Request->Req.QueryStreamInformation),
|
||||
Response->Buffer,
|
||||
FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX,
|
||||
&BytesTransferred);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fuse/fuse.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -523,8 +523,8 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
||||
opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE;
|
||||
opt_data.VolumeParams.NamedStreams = FALSE;
|
||||
opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume;
|
||||
opt_data.VolumeParams.PostCleanupOnDeleteOnly = TRUE;
|
||||
opt_data.VolumeParams.UmFileNodeIsUserContext2 = TRUE;
|
||||
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
|
||||
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
|
||||
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
|
||||
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fuse/fuse_intf.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -26,6 +26,7 @@ VOID fsp_fuse_op_enter_lock(FSP_FILE_SYSTEM *FileSystem,
|
||||
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||
FspFsctlTransactOverwriteKind == Request->Kind ||
|
||||
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||
Request->Req.Cleanup.Delete) ||
|
||||
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||
@ -69,6 +70,7 @@ VOID fsp_fuse_op_leave_unlock(FSP_FILE_SYSTEM *FileSystem,
|
||||
case FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE:
|
||||
if ((FspFsctlTransactCreateKind == Request->Kind &&
|
||||
FILE_OPEN != ((Request->Req.Create.CreateOptions >> 24) & 0xff)) ||
|
||||
FspFsctlTransactOverwriteKind == Request->Kind ||
|
||||
(FspFsctlTransactCleanupKind == Request->Kind &&
|
||||
Request->Req.Cleanup.Delete) ||
|
||||
(FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||
@ -143,8 +145,6 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
||||
FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset);
|
||||
Token = (HANDLE)Request->Req.SetInformation.Info.Rename.AccessToken;
|
||||
}
|
||||
else if (FspFsctlTransactSetSecurityKind == Request->Kind)
|
||||
Token = (HANDLE)Request->Req.SetSecurity.AccessToken;
|
||||
|
||||
if (0 != FileName)
|
||||
{
|
||||
@ -691,7 +691,6 @@ static NTSTATUS fsp_fuse_intf_GetReparsePointByName(
|
||||
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize);
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -715,7 +714,6 @@ static NTSTATUS fsp_fuse_intf_GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_SetVolumeLabel(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR VolumeLabel,
|
||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||
{
|
||||
@ -758,8 +756,7 @@ exit:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
|
||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
@ -914,8 +911,7 @@ exit:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PWSTR FileName, BOOLEAN CaseSensitive, UINT32 CreateOptions,
|
||||
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
|
||||
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -941,7 +937,7 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
memset(&fi, 0, sizeof fi);
|
||||
switch (Request->Req.Create.DesiredAccess & (FILE_READ_DATA | FILE_WRITE_DATA))
|
||||
switch (GrantedAccess & (FILE_READ_DATA | FILE_WRITE_DATA))
|
||||
{
|
||||
default:
|
||||
case FILE_READ_DATA:
|
||||
@ -1017,8 +1013,7 @@ exit:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes,
|
||||
PVOID FileNode, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -1055,8 +1050,7 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PWSTR FileName, BOOLEAN Delete)
|
||||
PVOID FileNode, PWSTR FileName, ULONG Flags)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||
@ -1078,7 +1072,7 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||
* FUSE option and can safely remove the file at this time.
|
||||
*/
|
||||
|
||||
if (Delete)
|
||||
if (Flags & FspCleanupDelete)
|
||||
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
|
||||
{
|
||||
if (0 != f->ops.rmdir)
|
||||
@ -1092,7 +1086,6 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -1126,7 +1119,6 @@ static VOID fsp_fuse_intf_Close(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Read(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PULONG PBytesTransferred)
|
||||
{
|
||||
@ -1161,7 +1153,6 @@ static NTSTATUS fsp_fuse_intf_Read(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
|
||||
PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
@ -1224,12 +1215,14 @@ success:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode)
|
||||
PVOID FileNode,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||
UINT32 Uid, Gid, Mode;
|
||||
struct fuse_file_info fi;
|
||||
FSP_FSCTL_FILE_INFO FileInfoBuf;
|
||||
int err;
|
||||
NTSTATUS Result;
|
||||
|
||||
@ -1259,12 +1252,20 @@ static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
|
||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||
}
|
||||
}
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
return Result;
|
||||
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||
&Uid, &Gid, &Mode, &FileInfoBuf);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
@ -1282,9 +1283,8 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT32 FileAttributes,
|
||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
|
||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -1361,7 +1361,6 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, UINT64 NewSize, BOOLEAN SetAllocationSize,
|
||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||
{
|
||||
@ -1445,7 +1444,6 @@ static int fsp_fuse_intf_CanDeleteAddDirInfoOld(fuse_dirh_t dh, const char *name
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PWSTR FileName)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
@ -1479,7 +1477,6 @@ static NTSTATUS fsp_fuse_intf_CanDelete(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists)
|
||||
{
|
||||
@ -1513,7 +1510,6 @@ static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptorBuf, SIZE_T *PSecurityDescriptorSize)
|
||||
{
|
||||
@ -1531,9 +1527,8 @@ static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR Ignored)
|
||||
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor)
|
||||
{
|
||||
struct fuse *f = FileSystem->UserContext;
|
||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||
@ -1560,7 +1555,10 @@ static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
Result = FspSetSecurityDescriptor(FileSystem, Request, SecurityDescriptor,
|
||||
Result = FspSetSecurityDescriptor(
|
||||
SecurityDescriptor,
|
||||
SecurityInformation,
|
||||
ModificationDescriptor,
|
||||
&NewSecurityDescriptor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
@ -1663,7 +1661,6 @@ int fsp_fuse_intf_AddDirInfoOld(fuse_dirh_t dh, const char *name,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode, PVOID Buffer, UINT64 Offset, ULONG Length,
|
||||
PWSTR Pattern,
|
||||
PULONG PBytesTransferred)
|
||||
@ -1748,6 +1745,15 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (sizeof(struct fsp_fuse_dirinfo) > di->Size)
|
||||
break;
|
||||
|
||||
if ('/' == filedesc->PosixPath[0] && '\0' == filedesc->PosixPath[1])
|
||||
{
|
||||
/* if this is the root directory do not add the dot entries */
|
||||
|
||||
if ('.' == di->PosixNameBuf[0] && ('\0' == di->PosixNameBuf[1] ||
|
||||
('.' == di->PosixNameBuf[1] && '\0' == di->PosixNameBuf[2])))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!di->FileInfoValid)
|
||||
{
|
||||
if (0 == PosixPath)
|
||||
@ -1871,7 +1877,6 @@ exit:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PWSTR FileName, PVOID Buffer, PSIZE_T PSize)
|
||||
{
|
||||
@ -1886,7 +1891,6 @@ static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PWSTR FileName, PVOID Buffer, SIZE_T Size)
|
||||
{
|
||||
@ -1971,6 +1975,8 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
||||
if (0 == (ReparseData->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE) &&
|
||||
ReparseTargetPathLength >= sizeof(WCHAR) && L'\\' == ReparseTargetPath[0])
|
||||
{
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request;
|
||||
|
||||
/* we do not support absolute paths that point outside this file system */
|
||||
if (0 == Request->Req.FileSystemControl.TargetOnFileSystem)
|
||||
return STATUS_ACCESS_DENIED;
|
||||
@ -2081,7 +2087,6 @@ exit:
|
||||
}
|
||||
|
||||
static NTSTATUS fsp_fuse_intf_DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem,
|
||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||
PVOID FileNode,
|
||||
PWSTR FileName, PVOID Buffer, SIZE_T Size)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fuse/fuse_main.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fuse/fuse_opt.c
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -107,7 +107,7 @@ static void fsp_fuse_opt_match_templ(
|
||||
if ('%' == *p || '\0' == *p)
|
||||
*pspec = p, *parg = q;
|
||||
else
|
||||
*parg = 0 == lstrcmpA(q, p) ?
|
||||
*parg = 0 == invariant_strcmp(q, p) ?
|
||||
fsp_fuse_opt_match_exact : fsp_fuse_opt_match_none;
|
||||
}
|
||||
else
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dll/fuse/library.h
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|