mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 09:22:57 -05:00
Compare commits
1 Commits
v1.0RC1
...
baseline-p
Author | SHA1 | Date | |
---|---|---|---|
56873406e3 |
@ -3,13 +3,9 @@
|
|||||||
|
|
||||||
v1.0RC1::
|
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:
|
This is the first Release Candidate. It has been tested for robustness and correct file system semantics in a variety of scenarios. Some of the more important changes:
|
||||||
|
|
||||||
- API has been polished and finalized.
|
- 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.
|
- Sharing a (disk) file system over the network is supported.
|
||||||
- Case insensitive file systems are supported.
|
- Case insensitive file systems are supported.
|
||||||
- Directories are supported as mount points.
|
- Directories are supported as mount points.
|
||||||
|
19
README.md
19
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.
|
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 of using WinFsp are listed below:
|
Some of the benefits and features of using WinFsp are listed below:
|
||||||
|
|
||||||
* Very well-tested and stable. Read about its [Testing Strategy](doc/WinFsp-Testing.asciidoc).
|
* 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).
|
||||||
* Very fast. Read about its [Performance](doc/WinFsp-Performance-Testing.asciidoc).
|
* Support for disk and network based file systems.
|
||||||
* Strives for compatibility with NTFS. Read about its [Compatibility](doc/NTFS-Compatibility.asciidoc ).
|
* Support for NTFS level security and access control.
|
||||||
* Easy to understand but comprehensive API. Consult the [API Reference](http://www.secfs.net/winfsp/apiref/).
|
* Support for memory mapped files, cached files and the NT cache manager.
|
||||||
* FUSE compatibility layer for native Windows and Cygwin. See [fuse.h](inc/fuse/fuse.h).
|
* Support for file change notifications.
|
||||||
* Signed drivers provided on every release.
|
* Support for file locking.
|
||||||
* Available under the GPLv3.
|
* Correct NT semantics with respect to file sharing, file deletion and renaming.
|
||||||
|
|
||||||
To learn more about WinFsp, please visit its website: http://www.secfs.net/winfsp/
|
To learn more about WinFsp, please visit its website: http://www.secfs.net/winfsp/
|
||||||
|
|
||||||
@ -53,7 +53,6 @@ WinFsp is designed to run on Vista and above. It has been tested on the followin
|
|||||||
* Windows 8 Pro
|
* Windows 8 Pro
|
||||||
* Windows 10 Pro
|
* Windows 10 Pro
|
||||||
* Windows Server 2012
|
* Windows Server 2012
|
||||||
* Windows Server 2016
|
|
||||||
|
|
||||||
## How to Help
|
## How to Help
|
||||||
|
|
||||||
@ -61,7 +60,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 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.
|
* 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). 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.
|
* 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.
|
||||||
|
|
||||||
In all cases I can provide ideas and/or support.
|
In all cases I can provide ideas and/or support.
|
||||||
|
|
||||||
|
@ -2,10 +2,6 @@ version: '{build}'
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- CONFIGURATION: Debug
|
|
||||||
TESTING: Func
|
|
||||||
- CONFIGURATION: Release
|
|
||||||
TESTING: Func
|
|
||||||
- CONFIGURATION: Release
|
- CONFIGURATION: Release
|
||||||
TESTING: Perf
|
TESTING: Perf
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file CustomActions.cpp
|
* @file CustomActions.cpp
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -155,7 +155,7 @@
|
|||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="CommandLine"
|
Name="CommandLine"
|
||||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
Value="-i -n 65536 -s 67108864 -u %1 -m %2" />
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="Security"
|
Name="Security"
|
||||||
@ -181,7 +181,7 @@
|
|||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="CommandLine"
|
Name="CommandLine"
|
||||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
Value="-i -n 65536 -s 67108864 -u %1 -m %2" />
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="Security"
|
Name="Security"
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
||||||
<DefineConstants>Debug;MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
|
<DefineConstants>Debug;MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion)</DefineConstants>
|
||||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||||
<Pedantic>True</Pedantic>
|
<Pedantic>True</Pedantic>
|
||||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(SolutionDir)build\$(Name).build\$(Configuration)\$(Platform)\</IntermediateOutputPath>
|
||||||
<DefineConstants>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyFullVersion=$(MyFullVersion)</DefineConstants>
|
<DefineConstants>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion)</DefineConstants>
|
||||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||||
<Pedantic>True</Pedantic>
|
<Pedantic>True</Pedantic>
|
||||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||||
|
@ -193,10 +193,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\..\..\src\launcher\launchctl-version.rc">
|
<ResourceCompile Include="..\..\..\src\launcher\launchctl-version.rc">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -202,10 +202,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\..\..\src\launcher\launcher-version.rc">
|
<ResourceCompile Include="..\..\..\src\launcher\launcher-version.rc">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<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>
|
<MyProductName>WinFsp</MyProductName>
|
||||||
<MyDescription>Windows File System Proxy</MyDescription>
|
<MyDescription>Windows File System Proxy</MyDescription>
|
||||||
<MyCompanyName>Navimatics Corporation</MyCompanyName>
|
<MyCompanyName>Navimatics Corporation</MyCompanyName>
|
||||||
@ -17,20 +8,19 @@
|
|||||||
|
|
||||||
<MyCanonicalVersion>1.0</MyCanonicalVersion>
|
<MyCanonicalVersion>1.0</MyCanonicalVersion>
|
||||||
|
|
||||||
<MyProductVersion>2017 RC1</MyProductVersion>
|
<MyProductVersion>$(MyCanonicalVersion) RC1</MyProductVersion>
|
||||||
<MyProductStage>RC</MyProductStage>
|
<MyProductStage>RC</MyProductStage>
|
||||||
|
|
||||||
|
<!-- 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>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||||
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
||||||
<MyFullVersion>$(MyCanonicalVersion).$(MyBuildNumber).$(MyGitRevision)</MyFullVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ResourceCompile>
|
|
||||||
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
</Project>
|
</Project>
|
@ -78,10 +78,10 @@ copy /b $(OutDir)fuse-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse-$(Platfor
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\..\src\dll\eventlog\eventlog.rc" />
|
<ResourceCompile Include="..\..\src\dll\eventlog\eventlog.rc" />
|
||||||
<ResourceCompile Include="..\..\src\dll\version.rc">
|
<ResourceCompile Include="..\..\src\dll\version.rc">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_UNICODE;UNICODE;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
|
@ -177,7 +177,6 @@
|
|||||||
<ClCompile Include="..\..\src\sys\read.c" />
|
<ClCompile Include="..\..\src\sys\read.c" />
|
||||||
<ClCompile Include="..\..\src\sys\security.c" />
|
<ClCompile Include="..\..\src\sys\security.c" />
|
||||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||||
<ClCompile Include="..\..\src\sys\statistics.c" />
|
|
||||||
<ClCompile Include="..\..\src\sys\util.c" />
|
<ClCompile Include="..\..\src\sys\util.c" />
|
||||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||||
<ClCompile Include="..\..\src\sys\volume.c" />
|
<ClCompile Include="..\..\src\sys\volume.c" />
|
||||||
@ -190,77 +189,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\..\src\sys\version.rc">
|
<ResourceCompile Include="..\..\src\sys\version.rc">
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WIN64;_AMD64_=1;AMD64;%(PreprocessorDefinitions);MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</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" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -95,9 +95,6 @@
|
|||||||
<ClCompile Include="..\..\src\sys\name.c">
|
<ClCompile Include="..\..\src\sys\name.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\sys\statistics.c">
|
|
||||||
<Filter>Source</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
@ -112,9 +109,4 @@
|
|||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<None Include="..\..\src\sys\driver.inf.in">
|
|
||||||
<Filter>Source</Filter>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
@ -1,46 +0,0 @@
|
|||||||
= 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.
|
|
@ -16,21 +16,17 @@ WinFsp currently has the following test suites:
|
|||||||
+
|
+
|
||||||
This test suite is developed together with WinFsp. It is written in C/C++ and provides a form of gray box testing.
|
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.
|
- *Winfstest*: This is a file system test suite that was originally developed for the secfs.test collection of file system test programs by the WinFsp author. However none of its tests are WinFsp specific and all its tests pass on NTFS. Winfstest is used for testing by other Windows file systems.
|
||||||
+
|
+
|
||||||
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.
|
This test suite is written in Python and C. 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.
|
- *FSX*: This is Apple's FSX ported to Windows by the WinFsp author. This FSX port is not WinFsp specific and is used for testing by other Windows file systems.
|
||||||
+
|
|
||||||
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.
|
- *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++.
|
This test is WinFsp specific and 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.
|
- *Fsbench*: This is a tool that can be used to test the performance of Windows file systems under different scenarios. It is not WinFsp specific.
|
||||||
+
|
+
|
||||||
This tool is currently developed together with WinFsp. It is written in C.
|
This tool is currently developed together with WinFsp. It is written in C.
|
||||||
|
|
||||||
@ -38,7 +34,7 @@ These test suites and a few smaller tests are run through Continuous Integration
|
|||||||
|
|
||||||
=== Test File System
|
=== 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.
|
WinFsp includes a test user mode file system called *MEMFS*. This is a simple in memory file system written in C/C++. MEMFS attempts to achieve parity with NTFS (barring a few WinFsp limitations -- notably no support for hard links). MEMFS also performs some user mode file system checks during testing, for example, it checks that the buffer received during WRITE calls is read-only.
|
||||||
|
|
||||||
== Tested Scenarios
|
== Tested Scenarios
|
||||||
|
|
||||||
@ -95,12 +91,6 @@ if (!Success)
|
|||||||
|
|
||||||
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.
|
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
|
== 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.
|
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.
|
@ -215,7 +215,7 @@ not need to perform access checks, but may performs tasks such as check for empt
|
|||||||
directories, etc.
|
directories, etc.
|
||||||
|
|
||||||
This function should **NEVER** delete the file or directory in question. Deletion should
|
This function should **NEVER** delete the file or directory in question. Deletion should
|
||||||
happen during Cleanup with the FspCleanupDelete flag set.
|
happen during Cleanup with Delete==TRUE.
|
||||||
|
|
||||||
This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
|
This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
|
||||||
It does not get called when a file or directory is opened with FILE\_DELETE\_ON\_CLOSE.
|
It does not get called when a file or directory is opened with FILE\_DELETE\_ON\_CLOSE.
|
||||||
@ -233,14 +233,16 @@ It does not get called when a file or directory is opened with FILE\_DELETE\_ON\
|
|||||||
FSP_FILE_SYSTEM *FileSystem,
|
FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext,
|
PVOID FileContext,
|
||||||
PWSTR FileName,
|
PWSTR FileName,
|
||||||
ULONG Flags);
|
BOOLEAN Delete);
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- _FileSystem_ \- The file system on which this request is posted.
|
- _FileSystem_ \- The file system on which this request is posted.
|
||||||
- _FileContext_ \- The file context of the file or directory to cleanup.
|
- _FileContext_ \- The file context of the file or directory to cleanup.
|
||||||
- _FileName_ \- The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
- _FileName_ \- The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
||||||
- _Flags_ \- These flags determine whether the file was modified and whether to delete the file.
|
- _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.
|
||||||
|
|
||||||
**Discussion**
|
**Discussion**
|
||||||
|
|
||||||
@ -251,43 +253,18 @@ file object. When all handles for a particular file object get closed (using Clo
|
|||||||
the system sends a Cleanup request to the file system.
|
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
|
There will be a Cleanup operation for every Create or Open operation posted to the user mode
|
||||||
file system. However the Cleanup operation is **not** the final close operation on a file.
|
file system. However the Cleanup operation is **not** the final close operation on a file. The
|
||||||
The file system must be ready to receive additional operations until close time. This is true
|
file system must be ready to receive additional operations until close time. This is true
|
||||||
even when the file is being deleted!
|
even when the file is being deleted!
|
||||||
|
|
||||||
The Flags parameter contains information about the cleanup operation:
|
|
||||||
|
|
||||||
- FspCleanupDelete -
|
|
||||||
An important function of the Cleanup operation is to complete a delete operation. Deleting
|
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
|
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
|
tested to see if the delete can proceed and if the answer is positive the file is then
|
||||||
deleted during Cleanup.
|
deleted during Cleanup.
|
||||||
|
|
||||||
When this flag is set, this is the last outstanding cleanup for this particular file node.
|
|
||||||
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
|
|
||||||
- FspCleanupSetArchiveBit -
|
|
||||||
File systems that support the archive bit should set the file node's archive bit when this
|
|
||||||
flag is set.
|
|
||||||
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 ::
|
As an optimization a file system may specify the FSP\_FSCTL\_VOLUME\_PARAMS ::
|
||||||
PostCleanupWhenModifiedOnly flag. In this case the FSD will only post Cleanup requests when
|
PostCleanupOnDeleteOnly flag. In this case the FSD will only post Cleanup requests when a
|
||||||
the file was modified/deleted.
|
file is being deleted.
|
||||||
|
|
||||||
**See Also**
|
**See Also**
|
||||||
|
|
||||||
@ -385,17 +362,12 @@ STATUS\_SUCCESS or error code.
|
|||||||
:::c
|
:::c
|
||||||
NTSTATUS ( *Flush)(
|
NTSTATUS ( *Flush)(
|
||||||
FSP_FILE_SYSTEM *FileSystem,
|
FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext,
|
PVOID FileContext);
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
- _FileSystem_ \- The file system on which this request is posted.
|
- _FileSystem_ \- The file system on which this request is posted.
|
||||||
- _FileContext_ \- The file context of the file to be flushed. When NULL the whole volume is being flushed.
|
- _FileContext_ \- The file context of the file to be flushed. When NULL the whole volume is being flushed.
|
||||||
- _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 Value**
|
**Return Value**
|
||||||
|
|
||||||
@ -617,7 +589,6 @@ STATUS\_SUCCESS or error code.
|
|||||||
PVOID FileContext,
|
PVOID FileContext,
|
||||||
UINT32 FileAttributes,
|
UINT32 FileAttributes,
|
||||||
BOOLEAN ReplaceFileAttributes,
|
BOOLEAN ReplaceFileAttributes,
|
||||||
UINT64 AllocationSize,
|
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
@ -627,7 +598,6 @@ STATUS\_SUCCESS or error code.
|
|||||||
- _FileAttributes_ \- File attributes to apply to the overwritten file.
|
- _FileAttributes_ \- File attributes to apply to the overwritten file.
|
||||||
- _ReplaceFileAttributes_ \- When TRUE the existing file attributes should be replaced with the new ones.
|
- _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.
|
When FALSE the existing file attributes should be merged (or'ed) with the new ones.
|
||||||
- _AllocationSize_ \- Allocation size for the overwritten file.
|
|
||||||
- _FileInfo_ \- [out]
|
- _FileInfo_ \- [out]
|
||||||
Pointer to a structure that will receive the file information on successful return
|
Pointer to a structure that will receive the file information on successful return
|
||||||
from this call. This information includes file attributes, file times, etc.
|
from this call. This information includes file attributes, file times, etc.
|
||||||
@ -688,16 +658,6 @@ 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
|
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.
|
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.
|
|
||||||
- _Length_ \- Length of data to read.
|
- _Length_ \- Length of data to read.
|
||||||
- _Pattern_ \- The pattern to match against files in this directory. Can be NULL. The file system
|
- _Pattern_ \- The pattern to match against files in this directory. Can be NULL. The file system
|
||||||
can choose to ignore this parameter as the FSD will always perform its own pattern
|
can choose to ignore this parameter as the FSD will always perform its own pattern
|
||||||
@ -742,6 +702,10 @@ STATUS\_SUCCESS or error code.
|
|||||||
|
|
||||||
The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
||||||
|
|
||||||
|
- A file cannot be renamed if it has any open handles, other than the one used to perform
|
||||||
|
the rename.
|
||||||
|
|
||||||
|
|
||||||
- A file cannot be renamed if a file with the same name exists and has open handles.
|
- A file cannot be renamed if a file with the same name exists and has open handles.
|
||||||
|
|
||||||
|
|
||||||
@ -812,7 +776,6 @@ should be returned to the FSD with status STATUS\_REPARSE/IO\_REPARSE.
|
|||||||
UINT64 CreationTime,
|
UINT64 CreationTime,
|
||||||
UINT64 LastAccessTime,
|
UINT64 LastAccessTime,
|
||||||
UINT64 LastWriteTime,
|
UINT64 LastWriteTime,
|
||||||
UINT64 ChangeTime,
|
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
@ -827,8 +790,6 @@ time should not be changed.
|
|||||||
access time should not be changed.
|
access time should not be changed.
|
||||||
- _LastWriteTime_ \- Last write time to apply to the file or directory. If the value 0 is sent, the last
|
- _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.
|
write time should not be changed.
|
||||||
- _ChangeTime_ \- Change time to apply to the file or directory. If the value 0 is sent, the change time
|
|
||||||
should not be changed.
|
|
||||||
- _FileInfo_ \- [out]
|
- _FileInfo_ \- [out]
|
||||||
Pointer to a structure that will receive the file information on successful return
|
Pointer to a structure that will receive the file information on successful return
|
||||||
from this call. This information includes file attributes, file times, etc.
|
from this call. This information includes file attributes, file times, etc.
|
||||||
@ -925,7 +886,8 @@ STATUS\_SUCCESS or error code.
|
|||||||
FSP_FILE_SYSTEM *FileSystem,
|
FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext,
|
PVOID FileContext,
|
||||||
SECURITY_INFORMATION SecurityInformation,
|
SECURITY_INFORMATION SecurityInformation,
|
||||||
PSECURITY_DESCRIPTOR ModificationDescriptor);
|
PSECURITY_DESCRIPTOR ModificationDescriptor,
|
||||||
|
HANDLE AccessToken);
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
@ -934,6 +896,8 @@ STATUS\_SUCCESS or error code.
|
|||||||
- _SecurityInformation_ \- Describes what parts of the file or directory security descriptor should
|
- _SecurityInformation_ \- Describes what parts of the file or directory security descriptor should
|
||||||
be modified.
|
be modified.
|
||||||
- _ModificationDescriptor_ \- Describes the modifications to apply to the file or directory security descriptor.
|
- _ModificationDescriptor_ \- Describes the modifications to apply to the file or directory security descriptor.
|
||||||
|
- _AccessToken_ \- A handle to a token that can be used to verify whether the requested modifications
|
||||||
|
are allowed.
|
||||||
|
|
||||||
**Return Value**
|
**Return Value**
|
||||||
|
|
||||||
@ -1499,6 +1463,7 @@ file system requests from the kernel.
|
|||||||
PSECURITY_DESCRIPTOR InputDescriptor,
|
PSECURITY_DESCRIPTOR InputDescriptor,
|
||||||
SECURITY_INFORMATION SecurityInformation,
|
SECURITY_INFORMATION SecurityInformation,
|
||||||
PSECURITY_DESCRIPTOR ModificationDescriptor,
|
PSECURITY_DESCRIPTOR ModificationDescriptor,
|
||||||
|
HANDLE AccessToken,
|
||||||
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
@ -1508,6 +1473,9 @@ file system requests from the kernel.
|
|||||||
the same value passed to the SetSecurity SecurityInformation parameter.
|
the same value passed to the SetSecurity SecurityInformation parameter.
|
||||||
- _ModificationDescriptor_ \- Describes the modifications to apply to the InputDescriptor. This should contain
|
- _ModificationDescriptor_ \- Describes the modifications to apply to the InputDescriptor. This should contain
|
||||||
the same value passed to the SetSecurity ModificationDescriptor parameter.
|
the same value passed to the SetSecurity ModificationDescriptor parameter.
|
||||||
|
- _AccessToken_ \- A handle to a token that can be used to verify whether the requested modifications
|
||||||
|
are allowed. This should contain the same value passed to the SetSecurity AccessToken
|
||||||
|
parameter.
|
||||||
- _PSecurityDescriptor_ \- [out]
|
- _PSecurityDescriptor_ \- [out]
|
||||||
Pointer to a memory location that will receive the resulting security descriptor.
|
Pointer to a memory location that will receive the resulting security descriptor.
|
||||||
This security descriptor can be later freed using FspDeleteSecurityDescriptor.
|
This security descriptor can be later freed using FspDeleteSecurityDescriptor.
|
||||||
|
2
ext/test
2
ext/test
Submodule ext/test updated: 6ac65cda46...5a3a0b40a0
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.c
|
* @file tlib/callstack.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/callstack.h>
|
#include <tlib/callstack.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.h
|
* @file tlib/callstack.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/allfunc.h
|
* @file tlib/injected/allfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/curlfunc.c
|
* @file tlib/injected/curlfunc.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injected/curlfunc.h>
|
#include <tlib/injected/curlfunc.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/curlfunc.h
|
* @file tlib/injected/curlfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/stdfunc.c
|
* @file tlib/injected/stdfunc.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injected/stdfunc.h>
|
#include <tlib/injected/stdfunc.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/stdfunc.h
|
* @file tlib/injected/stdfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injection.c
|
* @file tlib/injection.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injection.h>
|
#include <tlib/injection.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injection.h
|
* @file tlib/injection.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: This header may usefully be included multiple times.
|
/* NOTE: This header may usefully be included multiple times.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/testsuite.c
|
* @file tlib/testsuite.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/testsuite.h>
|
#include <tlib/testsuite.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/testsuite.h
|
* @file tlib/testsuite.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2015 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file fuse/winfsp_fuse.h
|
* @file fuse/winfsp_fuse.h
|
||||||
* WinFsp FUSE compatible API.
|
* WinFsp FUSE compatible API.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file winfsp/fsctl.h
|
* @file winfsp/fsctl.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -146,7 +146,7 @@ typedef struct
|
|||||||
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */
|
UINT32 ExtendedAttributes:1; /* unimplemented; set to 0 */
|
||||||
UINT32 ReadOnlyVolume:1;
|
UINT32 ReadOnlyVolume:1;
|
||||||
/* kernel-mode flags */
|
/* kernel-mode flags */
|
||||||
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */
|
UINT32 PostCleanupOnDeleteOnly:1; /* post Cleanup when deleting a file only */
|
||||||
UINT32 KmReservedFlags:5;
|
UINT32 KmReservedFlags:5;
|
||||||
/* user-mode flags */
|
/* user-mode flags */
|
||||||
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
||||||
@ -232,8 +232,7 @@ typedef struct
|
|||||||
UINT32 HasRestorePrivilege:1; /* requestor has TOKEN_HAS_RESTORE_PRIVILEGE */
|
UINT32 HasRestorePrivilege:1; /* requestor has TOKEN_HAS_RESTORE_PRIVILEGE */
|
||||||
UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */
|
UINT32 OpenTargetDirectory:1; /* open target dir and report FILE_{EXISTS,DOES_NOT_EXIST} */
|
||||||
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
||||||
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
|
UINT32 ReservedFlags:26;
|
||||||
UINT32 ReservedFlags:25;
|
|
||||||
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
|
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
|
||||||
} Create;
|
} Create;
|
||||||
struct
|
struct
|
||||||
@ -249,11 +248,6 @@ typedef struct
|
|||||||
UINT64 UserContext;
|
UINT64 UserContext;
|
||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
UINT32 Delete:1; /* file must be deleted */
|
UINT32 Delete:1; /* file must be deleted */
|
||||||
UINT32 SetAllocationSize:1;
|
|
||||||
UINT32 SetArchiveBit:1;
|
|
||||||
UINT32 SetLastAccessTime:1;
|
|
||||||
UINT32 SetLastWriteTime:1;
|
|
||||||
UINT32 SetChangeTime:1;
|
|
||||||
} Cleanup;
|
} Cleanup;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -301,7 +295,6 @@ typedef struct
|
|||||||
UINT64 CreationTime;
|
UINT64 CreationTime;
|
||||||
UINT64 LastAccessTime;
|
UINT64 LastAccessTime;
|
||||||
UINT64 LastWriteTime;
|
UINT64 LastWriteTime;
|
||||||
UINT64 ChangeTime;
|
|
||||||
} Basic;
|
} Basic;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -422,10 +415,6 @@ typedef struct
|
|||||||
FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */
|
FSP_FSCTL_FILE_INFO FileInfo; /* valid: File{Allocation,Basic,EndOfFile}Information */
|
||||||
} SetInformation;
|
} SetInformation;
|
||||||
struct
|
struct
|
||||||
{
|
|
||||||
FSP_FSCTL_FILE_INFO FileInfo; /* valid when flushing file (not volume) */
|
|
||||||
} FlushBuffers;
|
|
||||||
struct
|
|
||||||
{
|
{
|
||||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
} QueryVolumeInformation;
|
} QueryVolumeInformation;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h>
|
* 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.
|
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -122,15 +122,6 @@ typedef enum
|
|||||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0,
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE = 0,
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE,
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE,
|
||||||
} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY;
|
} FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY;
|
||||||
enum
|
|
||||||
{
|
|
||||||
FspCleanupDelete = 0x01,
|
|
||||||
FspCleanupSetAllocationSize = 0x02,
|
|
||||||
FspCleanupSetArchiveBit = 0x10,
|
|
||||||
FspCleanupSetLastAccessTime = 0x20,
|
|
||||||
FspCleanupSetLastWriteTime = 0x40,
|
|
||||||
FspCleanupSetChangeTime = 0x80,
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* @class FSP_FILE_SYSTEM
|
* @class FSP_FILE_SYSTEM
|
||||||
* File system interface.
|
* File system interface.
|
||||||
@ -331,40 +322,18 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* the system sends a Cleanup request to the file system.
|
* 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
|
* 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.
|
* file system. However the Cleanup operation is <b>not</b> the final close operation on a file. The
|
||||||
* The file system must be ready to receive additional operations until close time. This is true
|
* file system must be ready to receive additional operations until close time. This is true
|
||||||
* even when the file is being deleted!
|
* 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
|
* 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
|
* 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
|
* tested to see if the delete can proceed and if the answer is positive the file is then
|
||||||
* deleted during Cleanup.
|
* 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 ::
|
* As an optimization a file system may specify the FSP_FSCTL_VOLUME_PARAMS ::
|
||||||
* PostCleanupWhenModifiedOnly flag. In this case the FSD will only post Cleanup requests when
|
* PostCleanupOnDeleteOnly flag. In this case the FSD will only post Cleanup requests when a
|
||||||
* the file was modified/deleted.
|
* file is being deleted.
|
||||||
*
|
*
|
||||||
* @param FileSystem
|
* @param FileSystem
|
||||||
* The file system on which this request is posted.
|
* The file system on which this request is posted.
|
||||||
@ -372,14 +341,16 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* The file context of the file or directory to cleanup.
|
* The file context of the file or directory to cleanup.
|
||||||
* @param FileName
|
* @param FileName
|
||||||
* The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
* The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
||||||
* @param Flags
|
* @param Delete
|
||||||
* These flags determine whether the file was modified and whether to delete the file.
|
* 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.
|
||||||
* @see
|
* @see
|
||||||
* Close
|
* Close
|
||||||
* CanDelete
|
* CanDelete
|
||||||
*/
|
*/
|
||||||
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
|
VOID (*Cleanup)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext, PWSTR FileName, ULONG Flags);
|
PVOID FileContext, PWSTR FileName, BOOLEAN Delete);
|
||||||
/**
|
/**
|
||||||
* Close a file.
|
* Close a file.
|
||||||
*
|
*
|
||||||
@ -452,16 +423,11 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* The file system on which this request is posted.
|
* The file system on which this request is posted.
|
||||||
* @param FileContext
|
* @param FileContext
|
||||||
* The file context of the file to be flushed. When NULL the whole volume is being flushed.
|
* 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
|
* @return
|
||||||
* STATUS_SUCCESS or error code.
|
* STATUS_SUCCESS or error code.
|
||||||
*/
|
*/
|
||||||
NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*Flush)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext,
|
PVOID FileContext);
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
|
||||||
/**
|
/**
|
||||||
* Get file or directory information.
|
* Get file or directory information.
|
||||||
*
|
*
|
||||||
@ -497,9 +463,6 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* @param LastWriteTime
|
* @param LastWriteTime
|
||||||
* Last write time to apply to the file or directory. If the value 0 is sent, the last
|
* Last write time to apply to the file or directory. If the value 0 is sent, the last
|
||||||
* write time should not be changed.
|
* 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]
|
* @param FileInfo [out]
|
||||||
* Pointer to a structure that will receive the file information on successful return
|
* Pointer to a structure that will receive the file information on successful return
|
||||||
* from this call. This information includes file attributes, file times, etc.
|
* from this call. This information includes file attributes, file times, etc.
|
||||||
@ -508,7 +471,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
*/
|
*/
|
||||||
NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext, UINT32 FileAttributes,
|
PVOID FileContext, UINT32 FileAttributes,
|
||||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
|
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo);
|
FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
/**
|
/**
|
||||||
* Set file/allocation size.
|
* Set file/allocation size.
|
||||||
@ -555,7 +518,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
* directories, etc.
|
* directories, etc.
|
||||||
*
|
*
|
||||||
* This function should <b>NEVER</b> delete the file or directory in question. Deletion should
|
* This function should <b>NEVER</b> delete the file or directory in question. Deletion should
|
||||||
* happen during Cleanup with the FspCleanupDelete flag set.
|
* happen during Cleanup with Delete==TRUE.
|
||||||
*
|
*
|
||||||
* This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
|
* This function gets called when Win32 API's such as DeleteFile or RemoveDirectory are used.
|
||||||
* It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE.
|
* It does not get called when a file or directory is opened with FILE_DELETE_ON_CLOSE.
|
||||||
@ -578,6 +541,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
*
|
*
|
||||||
* The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
* The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
||||||
* <ul>
|
* <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 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
|
* <li>A directory cannot be renamed if it or any of its subdirectories contains a file that
|
||||||
* has open handles.</li>
|
* has open handles.</li>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file cygfuse/cygfuse.c
|
* @file cygfuse/cygfuse.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/debug.c
|
* @file dll/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/eventlog.c
|
* @file dll/eventlog.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fs.c
|
* @file dll/fs.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsctl.c
|
* @file dll/fsctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsop.c
|
* @file dll/fsop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -189,16 +189,9 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
ParentDesiredAccess = FILE_ADD_SUBDIRECTORY;
|
ParentDesiredAccess = FILE_ADD_SUBDIRECTORY;
|
||||||
else
|
else
|
||||||
ParentDesiredAccess = FILE_ADD_FILE;
|
ParentDesiredAccess = FILE_ADD_FILE;
|
||||||
if (Request->Req.Create.HasTrailingBackslash &&
|
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||||
!(Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE))
|
ParentDesiredAccess,
|
||||||
Result = STATUS_OBJECT_NAME_INVALID;
|
&GrantedAccess, PSecurityDescriptor);
|
||||||
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)
|
if (STATUS_REPARSE == Result)
|
||||||
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
||||||
else if (NT_SUCCESS(Result))
|
else if (NT_SUCCESS(Result))
|
||||||
@ -212,14 +205,11 @@ NTSTATUS FspFileSystemCreateCheck(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
{
|
{
|
||||||
*PSecurityDescriptor = 0;
|
*PSecurityDescriptor = 0;
|
||||||
|
|
||||||
if (Request->Req.Create.HasTrailingBackslash)
|
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
||||||
Result = STATUS_OBJECT_NAME_INVALID;
|
Request->Req.Create.DesiredAccess |
|
||||||
else
|
FILE_WRITE_DATA |
|
||||||
Result = FspAccessCheckEx(FileSystem, Request, TRUE, AllowTraverseCheck,
|
((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0),
|
||||||
Request->Req.Create.DesiredAccess |
|
&GrantedAccess, 0);
|
||||||
FILE_WRITE_DATA |
|
|
||||||
((Request->Req.Create.CreateOptions & FILE_DELETE_ON_CLOSE) ? DELETE : 0),
|
|
||||||
&GrantedAccess, 0);
|
|
||||||
if (STATUS_REPARSE == Result)
|
if (STATUS_REPARSE == Result)
|
||||||
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
Result = FspFileSystemCallResolveReparsePoints(FileSystem, Request, Response, GrantedAccess);
|
||||||
else if (NT_SUCCESS(Result))
|
else if (NT_SUCCESS(Result))
|
||||||
@ -556,6 +546,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
UINT32 GrantedAccess;
|
UINT32 GrantedAccess;
|
||||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
|
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
||||||
|
|
||||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||||
@ -579,7 +570,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = FILE_OVERWRITTEN;
|
Response->IoStatus.Information = Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
|
||||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
@ -595,7 +586,6 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
PSECURITY_DESCRIPTOR ParentDescriptor, ObjectDescriptor;
|
||||||
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
FSP_FSCTL_TRANSACT_FULL_CONTEXT FullContext;
|
||||||
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
FSP_FSCTL_OPEN_FILE_INFO OpenFileInfo;
|
||||||
BOOLEAN Supersede = FILE_SUPERSEDE == ((Request->Req.Create.CreateOptions >> 24) & 0xff);
|
|
||||||
BOOLEAN Create = FALSE;
|
BOOLEAN Create = FALSE;
|
||||||
|
|
||||||
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
Result = FspFileSystemOverwriteCheck(FileSystem, Request, Response, TRUE, &GrantedAccess);
|
||||||
@ -657,8 +647,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
|
|||||||
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
Response->Rsp.Create.Opened.FileName.Size = (UINT16)OpenFileInfo.NormalizedNameSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
Response->IoStatus.Information = Create ? FILE_CREATED :
|
Response->IoStatus.Information = Create ? FILE_CREATED : FILE_OVERWRITTEN;
|
||||||
(Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN);
|
|
||||||
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
SetFileContext(Response->Rsp.Create.Opened, FullContext);
|
||||||
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
Response->Rsp.Create.Opened.GrantedAccess = GrantedAccess;
|
||||||
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
memcpy(&Response->Rsp.Create.Opened.FileInfo,
|
||||||
@ -827,10 +816,10 @@ FSP_API NTSTATUS FspFileSystemOpCreate(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
Result = FspFileSystemOpCreate_FileOpenIf(FileSystem, Request, Response);
|
Result = FspFileSystemOpCreate_FileOpenIf(FileSystem, Request, Response);
|
||||||
break;
|
break;
|
||||||
case FILE_OVERWRITE:
|
case FILE_OVERWRITE:
|
||||||
|
case FILE_SUPERSEDE:
|
||||||
Result = FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, Response);
|
Result = FspFileSystemOpCreate_FileOverwrite(FileSystem, Request, Response);
|
||||||
break;
|
break;
|
||||||
case FILE_OVERWRITE_IF:
|
case FILE_OVERWRITE_IF:
|
||||||
case FILE_SUPERSEDE:
|
|
||||||
Result = FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request, Response);
|
Result = FspFileSystemOpCreate_FileOverwriteIf(FileSystem, Request, Response);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -881,12 +870,7 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FileSystem->Interface->Cleanup(FileSystem,
|
FileSystem->Interface->Cleanup(FileSystem,
|
||||||
(PVOID)ValOfFileContext(Request->Req.Cleanup),
|
(PVOID)ValOfFileContext(Request->Req.Cleanup),
|
||||||
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
|
0 != Request->FileName.Size ? (PWSTR)Request->Buffer : 0,
|
||||||
(0 != Request->Req.Cleanup.Delete ? FspCleanupDelete : 0) |
|
0 != Request->Req.Cleanup.Delete);
|
||||||
(0 != Request->Req.Cleanup.SetAllocationSize ? FspCleanupSetAllocationSize : 0) |
|
|
||||||
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
|
|
||||||
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
|
|
||||||
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
|
|
||||||
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -961,21 +945,11 @@ FSP_API NTSTATUS FspFileSystemOpWrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpFlushBuffers(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
|
||||||
FSP_FSCTL_FILE_INFO FileInfo;
|
|
||||||
|
|
||||||
memset(&FileInfo, 0, sizeof FileInfo);
|
|
||||||
if (0 == FileSystem->Interface->Flush)
|
if (0 == FileSystem->Interface->Flush)
|
||||||
Result = FileSystem->Interface->GetFileInfo(FileSystem,
|
return STATUS_SUCCESS; /* liar! */
|
||||||
(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 FileSystem->Interface->Flush(FileSystem,
|
||||||
return STATUS_SUCCESS;
|
(PVOID)ValOfFileContext(Request->Req.FlushBuffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -1015,7 +989,6 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
Request->Req.SetInformation.Info.Basic.CreationTime,
|
Request->Req.SetInformation.Info.Basic.CreationTime,
|
||||||
Request->Req.SetInformation.Info.Basic.LastAccessTime,
|
Request->Req.SetInformation.Info.Basic.LastAccessTime,
|
||||||
Request->Req.SetInformation.Info.Basic.LastWriteTime,
|
Request->Req.SetInformation.Info.Basic.LastWriteTime,
|
||||||
Request->Req.SetInformation.Info.Basic.ChangeTime,
|
|
||||||
&FileInfo);
|
&FileInfo);
|
||||||
break;
|
break;
|
||||||
case 19/*FileAllocationInformation*/:
|
case 19/*FileAllocationInformation*/:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse.c
|
* @file dll/fuse/fuse.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -523,7 +523,7 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
|||||||
opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE;
|
opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE;
|
||||||
opt_data.VolumeParams.NamedStreams = FALSE;
|
opt_data.VolumeParams.NamedStreams = FALSE;
|
||||||
opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume;
|
opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume;
|
||||||
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
|
opt_data.VolumeParams.PostCleanupOnDeleteOnly = TRUE;
|
||||||
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
|
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
|
||||||
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
|
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
|
||||||
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
|
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_intf.c
|
* @file dll/fuse/fuse_intf.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1050,7 +1050,7 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileNode, PWSTR FileName, ULONG Flags)
|
PVOID FileNode, PWSTR FileName, BOOLEAN Delete)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||||
@ -1072,7 +1072,7 @@ static VOID fsp_fuse_intf_Cleanup(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
* FUSE option and can safely remove the file at this time.
|
* FUSE option and can safely remove the file at this time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (Flags & FspCleanupDelete)
|
if (Delete)
|
||||||
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
|
if (filedesc->IsDirectory && !filedesc->IsReparsePoint)
|
||||||
{
|
{
|
||||||
if (0 != f->ops.rmdir)
|
if (0 != f->ops.rmdir)
|
||||||
@ -1215,14 +1215,11 @@ success:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileNode,
|
PVOID FileNode)
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
struct fsp_fuse_file_desc *filedesc = FileNode;
|
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||||
UINT32 Uid, Gid, Mode;
|
|
||||||
struct fuse_file_info fi;
|
struct fuse_file_info fi;
|
||||||
FSP_FSCTL_FILE_INFO FileInfoBuf;
|
|
||||||
int err;
|
int err;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
@ -1252,17 +1249,8 @@ static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
return Result;
|
||||||
&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,
|
static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -1284,7 +1272,7 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileNode, UINT32 FileAttributes,
|
PVOID FileNode, UINT32 FileAttributes,
|
||||||
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
|
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime,
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_main.c
|
* @file dll/fuse/fuse_main.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_opt.c
|
* @file dll/fuse/fuse_opt.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/library.h
|
* @file dll/fuse/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.c
|
* @file dll/library.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.h
|
* @file dll/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/np.c
|
* @file dll/np.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/ntstatus.c
|
* @file dll/ntstatus.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/path.c
|
* @file dll/path.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* [SNAME]
|
* [SNAME]
|
||||||
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/security.c
|
* @file dll/security.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -191,13 +191,6 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
if (!NT_SUCCESS(Result) || STATUS_REPARSE == Result)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (!CheckParentOrMain && Request->Req.Create.HasTrailingBackslash &&
|
|
||||||
!(FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
{
|
|
||||||
Result = STATUS_OBJECT_NAME_INVALID;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Request->Req.Create.UserMode && 0 < SecurityDescriptorSize)
|
if (Request->Req.Create.UserMode && 0 < SecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
if (0 == DesiredAccess)
|
if (0 == DesiredAccess)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/service.c
|
* @file dll/service.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/util.c
|
* @file dll/util.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -22,7 +22,7 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", STR(MyCompanyName)
|
VALUE "CompanyName", STR(MyCompanyName)
|
||||||
VALUE "FileDescription", STR(MyDescription)
|
VALUE "FileDescription", STR(MyDescription)
|
||||||
VALUE "FileVersion", STR(MyFullVersion)
|
VALUE "FileVersion", STR(MyVersion)
|
||||||
VALUE "InternalName", "winfsp.dll"
|
VALUE "InternalName", "winfsp.dll"
|
||||||
VALUE "LegalCopyright", STR(MyCopyright)
|
VALUE "LegalCopyright", STR(MyCopyright)
|
||||||
VALUE "OriginalFilename", "winfsp.dll"
|
VALUE "OriginalFilename", "winfsp.dll"
|
||||||
|
@ -22,7 +22,7 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", STR(MyCompanyName)
|
VALUE "CompanyName", STR(MyCompanyName)
|
||||||
VALUE "FileDescription", STR(MyDescription)
|
VALUE "FileDescription", STR(MyDescription)
|
||||||
VALUE "FileVersion", STR(MyFullVersion)
|
VALUE "FileVersion", STR(MyVersion)
|
||||||
VALUE "InternalName", "launchctl.exe"
|
VALUE "InternalName", "launchctl.exe"
|
||||||
VALUE "LegalCopyright", STR(MyCopyright)
|
VALUE "LegalCopyright", STR(MyCopyright)
|
||||||
VALUE "OriginalFilename", "launchctl.exe"
|
VALUE "OriginalFilename", "launchctl.exe"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launchctl.c
|
* @file launcher/launchctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -22,7 +22,7 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", STR(MyCompanyName)
|
VALUE "CompanyName", STR(MyCompanyName)
|
||||||
VALUE "FileDescription", STR(MyDescription)
|
VALUE "FileDescription", STR(MyDescription)
|
||||||
VALUE "FileVersion", STR(MyFullVersion)
|
VALUE "FileVersion", STR(MyVersion)
|
||||||
VALUE "InternalName", "launcher.exe"
|
VALUE "InternalName", "launcher.exe"
|
||||||
VALUE "LegalCopyright", STR(MyCopyright)
|
VALUE "LegalCopyright", STR(MyCopyright)
|
||||||
VALUE "OriginalFilename", "launcher.exe"
|
VALUE "OriginalFilename", "launcher.exe"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launcher.c
|
* @file launcher/launcher.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launcher.h
|
* @file launcher/launcher.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/minimal.h
|
* @file shared/minimal.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file sys/callbacks.c
|
* @file sys/callbacks.c
|
||||||
* Fast I/O and resource acquisition callbacks.
|
* Fast I/O and resource acquisition callbacks.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/cleanup.c
|
* @file sys/cleanup.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -77,17 +77,13 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
ULONG CleanupFlags;
|
BOOLEAN DeletePending;
|
||||||
BOOLEAN DeletePending, SetAllocationSize, FileModified;
|
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
FspFileNodeAcquireExclusive(FileNode, Main);
|
FspFileNodeAcquireExclusive(FileNode, Main);
|
||||||
|
|
||||||
FspFileNodeCleanup(FileNode, FileObject, &CleanupFlags);
|
FspFileNodeCleanup(FileNode, FileObject, &DeletePending);
|
||||||
DeletePending = CleanupFlags & 1;
|
|
||||||
SetAllocationSize = !!(CleanupFlags & 2);
|
|
||||||
FileModified = BooleanFlagOn(FileObject->Flags, FO_FILE_MODIFIED);
|
|
||||||
|
|
||||||
/* if this is a directory inform the FSRTL Notify mechanism */
|
/* if this is a directory inform the FSRTL Notify mechanism */
|
||||||
if (FileNode->IsDirectory)
|
if (FileNode->IsDirectory)
|
||||||
@ -110,25 +106,13 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
Request->Req.Cleanup.UserContext = FileNode->UserContext;
|
Request->Req.Cleanup.UserContext = FileNode->UserContext;
|
||||||
Request->Req.Cleanup.UserContext2 = FileDesc->UserContext2;
|
Request->Req.Cleanup.UserContext2 = FileDesc->UserContext2;
|
||||||
Request->Req.Cleanup.Delete = DeletePending;
|
Request->Req.Cleanup.Delete = DeletePending;
|
||||||
Request->Req.Cleanup.SetAllocationSize = SetAllocationSize;
|
|
||||||
Request->Req.Cleanup.SetArchiveBit = (FileModified || FileDesc->DidSetSecurity) &&
|
|
||||||
!FileDesc->DidSetFileAttributes;
|
|
||||||
Request->Req.Cleanup.SetLastAccessTime = !FileDesc->DidSetLastAccessTime;
|
|
||||||
Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime;
|
|
||||||
Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) &&
|
|
||||||
!FileDesc->DidSetChangeTime;
|
|
||||||
|
|
||||||
FspFileNodeAcquireExclusive(FileNode, Pgio);
|
FspFileNodeAcquireExclusive(FileNode, Pgio);
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
|
||||||
if (Request->Req.Cleanup.Delete ||
|
if (DeletePending || !FsvolDeviceExtension->VolumeParams.PostCleanupOnDeleteOnly)
|
||||||
Request->Req.Cleanup.SetAllocationSize ||
|
|
||||||
Request->Req.Cleanup.SetArchiveBit ||
|
|
||||||
Request->Req.Cleanup.SetLastWriteTime ||
|
|
||||||
Request->Req.Cleanup.SetChangeTime ||
|
|
||||||
!FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly)
|
|
||||||
/*
|
/*
|
||||||
* Note that it is still possible for this request to not be delivered,
|
* Note that it is still possible for this request to not be delivered,
|
||||||
* if the volume device Ioq is stopped. But such failures are benign
|
* if the volume device Ioq is stopped. But such failures are benign
|
||||||
@ -138,13 +122,9 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
return FSP_STATUS_IOQ_POST_BEST_EFFORT;
|
return FSP_STATUS_IOQ_POST_BEST_EFFORT;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (FileDesc->DidSetMetadata)
|
/* if the file is being resized invalidate the volume info */
|
||||||
{
|
if (FileNode->TruncateOnClose)
|
||||||
if (0 == FileNode->MainFileNode)
|
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
|
||||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
|
||||||
else
|
|
||||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
|
return STATUS_SUCCESS; /* FspFsvolCleanupRequestFini will take care of the rest! */
|
||||||
}
|
}
|
||||||
@ -158,51 +138,15 @@ NTSTATUS FspFsvolCleanupComplete(
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
|
||||||
ULONG NotifyFilter, NotifyAction;
|
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
/* if the file is being deleted do a change notification */
|
||||||
|
|
||||||
/* send the appropriate notification; also invalidate dirinfo/etc. caches */
|
|
||||||
if (Request->Req.Cleanup.Delete)
|
if (Request->Req.Cleanup.Delete)
|
||||||
{
|
FspFileNodeNotifyChange(FileNode,
|
||||||
NotifyFilter = FileNode->IsDirectory ?
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME;
|
FILE_ACTION_REMOVED);
|
||||||
NotifyAction = FILE_ACTION_REMOVED;
|
/* if the file is being resized invalidate the volume info */
|
||||||
}
|
else if (FileNode->TruncateOnClose)
|
||||||
else
|
FspFsvolDeviceInvalidateVolumeInfo(IrpSp->DeviceObject);
|
||||||
{
|
|
||||||
/* send notification for any metadata changes */
|
|
||||||
NotifyFilter = 0;
|
|
||||||
#if 0
|
|
||||||
/* do not send notification when resetting the allocation size */
|
|
||||||
if (Request->Req.Cleanup.SetAllocationSize)
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_SIZE;
|
|
||||||
#endif
|
|
||||||
if (Request->Req.Cleanup.SetArchiveBit)
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
|
|
||||||
#if 0
|
|
||||||
/* do not send notification for implicit LastAccessTime changes */
|
|
||||||
if (Request->Req.Cleanup.SetLastAccessTime)
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
|
||||||
#endif
|
|
||||||
if (Request->Req.Cleanup.SetLastWriteTime)
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
|
||||||
NotifyAction = FILE_ACTION_MODIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != NotifyFilter)
|
|
||||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, NotifyAction, TRUE);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (FileDesc->DidSetMetadata)
|
|
||||||
{
|
|
||||||
if (0 == FileNode->MainFileNode)
|
|
||||||
FspFileNodeInvalidateParentDirInfo(FileNode);
|
|
||||||
else
|
|
||||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
|
FSP_LEAVE_IOC("FileObject=%p", IrpSp->FileObject);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/close.c
|
* @file sys/close.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/create.c
|
* @file sys/create.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -193,7 +193,6 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_BACKUP_PRIVILEGE);
|
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_BACKUP_PRIVILEGE);
|
||||||
BOOLEAN HasRestorePrivilege =
|
BOOLEAN HasRestorePrivilege =
|
||||||
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE);
|
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE);
|
||||||
BOOLEAN HasTrailingBackslash = FALSE;
|
|
||||||
FSP_FILE_NODE *FileNode, *RelatedFileNode;
|
FSP_FILE_NODE *FileNode, *RelatedFileNode;
|
||||||
FSP_FILE_DESC *FileDesc;
|
FSP_FILE_DESC *FileDesc;
|
||||||
UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 };
|
UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 };
|
||||||
@ -217,12 +216,6 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
FlagOn(CreateOptions, FILE_DIRECTORY_FILE))
|
FlagOn(CreateOptions, FILE_DIRECTORY_FILE))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* do not allow the temporary bit on a directory */
|
|
||||||
if (FlagOn(CreateOptions, FILE_DIRECTORY_FILE) &&
|
|
||||||
FlagOn(FileAttributes, FILE_ATTRIBUTE_TEMPORARY) &&
|
|
||||||
(FILE_CREATE == CreateDisposition || FILE_OPEN_IF == CreateDisposition))
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* check security descriptor validity */
|
/* check security descriptor validity */
|
||||||
if (0 != SecurityDescriptor)
|
if (0 != SecurityDescriptor)
|
||||||
{
|
{
|
||||||
@ -264,7 +257,7 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
|
|
||||||
/* must be a relative path */
|
/* must be a relative path */
|
||||||
if (sizeof(WCHAR) <= FileName.Length && L'\\' == FileName.Buffer[0])
|
if (sizeof(WCHAR) <= FileName.Length && L'\\' == FileName.Buffer[0])
|
||||||
return STATUS_INVALID_PARAMETER; /* IFSTEST */
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
BOOLEAN AppendBackslash =
|
BOOLEAN AppendBackslash =
|
||||||
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFileNode->FileName.Length &&
|
sizeof(WCHAR) * 2/* not empty or root */ <= RelatedFileNode->FileName.Length &&
|
||||||
@ -300,7 +293,7 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
/* check filename validity */
|
/* check filename validity */
|
||||||
if (!FspFileNameIsValid(&FileNode->FileName, FsvolDeviceExtension->VolumeParams.MaxComponentLength,
|
if (!FspFileNameIsValid(&FileNode->FileName,
|
||||||
FsvolDeviceExtension->VolumeParams.NamedStreams ? &StreamPart : 0,
|
FsvolDeviceExtension->VolumeParams.NamedStreams ? &StreamPart : 0,
|
||||||
&StreamType))
|
&StreamType))
|
||||||
{
|
{
|
||||||
@ -351,7 +344,12 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
if (sizeof(WCHAR) * 2/* not empty or root */ <= FileNode->FileName.Length &&
|
if (sizeof(WCHAR) * 2/* not empty or root */ <= FileNode->FileName.Length &&
|
||||||
L'\\' == FileNode->FileName.Buffer[FileNode->FileName.Length / sizeof(WCHAR) - 1])
|
L'\\' == FileNode->FileName.Buffer[FileNode->FileName.Length / sizeof(WCHAR) - 1])
|
||||||
{
|
{
|
||||||
HasTrailingBackslash = TRUE;
|
if (!FlagOn(CreateOptions, FILE_DIRECTORY_FILE))
|
||||||
|
{
|
||||||
|
FspFileNodeDereference(FileNode);
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
FileNode->FileName.Length -= sizeof(WCHAR);
|
FileNode->FileName.Length -= sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,9 +442,7 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
FileAttributes = 0;
|
FileAttributes = 0;
|
||||||
|
|
||||||
/* remember the main file node */
|
/* remember the main file node */
|
||||||
ASSERT(0 == FileNode->MainFileNode);
|
|
||||||
FileNode->MainFileNode = FileDesc->MainFileObject->FsContext;
|
FileNode->MainFileNode = FileDesc->MainFileObject->FsContext;
|
||||||
FspFileNodeReference(FileNode->MainFileNode);
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -505,7 +501,6 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
Request->Req.Create.HasRestorePrivilege = HasRestorePrivilege;
|
Request->Req.Create.HasRestorePrivilege = HasRestorePrivilege;
|
||||||
Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY);
|
Request->Req.Create.OpenTargetDirectory = BooleanFlagOn(Flags, SL_OPEN_TARGET_DIRECTORY);
|
||||||
Request->Req.Create.CaseSensitive = CaseSensitive;
|
Request->Req.Create.CaseSensitive = CaseSensitive;
|
||||||
Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash;
|
|
||||||
Request->Req.Create.NamedStream = MainFileName.Length;
|
Request->Req.Create.NamedStream = MainFileName.Length;
|
||||||
|
|
||||||
ASSERT(
|
ASSERT(
|
||||||
@ -823,10 +818,7 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
|
|
||||||
if (Response->Buffer + Response->Rsp.Create.Opened.FileName.Size >
|
if (Response->Buffer + Response->Rsp.Create.Opened.FileName.Size >
|
||||||
(PUINT8)Response + Response->Size)
|
(PUINT8)Response + Response->Size)
|
||||||
{
|
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
|
||||||
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
||||||
}
|
|
||||||
|
|
||||||
NormalizedName.Length = NormalizedName.MaximumLength =
|
NormalizedName.Length = NormalizedName.MaximumLength =
|
||||||
Response->Rsp.Create.Opened.FileName.Size;
|
Response->Rsp.Create.Opened.FileName.Size;
|
||||||
@ -834,10 +826,7 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
|
|
||||||
/* normalized file name can only differ in case from requested one */
|
/* normalized file name can only differ in case from requested one */
|
||||||
if (0 != FspFileNameCompare(&FileNode->FileName, &NormalizedName, TRUE, 0))
|
if (0 != FspFileNameCompare(&FileNode->FileName, &NormalizedName, TRUE, 0))
|
||||||
{
|
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
|
||||||
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
FSP_RETURN(Result = STATUS_OBJECT_NAME_INVALID);
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(FileNode->FileName.Length == NormalizedName.Length);
|
ASSERT(FileNode->FileName.Length == NormalizedName.Length);
|
||||||
RtlCopyMemory(FileNode->FileName.Buffer, NormalizedName.Buffer, NormalizedName.Length);
|
RtlCopyMemory(FileNode->FileName.Buffer, NormalizedName.Buffer, NormalizedName.Length);
|
||||||
@ -903,7 +892,6 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
/* set up the AccessState */
|
/* set up the AccessState */
|
||||||
AccessState->RemainingDesiredAccess = 0;
|
AccessState->RemainingDesiredAccess = 0;
|
||||||
AccessState->PreviouslyGrantedAccess = Response->Rsp.Create.Opened.GrantedAccess;
|
AccessState->PreviouslyGrantedAccess = Response->Rsp.Create.Opened.GrantedAccess;
|
||||||
FileDesc->GrantedAccess = Response->Rsp.Create.Opened.GrantedAccess;
|
|
||||||
|
|
||||||
/* set up the FileObject */
|
/* set up the FileObject */
|
||||||
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
@ -913,13 +901,6 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
FileObject->PrivateCacheMap = 0;
|
FileObject->PrivateCacheMap = 0;
|
||||||
FileObject->FsContext = FileNode;
|
FileObject->FsContext = FileNode;
|
||||||
FileObject->FsContext2 = FileDesc;
|
FileObject->FsContext2 = FileDesc;
|
||||||
if (!FileNode->IsDirectory)
|
|
||||||
{
|
|
||||||
/* properly set temporary bit for lazy writer */
|
|
||||||
if (FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes,
|
|
||||||
FILE_ATTRIBUTE_TEMPORARY))
|
|
||||||
SetFlag(FileObject->Flags, FO_TEMPORARY_FILE);
|
|
||||||
}
|
|
||||||
if (FspTimeoutInfinity32 == FsvolDeviceExtension->VolumeParams.FileInfoTimeout &&
|
if (FspTimeoutInfinity32 == FsvolDeviceExtension->VolumeParams.FileInfoTimeout &&
|
||||||
!FlagOn(IrpSp->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING) &&
|
!FlagOn(IrpSp->Parameters.Create.Options, FILE_NO_INTERMEDIATE_BUFFERING) &&
|
||||||
!Response->Rsp.Create.Opened.DisableCache)
|
!Response->Rsp.Create.Opened.DisableCache)
|
||||||
@ -958,19 +939,6 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
if (FileNode->IsDirectory)
|
if (FileNode->IsDirectory)
|
||||||
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
|
SetFlag(FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
|
||||||
|
|
||||||
/* overwrite/supersede operations must have the correct hidden/system attributes set */
|
|
||||||
if ((FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_HIDDEN) &&
|
|
||||||
!FlagOn(FileAttributes, FILE_ATTRIBUTE_HIDDEN)) ||
|
|
||||||
(FlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, FILE_ATTRIBUTE_SYSTEM) &&
|
|
||||||
!FlagOn(FileAttributes, FILE_ATTRIBUTE_SYSTEM)))
|
|
||||||
{
|
|
||||||
FspFsvolCreatePostClose(FileDesc);
|
|
||||||
FspFileNodeClose(FileNode, FileObject, TRUE);
|
|
||||||
|
|
||||||
Result = STATUS_ACCESS_DENIED;
|
|
||||||
FSP_RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject);
|
PVOID RequestDeviceObjectValue = FspIopRequestContext(Request, RequestDeviceObject);
|
||||||
|
|
||||||
/* disassociate the FileDesc momentarily from the Request */
|
/* disassociate the FileDesc momentarily from the Request */
|
||||||
@ -1030,11 +998,10 @@ NTSTATUS FspFsvolCreateComplete(
|
|||||||
/* file was successfully overwritten/superseded */
|
/* file was successfully overwritten/superseded */
|
||||||
if (0 == FileNode->MainFileNode)
|
if (0 == FileNode->MainFileNode)
|
||||||
FspFileNodeOverwriteStreams(FileNode);
|
FspFileNodeOverwriteStreams(FileNode);
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo);
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,
|
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE,
|
||||||
FILE_ACTION_MODIFIED,
|
FILE_ACTION_MODIFIED);
|
||||||
FALSE);
|
|
||||||
|
|
||||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||||
|
|
||||||
@ -1097,8 +1064,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Create.Opened.FileInfo,
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Create.Opened.FileInfo);
|
||||||
FILE_CREATED == Response->IoStatus.Information);
|
|
||||||
|
|
||||||
if (FlushImage)
|
if (FlushImage)
|
||||||
{
|
{
|
||||||
@ -1125,8 +1091,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re
|
|||||||
if (FILE_CREATED == Response->IoStatus.Information)
|
if (FILE_CREATED == Response->IoStatus.Information)
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_ADDED,
|
FILE_ACTION_ADDED);
|
||||||
TRUE);
|
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/debug.c
|
* @file sys/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/devctl.c
|
* @file sys/devctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/device.c
|
* @file sys/device.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -43,11 +43,9 @@ VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
|
|||||||
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||||
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||||
NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
PVOID **PContexts, PULONG PContextCount);
|
|
||||||
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
PVOID **PContexts, PULONG PContextCount);
|
PVOID **PContexts, PULONG PContextCount);
|
||||||
VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount);
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount);
|
||||||
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey);
|
BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey);
|
||||||
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
||||||
@ -82,9 +80,8 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameReleaseOwner)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFileRenameReleaseOwner)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable)
|
#pragma alloc_text(PAGE, FspFsvolDeviceLockContextTable)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable)
|
#pragma alloc_text(PAGE, FspFsvolDeviceUnlockContextTable)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextList)
|
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextByNameList)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextByNameList)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextList)
|
#pragma alloc_text(PAGE, FspFsvolDeviceDeleteContextByNameList)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceEnumerateContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceLookupContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceInsertContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceInsertContextByName)
|
||||||
@ -367,16 +364,9 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
|
|||||||
InitializeListHead(&FsvolDeviceExtension->NotifyList);
|
InitializeListHead(&FsvolDeviceExtension->NotifyList);
|
||||||
FsvolDeviceExtension->InitDoneNotify = 1;
|
FsvolDeviceExtension->InitDoneNotify = 1;
|
||||||
|
|
||||||
/* create file system statistics */
|
|
||||||
Result = FspStatisticsCreate(&FsvolDeviceExtension->Statistics);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
FsvolDeviceExtension->InitDoneStat = 1;
|
|
||||||
|
|
||||||
/* initialize our context table */
|
/* initialize our context table */
|
||||||
ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
ExInitializeResourceLite(&FsvolDeviceExtension->FileRenameResource);
|
||||||
ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
ExInitializeResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
||||||
InitializeListHead(&FsvolDeviceExtension->ContextList);
|
|
||||||
RtlInitializeGenericTableAvl(&FsvolDeviceExtension->ContextByNameTable,
|
RtlInitializeGenericTableAvl(&FsvolDeviceExtension->ContextByNameTable,
|
||||||
FspFsvolDeviceCompareContextByName,
|
FspFsvolDeviceCompareContextByName,
|
||||||
FspFsvolDeviceAllocateContextByName,
|
FspFsvolDeviceAllocateContextByName,
|
||||||
@ -418,10 +408,6 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
|
|||||||
if (FsvolDeviceExtension->InitDoneTimer)
|
if (FsvolDeviceExtension->InitDoneTimer)
|
||||||
IoStopTimer(DeviceObject);
|
IoStopTimer(DeviceObject);
|
||||||
|
|
||||||
/* delete the file system statistics */
|
|
||||||
if (FsvolDeviceExtension->InitDoneStat)
|
|
||||||
FspStatisticsDelete(FsvolDeviceExtension->Statistics);
|
|
||||||
|
|
||||||
/* uninitialize the FSRTL Notify mechanism */
|
/* uninitialize the FSRTL Notify mechanism */
|
||||||
if (FsvolDeviceExtension->InitDoneNotify)
|
if (FsvolDeviceExtension->InitDoneNotify)
|
||||||
{
|
{
|
||||||
@ -590,50 +576,6 @@ VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject)
|
|||||||
ExReleaseResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
ExReleaseResourceLite(&FsvolDeviceExtension->ContextTableResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
PVOID **PContexts, PULONG PContextCount)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(DeviceObject);
|
|
||||||
PVOID *Contexts;
|
|
||||||
ULONG ContextCount, Index;
|
|
||||||
|
|
||||||
*PContexts = 0;
|
|
||||||
*PContextCount = 0;
|
|
||||||
|
|
||||||
ContextCount = 0;
|
|
||||||
for (
|
|
||||||
PLIST_ENTRY Head = &FsvolDeviceExtension->ContextList, Entry = Head->Flink;
|
|
||||||
Head != Entry;
|
|
||||||
Entry = Entry->Flink)
|
|
||||||
{
|
|
||||||
ContextCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if ContextCount == 0 allocate an empty Context list */
|
|
||||||
Contexts = FspAlloc(sizeof(PVOID) * (0 != ContextCount ? ContextCount : 1));
|
|
||||||
if (0 == Contexts)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
Index = 0;
|
|
||||||
for (
|
|
||||||
PLIST_ENTRY Head = &FsvolDeviceExtension->ContextList, Entry = Head->Flink;
|
|
||||||
Head != Entry;
|
|
||||||
Entry = Entry->Flink)
|
|
||||||
{
|
|
||||||
ASSERT(Index < ContextCount);
|
|
||||||
Contexts[Index++] = CONTAINING_RECORD(Entry, FSP_FILE_NODE, ActiveEntry);
|
|
||||||
/* assume that Contexts can only be FSP_FILE_NODE's */
|
|
||||||
}
|
|
||||||
ASSERT(Index == ContextCount);
|
|
||||||
|
|
||||||
*PContexts = Contexts;
|
|
||||||
*PContextCount = Index;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
PVOID **PContexts, PULONG PContextCount)
|
PVOID **PContexts, PULONG PContextCount)
|
||||||
{
|
{
|
||||||
@ -668,7 +610,7 @@ NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount)
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/dirctl.c
|
* @file sys/dirctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -512,8 +512,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set the DirectoryPattern in the FileDesc */
|
/* set the DirectoryPattern in the FileDesc */
|
||||||
Result = FspFileDescResetDirectoryPattern(FileDesc, FileName,
|
Result = FspFileDescResetDirectoryPattern(FileDesc, FileName, RestartScan);
|
||||||
RestartScan && 0 != FileName && 0 != FileName->Length);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
FspFileNodeRelease(FileNode, Full);
|
FspFileNodeRelease(FileNode, Full);
|
||||||
@ -618,7 +617,6 @@ static NTSTATUS FspFsvolQueryDirectory(
|
|||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
||||||
@ -638,8 +636,7 @@ static NTSTATUS FspFsvolQueryDirectory(
|
|||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* check that FileName is valid (if supplied) */
|
/* check that FileName is valid (if supplied) */
|
||||||
if (0 != FileName &&
|
if (0 != FileName && !FspFileNameIsValidPattern(FileName))
|
||||||
!FspFileNameIsValidPattern(FileName, FsvolDeviceExtension->VolumeParams.MaxComponentLength))
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/* is this an allowed file information class? */
|
/* is this an allowed file information class? */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.c
|
* @file sys/driver.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -176,8 +176,6 @@ NTSTATUS DriverEntry(
|
|||||||
|
|
||||||
static VOID FspDriverMultiVersionInitialize(VOID)
|
static VOID FspDriverMultiVersionInitialize(VOID)
|
||||||
{
|
{
|
||||||
FspProcessorCount = KeQueryActiveProcessorCount(0);
|
|
||||||
|
|
||||||
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
|
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
|
||||||
|
|
||||||
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7))
|
if (RtlIsNtDdiVersionAvailable(NTDDI_WIN7))
|
||||||
@ -218,6 +216,5 @@ PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
|||||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||||
|
|
||||||
ULONG FspProcessorCount;
|
|
||||||
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
||||||
ULONG FspMvMdlMappingNoWrite = 0;
|
ULONG FspMvMdlMappingNoWrite = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.h
|
* @file sys/driver.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -40,7 +40,6 @@
|
|||||||
|
|
||||||
/* private NTSTATUS codes */
|
/* private NTSTATUS codes */
|
||||||
#define FSP_STATUS_PRIVATE_BIT (0x20000000)
|
#define FSP_STATUS_PRIVATE_BIT (0x20000000)
|
||||||
#define FSP_STATUS_IGNORE_BIT (0x10000000)
|
|
||||||
#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000)
|
#define FSP_STATUS_IOQ_POST (FSP_STATUS_PRIVATE_BIT | 0x0000)
|
||||||
#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001)
|
#define FSP_STATUS_IOQ_POST_BEST_EFFORT (FSP_STATUS_PRIVATE_BIT | 0x0001)
|
||||||
|
|
||||||
@ -199,7 +198,7 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result);
|
|||||||
} while (0,0)
|
} while (0,0)
|
||||||
#define FSP_LEAVE_MJ(fmt, ...) \
|
#define FSP_LEAVE_MJ(fmt, ...) \
|
||||||
FSP_LEAVE_( \
|
FSP_LEAVE_( \
|
||||||
if (STATUS_PENDING != Result && !(FSP_STATUS_IGNORE_BIT & Result))\
|
if (STATUS_PENDING != Result) \
|
||||||
{ \
|
{ \
|
||||||
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\
|
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||\
|
||||||
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\
|
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);\
|
||||||
@ -226,8 +225,6 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result);
|
|||||||
else \
|
else \
|
||||||
FspIopCompleteIrpEx(Irp, Result, fsp_device_deref);\
|
FspIopCompleteIrpEx(Irp, Result, fsp_device_deref);\
|
||||||
} \
|
} \
|
||||||
else \
|
|
||||||
Result &= ~FSP_STATUS_IGNORE_BIT;\
|
|
||||||
IoSetTopLevelIrp(fsp_top_level_irp);\
|
IoSetTopLevelIrp(fsp_top_level_irp);\
|
||||||
); \
|
); \
|
||||||
return Result
|
return Result
|
||||||
@ -440,9 +437,8 @@ enum
|
|||||||
FspFileNameStreamTypeNone = 0,
|
FspFileNameStreamTypeNone = 0,
|
||||||
FspFileNameStreamTypeData = 1,
|
FspFileNameStreamTypeData = 1,
|
||||||
};
|
};
|
||||||
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType);
|
||||||
PUNICODE_STRING StreamPart, PULONG StreamType);
|
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern);
|
||||||
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern, ULONG MaxComponentLength);
|
|
||||||
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
||||||
#if 0
|
#if 0
|
||||||
NTSTATUS FspFileNameUpcase(
|
NTSTATUS FspFileNameUpcase(
|
||||||
@ -914,7 +910,7 @@ BOOLEAN FspIopRetryCompleteIrp(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
|||||||
VOID FspIopSetIrpResponse(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
VOID FspIopSetIrpResponse(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp);
|
FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp);
|
||||||
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
NTSTATUS FspIopDispatchComplete(PIRP Irp, FSP_FSCTL_TRANSACT_RSP *Response);
|
NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
static inline
|
static inline
|
||||||
VOID FspIrpDeleteRequest(PIRP Irp)
|
VOID FspIrpDeleteRequest(PIRP Irp)
|
||||||
{
|
{
|
||||||
@ -952,21 +948,6 @@ VOID FspWqPostIrpWorkItem(PIRP Irp);
|
|||||||
#define FspWqRepostIrpWorkItem(I, RW, RF)\
|
#define FspWqRepostIrpWorkItem(I, RW, RF)\
|
||||||
FspWqCreateAndPostIrpWorkItem(I, RW, RF, TRUE)
|
FspWqCreateAndPostIrpWorkItem(I, RW, RF, TRUE)
|
||||||
|
|
||||||
/* file system statistics */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
FILESYSTEM_STATISTICS Base;
|
|
||||||
FAT_STATISTICS Specific; /* pretend that we are FAT when it comes to stats */
|
|
||||||
/* align to 64 bytes */
|
|
||||||
__declspec(align(64)) UINT8 EndOfStruct[];
|
|
||||||
} FSP_STATISTICS;
|
|
||||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics);
|
|
||||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics);
|
|
||||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength);
|
|
||||||
#define FspStatistics(S) (&(S)[KeGetCurrentProcessorNumber() % FspProcessorCount])
|
|
||||||
#define FspStatisticsInc(S,F) ((S)->F++)
|
|
||||||
#define FspStatisticsAdd(S,F,V) ((S)->F += (V))
|
|
||||||
|
|
||||||
/* device management */
|
/* device management */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -1008,7 +989,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1,
|
UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1,
|
||||||
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
|
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1;
|
||||||
PDEVICE_OBJECT FsctlDeviceObject;
|
PDEVICE_OBJECT FsctlDeviceObject;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
HANDLE MupHandle;
|
HANDLE MupHandle;
|
||||||
@ -1025,7 +1006,6 @@ typedef struct
|
|||||||
BOOLEAN ExpirationInProgress;
|
BOOLEAN ExpirationInProgress;
|
||||||
ERESOURCE FileRenameResource;
|
ERESOURCE FileRenameResource;
|
||||||
ERESOURCE ContextTableResource;
|
ERESOURCE ContextTableResource;
|
||||||
LIST_ENTRY ContextList;
|
|
||||||
RTL_AVL_TABLE ContextByNameTable;
|
RTL_AVL_TABLE ContextByNameTable;
|
||||||
PVOID ContextByNameTableElementStorage;
|
PVOID ContextByNameTableElementStorage;
|
||||||
UNICODE_STRING VolumeName;
|
UNICODE_STRING VolumeName;
|
||||||
@ -1035,7 +1015,6 @@ typedef struct
|
|||||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
PNOTIFY_SYNC NotifySync;
|
PNOTIFY_SYNC NotifySync;
|
||||||
LIST_ENTRY NotifyList;
|
LIST_ENTRY NotifyList;
|
||||||
FSP_STATISTICS *Statistics;
|
|
||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
static inline
|
static inline
|
||||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||||
@ -1066,11 +1045,9 @@ VOID FspFsvolDeviceFileRenameRelease(PDEVICE_OBJECT DeviceObject);
|
|||||||
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
VOID FspFsvolDeviceFileRenameReleaseOwner(PDEVICE_OBJECT DeviceObject, PVOID Owner);
|
||||||
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceLockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceUnlockContextTable(PDEVICE_OBJECT DeviceObject);
|
||||||
NTSTATUS FspFsvolDeviceCopyContextList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
PVOID **PContexts, PULONG PContextCount);
|
|
||||||
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFsvolDeviceCopyContextByNameList(PDEVICE_OBJECT DeviceObject,
|
||||||
PVOID **PContexts, PULONG PContextCount);
|
PVOID **PContexts, PULONG PContextCount);
|
||||||
VOID FspFsvolDeviceDeleteContextList(PVOID *Contexts, ULONG ContextCount);
|
VOID FspFsvolDeviceDeleteContextByNameList(PVOID *Contexts, ULONG ContextCount);
|
||||||
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
PVOID FspFsvolDeviceEnumerateContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName,
|
||||||
BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey);
|
BOOLEAN NextFlag, FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY *RestartKey);
|
||||||
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
PVOID FspFsvolDeviceLookupContextByName(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING FileName);
|
||||||
@ -1105,8 +1082,6 @@ VOID FspDeviceGlobalUnlock(VOID)
|
|||||||
extern ERESOURCE FspDeviceGlobalResource;
|
extern ERESOURCE FspDeviceGlobalResource;
|
||||||
ExReleaseResourceLite(&FspDeviceGlobalResource);
|
ExReleaseResourceLite(&FspDeviceGlobalResource);
|
||||||
}
|
}
|
||||||
#define FspFsvolDeviceStatistics(DeviceObject)\
|
|
||||||
FspStatistics(FspFsvolDeviceExtension(DeviceObject)->Statistics)
|
|
||||||
#define FspFsvolDeviceStoppedStatus(DeviceObject)\
|
#define FspFsvolDeviceStoppedStatus(DeviceObject)\
|
||||||
STATUS_VOLUME_DISMOUNTED
|
STATUS_VOLUME_DISMOUNTED
|
||||||
//(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\
|
//(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\
|
||||||
@ -1172,13 +1147,11 @@ typedef struct FSP_FILE_NODE
|
|||||||
LONG RefCount;
|
LONG RefCount;
|
||||||
UINT32 DeletePending;
|
UINT32 DeletePending;
|
||||||
/* locked under FSP_FSVOL_DEVICE_EXTENSION::ContextTableResource */
|
/* locked under FSP_FSVOL_DEVICE_EXTENSION::ContextTableResource */
|
||||||
LONG ActiveCount; /* CREATE w/o CLOSE count */
|
|
||||||
LONG OpenCount; /* ContextTable ref count */
|
LONG OpenCount; /* ContextTable ref count */
|
||||||
LONG HandleCount; /* HANDLE count (CREATE/CLEANUP) */
|
LONG HandleCount; /* HANDLE count (CREATE/CLEANUP) */
|
||||||
SHARE_ACCESS ShareAccess;
|
SHARE_ACCESS ShareAccess;
|
||||||
ULONG MainFileDenyDeleteCount; /* number of times main file is denying delete */
|
ULONG MainFileDenyDeleteCount; /* number of times main file is denying delete */
|
||||||
ULONG StreamDenyDeleteCount; /* number of times open streams are denying delete */
|
ULONG StreamDenyDeleteCount; /* number of times open streams are denying delete */
|
||||||
LIST_ENTRY ActiveEntry;
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT ContextByNameElementStorage;
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_ELEMENT ContextByNameElementStorage;
|
||||||
/* locked under FSP_FSVOL_DEVICE_EXTENSION::FileRenameResource or Header.Resource */
|
/* locked under FSP_FSVOL_DEVICE_EXTENSION::FileRenameResource or Header.Resource */
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
@ -1216,20 +1189,17 @@ typedef struct FSP_FILE_NODE
|
|||||||
UINT64 IndexNumber;
|
UINT64 IndexNumber;
|
||||||
BOOLEAN IsDirectory;
|
BOOLEAN IsDirectory;
|
||||||
BOOLEAN IsRootDirectory;
|
BOOLEAN IsRootDirectory;
|
||||||
struct FSP_FILE_NODE *MainFileNode;
|
struct FSP_FILE_NODE *MainFileNode; /* this becomes invalid after our last desc close */
|
||||||
WCHAR FileNameBuf[];
|
WCHAR FileNameBuf[];
|
||||||
} FSP_FILE_NODE;
|
} FSP_FILE_NODE;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
UINT32 GrantedAccess;
|
BOOLEAN CaseSensitive;
|
||||||
UINT32
|
BOOLEAN HasTraversePrivilege;
|
||||||
CaseSensitive:1, HasTraversePrivilege:1, DeleteOnClose:1,
|
BOOLEAN DeleteOnClose;
|
||||||
DidSetMetadata:1,
|
BOOLEAN DirectoryHasSuchFile;
|
||||||
DidSetFileAttributes:1, DidSetReparsePoint:1, DidSetSecurity:1,
|
|
||||||
DidSetCreationTime:1, DidSetLastAccessTime:1, DidSetLastWriteTime:1, DidSetChangeTime:1,
|
|
||||||
DirectoryHasSuchFile:1;
|
|
||||||
UNICODE_STRING DirectoryPattern;
|
UNICODE_STRING DirectoryPattern;
|
||||||
UINT64 DirectoryOffset;
|
UINT64 DirectoryOffset;
|
||||||
UINT64 DirInfo;
|
UINT64 DirInfo;
|
||||||
@ -1238,9 +1208,7 @@ typedef struct
|
|||||||
HANDLE MainFileHandle;
|
HANDLE MainFileHandle;
|
||||||
PFILE_OBJECT MainFileObject;
|
PFILE_OBJECT MainFileObject;
|
||||||
} FSP_FILE_DESC;
|
} FSP_FILE_DESC;
|
||||||
NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
|
||||||
NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
||||||
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
@ -1290,7 +1258,8 @@ VOID FspFileNodeReleaseForeign(FSP_FILE_NODE *FileNode)
|
|||||||
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
UINT32 GrantedAccess, UINT32 ShareAccess,
|
UINT32 GrantedAccess, UINT32 ShareAccess,
|
||||||
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
PBOOLEAN PDeletePending);
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
||||||
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
||||||
@ -1311,10 +1280,9 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
|||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose);
|
const FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
|
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
|
||||||
VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode);
|
|
||||||
static inline
|
static inline
|
||||||
ULONG FspFileNodeFileInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
ULONG FspFileNodeFileInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
@ -1344,7 +1312,6 @@ ULONG FspFileNodeDirInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
|||||||
{
|
{
|
||||||
return FileNode->DirInfoChangeNumber;
|
return FileNode->DirInfoChangeNumber;
|
||||||
}
|
}
|
||||||
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode);
|
|
||||||
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
||||||
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
||||||
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||||
@ -1356,9 +1323,7 @@ ULONG FspFileNodeStreamInfoChangeNumber(FSP_FILE_NODE *FileNode)
|
|||||||
FileNode = FileNode->MainFileNode;
|
FileNode = FileNode->MainFileNode;
|
||||||
return FileNode->StreamInfoChangeNumber;
|
return FileNode->StreamInfoChangeNumber;
|
||||||
}
|
}
|
||||||
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action);
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
|
||||||
BOOLEAN InvalidateCaches);
|
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||||
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||||
@ -1518,7 +1483,6 @@ extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
|||||||
extern ERESOURCE FspDeviceGlobalResource;
|
extern ERESOURCE FspDeviceGlobalResource;
|
||||||
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
|
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
|
||||||
extern const GUID FspMainFileOpenEcpGuid;
|
extern const GUID FspMainFileOpenEcpGuid;
|
||||||
extern ULONG FspProcessorCount;
|
|
||||||
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
extern FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
||||||
extern ULONG FspMvMdlMappingNoWrite;
|
extern ULONG FspMvMdlMappingNoWrite;
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
[Version]
|
|
||||||
Signature = "$WINDOWS NT$"
|
|
||||||
Class = Volume
|
|
||||||
ClassGuid = {71a27cdd-812a-11d0-bec7-08002be2092f}
|
|
||||||
CatalogFile = !CatalogFile!
|
|
||||||
Provider = !Provider!
|
|
||||||
|
|
||||||
[DestinationDirs]
|
|
||||||
DefaultDestDir = 12
|
|
||||||
|
|
||||||
[DefaultInstall]
|
|
||||||
CopyFiles = Driver.CopyFiles
|
|
||||||
|
|
||||||
[Driver.CopyFiles]
|
|
||||||
!DriverFile!
|
|
||||||
|
|
||||||
[SourceDisksFiles]
|
|
||||||
!DriverFile! = 1
|
|
||||||
|
|
||||||
[SourceDisksNames]
|
|
||||||
1 = Disk1
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/ea.c
|
* @file sys/ea.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
401
src/sys/file.c
401
src/sys/file.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/file.c
|
* @file sys/file.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
|
||||||
NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount);
|
||||||
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount);
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
@ -36,7 +34,8 @@ VOID FspFileNodeReleaseOwnerF(FSP_FILE_NODE *FileNode, ULONG Flags, PVOID Owner)
|
|||||||
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
UINT32 GrantedAccess, UINT32 ShareAccess,
|
UINT32 GrantedAccess, UINT32 ShareAccess,
|
||||||
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
FSP_FILE_NODE **POpenedFileNode, PULONG PSharingViolationReason);
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags);
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
PBOOLEAN PDeletePending);
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject);
|
||||||
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
||||||
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
PFILE_OBJECT FileObject, /* non-0 to remove share access */
|
||||||
@ -57,10 +56,9 @@ VOID FspFileNodeRename(FSP_FILE_NODE *FileNode, PUNICODE_STRING NewFileName);
|
|||||||
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose);
|
const FSP_FSCTL_FILE_INFO *FileInfo);
|
||||||
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
|
const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber);
|
||||||
VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode);
|
|
||||||
BOOLEAN FspFileNodeReferenceSecurity(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
BOOLEAN FspFileNodeReferenceSecurity(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
||||||
VOID FspFileNodeSetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
VOID FspFileNodeSetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
||||||
BOOLEAN FspFileNodeTrySetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
BOOLEAN FspFileNodeTrySetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||||
@ -70,16 +68,13 @@ VOID FspFileNodeSetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
|||||||
BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
BOOLEAN FspFileNodeTrySetDirInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||||
ULONG DirInfoChangeNumber);
|
ULONG DirInfoChangeNumber);
|
||||||
static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode);
|
static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode);
|
||||||
static VOID FspFileNodeInvalidateDirInfoByName(PDEVICE_OBJECT FsvolDeviceObject,
|
|
||||||
PUNICODE_STRING FileName);
|
|
||||||
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode);
|
|
||||||
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize);
|
||||||
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
VOID FspFileNodeSetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size);
|
||||||
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||||
ULONG StreamInfoChangeNumber);
|
ULONG StreamInfoChangeNumber);
|
||||||
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
||||||
BOOLEAN InvalidateCaches);
|
ULONG Filter, ULONG Action);
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||||
@ -102,8 +97,7 @@ VOID FspFileNodeOplockPrepare(PVOID Context, PIRP Irp);
|
|||||||
VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCopyActiveList)
|
#pragma alloc_text(PAGE, FspFileNodeCopyList)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCopyOpenList)
|
|
||||||
#pragma alloc_text(PAGE, FspFileNodeDeleteList)
|
#pragma alloc_text(PAGE, FspFileNodeDeleteList)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCreate)
|
#pragma alloc_text(PAGE, FspFileNodeCreate)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeDelete)
|
#pragma alloc_text(PAGE, FspFileNodeDelete)
|
||||||
@ -128,7 +122,6 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
|||||||
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeSetFileInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeTrySetFileInfo)
|
#pragma alloc_text(PAGE, FspFileNodeTrySetFileInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeInvalidateFileInfo)
|
|
||||||
#pragma alloc_text(PAGE, FspFileNodeReferenceSecurity)
|
#pragma alloc_text(PAGE, FspFileNodeReferenceSecurity)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeSetSecurity)
|
#pragma alloc_text(PAGE, FspFileNodeSetSecurity)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeTrySetSecurity)
|
#pragma alloc_text(PAGE, FspFileNodeTrySetSecurity)
|
||||||
@ -136,8 +129,6 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
|||||||
// !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeSetDirInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeTrySetDirInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeInvalidateDirInfoByName)
|
|
||||||
#pragma alloc_text(PAGE, FspFileNodeInvalidateParentDirInfo)
|
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeReferenceStreamInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeReferenceStreamInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeSetStreamInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeSetStreamInfo)
|
||||||
// !#pragma alloc_text(PAGE, FspFileNodeTrySetStreamInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeTrySetStreamInfo)
|
||||||
@ -171,86 +162,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
|||||||
if (IrpValid) \
|
if (IrpValid) \
|
||||||
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3))
|
FspIrpSetFlags(Irp, FspIrpFlags(Irp) & (~Flags & 3))
|
||||||
|
|
||||||
#define GATHER_DESCENDANTS(FILENAME, REFERENCE, ...)\
|
NTSTATUS FspFileNodeCopyList(PDEVICE_OBJECT DeviceObject,
|
||||||
FSP_FILE_NODE *DescendantFileNode;\
|
|
||||||
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;\
|
|
||||||
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;\
|
|
||||||
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;\
|
|
||||||
DescendantFileNodes = DescendantFileNodeArray;\
|
|
||||||
DescendantFileNodeCount = 0;\
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);\
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,\
|
|
||||||
FILENAME, FALSE, &RestartKey);\
|
|
||||||
if (0 == DescendantFileNode) \
|
|
||||||
break; \
|
|
||||||
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
|
||||||
__VA_ARGS__; \
|
|
||||||
if (REFERENCE) \
|
|
||||||
FspFileNodeReference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)\
|
|
||||||
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;\
|
|
||||||
DescendantFileNodeCount++; \
|
|
||||||
} \
|
|
||||||
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount ||\
|
|
||||||
DEBUGTEST_EX(0 != DescendantFileNodeCount, 10, FALSE)) \
|
|
||||||
{ \
|
|
||||||
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));\
|
|
||||||
DescendantFileNodeIndex = 0; \
|
|
||||||
memset(&RestartKey, 0, sizeof RestartKey);\
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,\
|
|
||||||
FILENAME, FALSE, &RestartKey);\
|
|
||||||
if (0 == DescendantFileNode)\
|
|
||||||
break; \
|
|
||||||
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
|
||||||
__VA_ARGS__; \
|
|
||||||
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;\
|
|
||||||
DescendantFileNodeIndex++; \
|
|
||||||
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);\
|
|
||||||
} \
|
|
||||||
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);\
|
|
||||||
} \
|
|
||||||
((VOID)0)
|
|
||||||
#define SCATTER_DESCENDANTS(REFERENCE) \
|
|
||||||
if (REFERENCE) \
|
|
||||||
{ \
|
|
||||||
for ( \
|
|
||||||
DescendantFileNodeIndex = 0;\
|
|
||||||
DescendantFileNodeCount > DescendantFileNodeIndex;\
|
|
||||||
DescendantFileNodeIndex++) \
|
|
||||||
{ \
|
|
||||||
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];\
|
|
||||||
FspFileNodeDereference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
if (DescendantFileNodeArray != DescendantFileNodes)\
|
|
||||||
FspFree(DescendantFileNodes); \
|
|
||||||
((VOID)0)
|
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCopyActiveList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(DeviceObject);
|
|
||||||
Result = FspFsvolDeviceCopyContextList(DeviceObject, PFileNodes, PFileNodeCount);
|
|
||||||
if (NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
for (Index = 0; *PFileNodeCount > Index; Index++)
|
|
||||||
FspFileNodeReference((*PFileNodes)[Index]);
|
|
||||||
}
|
|
||||||
FspFsvolDeviceUnlockContextTable(DeviceObject);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCopyOpenList(PDEVICE_OBJECT DeviceObject,
|
|
||||||
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount)
|
FSP_FILE_NODE ***PFileNodes, PULONG PFileNodeCount)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -279,7 +191,7 @@ VOID FspFileNodeDeleteList(FSP_FILE_NODE **FileNodes, ULONG FileNodeCount)
|
|||||||
for (Index = 0; FileNodeCount > Index; Index++)
|
for (Index = 0; FileNodeCount > Index; Index++)
|
||||||
FspFileNodeDereference(FileNodes[Index]);
|
FspFileNodeDereference(FileNodes[Index]);
|
||||||
|
|
||||||
FspFsvolDeviceDeleteContextList(FileNodes, FileNodeCount);
|
FspFsvolDeviceDeleteContextByNameList(FileNodes, FileNodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
|
||||||
@ -336,9 +248,6 @@ VOID FspFileNodeDelete(FSP_FILE_NODE *FileNode)
|
|||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
||||||
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
|
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
|
||||||
|
|
||||||
if (0 != FileNode->MainFileNode)
|
|
||||||
FspFileNodeDereference(FileNode->MainFileNode);
|
|
||||||
|
|
||||||
FsRtlUninitializeOplock(FspFileNodeAddrOfOplock(FileNode));
|
FsRtlUninitializeOplock(FspFileNodeAddrOfOplock(FileNode));
|
||||||
FsRtlUninitializeFileLock(&FileNode->FileLock);
|
FsRtlUninitializeFileLock(&FileNode->FileLock);
|
||||||
|
|
||||||
@ -715,14 +624,6 @@ exit:
|
|||||||
if (0 != OpenedFileNode)
|
if (0 != OpenedFileNode)
|
||||||
{
|
{
|
||||||
FspFileNodeReference(OpenedFileNode);
|
FspFileNodeReference(OpenedFileNode);
|
||||||
|
|
||||||
ASSERT(0 <= OpenedFileNode->ActiveCount);
|
|
||||||
ASSERT(0 <= OpenedFileNode->OpenCount);
|
|
||||||
ASSERT(0 <= OpenedFileNode->HandleCount);
|
|
||||||
|
|
||||||
if (0 == OpenedFileNode->ActiveCount++)
|
|
||||||
InsertTailList(&FspFsvolDeviceExtension(FsvolDeviceObject)->ContextList,
|
|
||||||
&FileNode->ActiveEntry);
|
|
||||||
OpenedFileNode->OpenCount++;
|
OpenedFileNode->OpenCount++;
|
||||||
OpenedFileNode->HandleCount++;
|
OpenedFileNode->HandleCount++;
|
||||||
}
|
}
|
||||||
@ -734,7 +635,8 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG PCleanupFlags)
|
VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
|
||||||
|
PBOOLEAN PDeletePending)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Determine whether a FileNode should be deleted. Note that when FileNode->DeletePending
|
* Determine whether a FileNode should be deleted. Note that when FileNode->DeletePending
|
||||||
@ -748,7 +650,7 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG
|
|||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
BOOLEAN DeletePending, SetAllocationSize, SingleHandle;
|
BOOLEAN DeletePending, SingleHandle;
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
@ -757,13 +659,12 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG
|
|||||||
DeletePending = 0 != FileNode->DeletePending;
|
DeletePending = 0 != FileNode->DeletePending;
|
||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
|
|
||||||
SetAllocationSize = !DeletePending && FileNode->TruncateOnClose;
|
|
||||||
|
|
||||||
SingleHandle = 1 == FileNode->HandleCount;
|
SingleHandle = 1 == FileNode->HandleCount;
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
*PCleanupFlags = SingleHandle ? DeletePending | (SetAllocationSize << 1) : 0;
|
if (0 != PDeletePending)
|
||||||
|
*PDeletePending = SingleHandle && DeletePending;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
|
VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
|
||||||
@ -783,7 +684,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
LARGE_INTEGER TruncateSize, *PTruncateSize = 0;
|
LARGE_INTEGER TruncateSize = { 0 }, *PTruncateSize = 0;
|
||||||
BOOLEAN DeletePending;
|
BOOLEAN DeletePending;
|
||||||
BOOLEAN DeletedFromContextTable = FALSE;
|
BOOLEAN DeletedFromContextTable = FALSE;
|
||||||
|
|
||||||
@ -807,7 +708,6 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
|
|
||||||
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
|
IoRemoveShareAccess(FileObject, &FileNode->ShareAccess);
|
||||||
|
|
||||||
ASSERT(0 < FileNode->HandleCount);
|
|
||||||
if (0 == --FileNode->HandleCount)
|
if (0 == --FileNode->HandleCount)
|
||||||
{
|
{
|
||||||
DeletePending = 0 != FileNode->DeletePending;
|
DeletePending = 0 != FileNode->DeletePending;
|
||||||
@ -815,72 +715,23 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
|
|||||||
|
|
||||||
if (DeletePending)
|
if (DeletePending)
|
||||||
{
|
{
|
||||||
|
PTruncateSize = &TruncateSize;
|
||||||
|
|
||||||
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,
|
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &FileNode->FileName,
|
||||||
&DeletedFromContextTable);
|
&DeletedFromContextTable);
|
||||||
ASSERT(DeletedFromContextTable);
|
ASSERT(DeletedFromContextTable);
|
||||||
|
|
||||||
FileNode->OpenCount = 0;
|
FileNode->OpenCount = 0;
|
||||||
FileNode->Header.FileSize.QuadPart = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We now have to deal with the scenario where there are cleaned up,
|
|
||||||
* but unclosed streams for this file still in the context table.
|
|
||||||
*/
|
|
||||||
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.NamedStreams &&
|
|
||||||
0 == FileNode->MainFileNode)
|
|
||||||
{
|
|
||||||
BOOLEAN StreamDeletedFromContextTable;
|
|
||||||
USHORT FileNameLength = FileNode->FileName.Length;
|
|
||||||
|
|
||||||
GATHER_DESCENDANTS(&FileNode->FileName, FALSE,
|
|
||||||
if (DescendantFileNode->FileName.Length > FileNameLength &&
|
|
||||||
L'\\' == DescendantFileNode->FileName.Buffer[FileNameLength / sizeof(WCHAR)])
|
|
||||||
break;
|
|
||||||
ASSERT(FileNode != DescendantFileNode);
|
|
||||||
ASSERT(0 != DescendantFileNode->OpenCount);
|
|
||||||
ASSERT(0 == DescendantFileNode->HandleCount);
|
|
||||||
);
|
|
||||||
|
|
||||||
for (
|
|
||||||
DescendantFileNodeIndex = 0;
|
|
||||||
DescendantFileNodeCount > DescendantFileNodeIndex;
|
|
||||||
DescendantFileNodeIndex++)
|
|
||||||
{
|
|
||||||
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
|
|
||||||
|
|
||||||
FspFsvolDeviceDeleteContextByName(FsvolDeviceObject, &DescendantFileNode->FileName,
|
|
||||||
&StreamDeletedFromContextTable);
|
|
||||||
if (StreamDeletedFromContextTable)
|
|
||||||
{
|
|
||||||
DescendantFileNode->OpenCount = 0;
|
|
||||||
FspFileNodeDereference(DescendantFileNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SCATTER_DESCENDANTS(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (FileNode->TruncateOnClose && FlagOn(FileObject->Flags, FO_CACHE_SUPPORTED))
|
||||||
if (DeletePending || FileNode->TruncateOnClose)
|
|
||||||
{
|
{
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension =
|
|
||||||
FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
UINT64 AllocationUnit =
|
|
||||||
FsvolDeviceExtension->VolumeParams.SectorSize *
|
|
||||||
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even when the FileInfo is expired, this is the best guess for a file size
|
* Even when the FileInfo is expired, this is the best guess for a file size
|
||||||
* without asking the user-mode file system.
|
* without asking the user-mode file system.
|
||||||
*/
|
*/
|
||||||
TruncateSize = FileNode->Header.FileSize;
|
TruncateSize = FileNode->Header.FileSize;
|
||||||
PTruncateSize = &TruncateSize;
|
PTruncateSize = &TruncateSize;
|
||||||
|
|
||||||
FileNode->Header.AllocationSize.QuadPart = (TruncateSize.QuadPart + AllocationUnit - 1)
|
|
||||||
/ AllocationUnit * AllocationUnit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileNode->TruncateOnClose = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
@ -940,15 +791,6 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode,
|
|||||||
ASSERT(DeletedFromContextTable);
|
ASSERT(DeletedFromContextTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(0 < FileNode->ActiveCount);
|
|
||||||
if (0 == --FileNode->ActiveCount)
|
|
||||||
{
|
|
||||||
ASSERT(0 == FileNode->OpenCount);
|
|
||||||
ASSERT(0 == FileNode->HandleCount);
|
|
||||||
|
|
||||||
RemoveEntryList(&FileNode->ActiveEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
if (DeletedFromContextTable)
|
if (DeletedFromContextTable)
|
||||||
@ -1012,6 +854,65 @@ NTSTATUS FspFileNodeFlushAndPurgeCache(FSP_FILE_NODE *FileNode,
|
|||||||
return IoStatus.Status;
|
return IoStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GATHER_DESCENDANTS(FILENAME, REFERENCE, ...)\
|
||||||
|
FSP_FILE_NODE *DescendantFileNode;\
|
||||||
|
FSP_FILE_NODE *DescendantFileNodeArray[16], **DescendantFileNodes;\
|
||||||
|
ULONG DescendantFileNodeCount, DescendantFileNodeIndex;\
|
||||||
|
FSP_DEVICE_CONTEXT_BY_NAME_TABLE_RESTART_KEY RestartKey;\
|
||||||
|
DescendantFileNodes = DescendantFileNodeArray;\
|
||||||
|
DescendantFileNodeCount = 0;\
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);\
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,\
|
||||||
|
FILENAME, FALSE, &RestartKey);\
|
||||||
|
if (0 == DescendantFileNode) \
|
||||||
|
break; \
|
||||||
|
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
||||||
|
__VA_ARGS__; \
|
||||||
|
if (REFERENCE) \
|
||||||
|
FspFileNodeReference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) > DescendantFileNodeCount)\
|
||||||
|
DescendantFileNodes[DescendantFileNodeCount] = DescendantFileNode;\
|
||||||
|
DescendantFileNodeCount++; \
|
||||||
|
} \
|
||||||
|
if (ARRAYSIZE(DescendantFileNodeArray) < DescendantFileNodeCount ||\
|
||||||
|
DEBUGTEST_EX(0 != DescendantFileNodeCount, 10, FALSE)) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNodes = FspAllocMustSucceed(DescendantFileNodeCount * sizeof(FSP_FILE_NODE *));\
|
||||||
|
DescendantFileNodeIndex = 0; \
|
||||||
|
memset(&RestartKey, 0, sizeof RestartKey);\
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNode = FspFsvolDeviceEnumerateContextByName(FsvolDeviceObject,\
|
||||||
|
FILENAME, FALSE, &RestartKey);\
|
||||||
|
if (0 == DescendantFileNode)\
|
||||||
|
break; \
|
||||||
|
ASSERT(0 == ((UINT_PTR)DescendantFileNode & 7));\
|
||||||
|
__VA_ARGS__; \
|
||||||
|
DescendantFileNodes[DescendantFileNodeIndex] = DescendantFileNode;\
|
||||||
|
DescendantFileNodeIndex++; \
|
||||||
|
ASSERT(DescendantFileNodeCount >= DescendantFileNodeIndex);\
|
||||||
|
} \
|
||||||
|
ASSERT(DescendantFileNodeCount == DescendantFileNodeIndex);\
|
||||||
|
} \
|
||||||
|
((VOID)0)
|
||||||
|
#define SCATTER_DESCENDANTS(REFERENCE) \
|
||||||
|
if (REFERENCE) \
|
||||||
|
{ \
|
||||||
|
for ( \
|
||||||
|
DescendantFileNodeIndex = 0;\
|
||||||
|
DescendantFileNodeCount > DescendantFileNodeIndex;\
|
||||||
|
DescendantFileNodeIndex++) \
|
||||||
|
{ \
|
||||||
|
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];\
|
||||||
|
FspFileNodeDereference((PVOID)((UINT_PTR)DescendantFileNode & ~7));\
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (DescendantFileNodeArray != DescendantFileNodes)\
|
||||||
|
FspFree(DescendantFileNodes); \
|
||||||
|
((VOID)0)
|
||||||
|
|
||||||
VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode)
|
VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1336,7 +1237,8 @@ NTSTATUS FspFileNodeRenameCheck(PDEVICE_OBJECT FsvolDeviceObject, PIRP OplockIrp
|
|||||||
if (0 == DescendantFileNode)
|
if (0 == DescendantFileNode)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (DescendantFileNode != FileNode && 0 < DescendantFileNode->HandleCount)
|
/* if this is the FileNode being renamed then HandleCount must be 1, else 0 */
|
||||||
|
if ((DescendantFileNode == FileNode) < DescendantFileNode->HandleCount)
|
||||||
{
|
{
|
||||||
/* release the FileNode in case of failure! */
|
/* release the FileNode in case of failure! */
|
||||||
FspFileNodeReleaseF(FileNode, AcquireFlags);
|
FspFileNodeReleaseF(FileNode, AcquireFlags);
|
||||||
@ -1504,7 +1406,7 @@ BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *
|
|||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
||||||
const FSP_FSCTL_FILE_INFO *FileInfo, BOOLEAN TruncateOnClose)
|
const FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
@ -1518,20 +1420,8 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject,
|
|||||||
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
|
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
|
||||||
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
||||||
|
|
||||||
if (TruncateOnClose)
|
FileNode->Header.AllocationSize.QuadPart = AllocationSize;
|
||||||
{
|
FileNode->Header.FileSize.QuadPart = FileInfo->FileSize;
|
||||||
if ((UINT64)FileNode->Header.AllocationSize.QuadPart != AllocationSize ||
|
|
||||||
(UINT64)FileNode->Header.FileSize.QuadPart != FileInfo->FileSize)
|
|
||||||
FileNode->TruncateOnClose = TRUE;
|
|
||||||
|
|
||||||
FileNode->Header.AllocationSize.QuadPart = AllocationSize;
|
|
||||||
FileNode->Header.FileSize.QuadPart = FileInfo->FileSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FileNode->Header.AllocationSize.QuadPart = AllocationSize;
|
|
||||||
FileNode->Header.FileSize.QuadPart = FileInfo->FileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileNode->FileInfoExpirationTime = FileNode->BasicInfoExpirationTime =
|
FileNode->FileInfoExpirationTime = FileNode->BasicInfoExpirationTime =
|
||||||
FspExpirationTimeFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout);
|
FspExpirationTimeFromMillis(FsvolDeviceExtension->VolumeParams.FileInfoTimeout);
|
||||||
@ -1621,20 +1511,10 @@ BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileOb
|
|||||||
if (FspFileNodeFileInfoChangeNumber(FileNode) != InfoChangeNumber)
|
if (FspFileNodeFileInfoChangeNumber(FileNode) != InfoChangeNumber)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
FspFileNodeSetFileInfo(FileNode, CcFileObject, FileInfo, FALSE);
|
FspFileNodeSetFileInfo(FileNode, CcFileObject, FileInfo);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeInvalidateFileInfo(FSP_FILE_NODE *FileNode)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FileNode->FileInfoExpirationTime = FileNode->BasicInfoExpirationTime = 0;
|
|
||||||
|
|
||||||
if (0 != FileNode->MainFileNode)
|
|
||||||
FileNode->MainFileNode->BasicInfoExpirationTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN FspFileNodeReferenceSecurity(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
|
BOOLEAN FspFileNodeReferenceSecurity(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -1747,40 +1627,6 @@ static VOID FspFileNodeInvalidateDirInfo(FSP_FILE_NODE *FileNode)
|
|||||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, DirInfo);
|
FspMetaCacheInvalidateItem(FsvolDeviceExtension->DirInfoCache, DirInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID FspFileNodeInvalidateDirInfoByName(PDEVICE_OBJECT FsvolDeviceObject,
|
|
||||||
PUNICODE_STRING FileName)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FSP_FILE_NODE *FileNode;
|
|
||||||
|
|
||||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
|
||||||
FileNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, FileName);
|
|
||||||
if (0 != FileNode)
|
|
||||||
FspFileNodeReference(FileNode);
|
|
||||||
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
|
||||||
|
|
||||||
if (0 != FileNode)
|
|
||||||
{
|
|
||||||
FspFileNodeInvalidateDirInfo(FileNode);
|
|
||||||
FspFileNodeDereference(FileNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspFileNodeInvalidateParentDirInfo(FSP_FILE_NODE *FileNode)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
if (sizeof(WCHAR) == FileNode->FileName.Length && L'\\' == FileNode->FileName.Buffer[0])
|
|
||||||
return; /* root does not have a parent */
|
|
||||||
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
|
||||||
UNICODE_STRING Parent, Suffix;
|
|
||||||
|
|
||||||
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
|
|
||||||
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
|
BOOLEAN FspFileNodeReferenceStreamInfo(FSP_FILE_NODE *FileNode, PCVOID *PBuffer, PULONG PSize)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
@ -1839,7 +1685,7 @@ BOOLEAN FspFileNodeTrySetStreamInfo(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULON
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
static VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
||||||
{
|
{
|
||||||
// !PAGED_CODE();
|
// !PAGED_CODE();
|
||||||
|
|
||||||
@ -1860,8 +1706,8 @@ VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode)
|
|||||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
|
FspMetaCacheInvalidateItem(FsvolDeviceExtension->StreamInfoCache, StreamInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode,
|
||||||
BOOLEAN InvalidateCaches)
|
ULONG Filter, ULONG Action)
|
||||||
{
|
{
|
||||||
/* FileNode must be acquired (exclusive or shared) Main */
|
/* FileNode must be acquired (exclusive or shared) Main */
|
||||||
|
|
||||||
@ -1870,6 +1716,32 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
UNICODE_STRING Parent, Suffix;
|
UNICODE_STRING Parent, Suffix;
|
||||||
|
FSP_FILE_NODE *ParentNode;
|
||||||
|
|
||||||
|
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
|
||||||
|
|
||||||
|
switch (Action)
|
||||||
|
{
|
||||||
|
case FILE_ACTION_ADDED:
|
||||||
|
case FILE_ACTION_REMOVED:
|
||||||
|
//case FILE_ACTION_MODIFIED:
|
||||||
|
case FILE_ACTION_RENAMED_OLD_NAME:
|
||||||
|
case FILE_ACTION_RENAMED_NEW_NAME:
|
||||||
|
FspFsvolDeviceInvalidateVolumeInfo(FsvolDeviceObject);
|
||||||
|
|
||||||
|
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||||
|
ParentNode = FspFsvolDeviceLookupContextByName(FsvolDeviceObject, &Parent);
|
||||||
|
if (0 != ParentNode)
|
||||||
|
FspFileNodeReference(ParentNode);
|
||||||
|
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
|
||||||
|
|
||||||
|
if (0 != ParentNode)
|
||||||
|
{
|
||||||
|
FspFileNodeInvalidateDirInfo(ParentNode);
|
||||||
|
FspFileNodeDereference(ParentNode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != FileNode->MainFileNode)
|
if (0 != FileNode->MainFileNode)
|
||||||
{
|
{
|
||||||
@ -1877,78 +1749,65 @@ VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action
|
|||||||
SetFlag(Filter, FILE_NOTIFY_CHANGE_STREAM_NAME);
|
SetFlag(Filter, FILE_NOTIFY_CHANGE_STREAM_NAME);
|
||||||
if (FlagOn(Filter, FILE_NOTIFY_CHANGE_SIZE))
|
if (FlagOn(Filter, FILE_NOTIFY_CHANGE_SIZE))
|
||||||
SetFlag(Filter, FILE_NOTIFY_CHANGE_STREAM_SIZE);
|
SetFlag(Filter, FILE_NOTIFY_CHANGE_STREAM_SIZE);
|
||||||
if (FlagOn(Filter, FILE_NOTIFY_CHANGE_LAST_WRITE))
|
/* ???: what about FILE_NOTIFY_CHANGE_STREAM_WRITE */
|
||||||
SetFlag(Filter, FILE_NOTIFY_CHANGE_STREAM_WRITE);
|
ClearFlag(Filter, ~(FILE_NOTIFY_CHANGE_STREAM_NAME | FILE_NOTIFY_CHANGE_STREAM_SIZE));
|
||||||
ClearFlag(Filter, ~(FILE_NOTIFY_CHANGE_STREAM_NAME | FILE_NOTIFY_CHANGE_STREAM_SIZE |
|
|
||||||
FILE_NOTIFY_CHANGE_STREAM_WRITE));
|
|
||||||
|
|
||||||
switch (Action)
|
switch (Action)
|
||||||
{
|
{
|
||||||
case FILE_ACTION_ADDED:
|
case FILE_ACTION_ADDED:
|
||||||
Action = FILE_ACTION_ADDED_STREAM;
|
Action = FILE_ACTION_ADDED_STREAM;
|
||||||
|
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
break;
|
break;
|
||||||
case FILE_ACTION_REMOVED:
|
case FILE_ACTION_REMOVED:
|
||||||
Action = FILE_ACTION_REMOVED_STREAM;
|
Action = FILE_ACTION_REMOVED_STREAM;
|
||||||
|
FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
break;
|
break;
|
||||||
case FILE_ACTION_MODIFIED:
|
case FILE_ACTION_MODIFIED:
|
||||||
Action = FILE_ACTION_MODIFIED_STREAM;
|
Action = FILE_ACTION_MODIFIED_STREAM;
|
||||||
|
//FspFileNodeInvalidateStreamInfo(FileNode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Filter)
|
if (0 != Filter)
|
||||||
{
|
|
||||||
FspFileNameSuffix(&FileNode->FileName, &Parent, &Suffix);
|
|
||||||
|
|
||||||
if (InvalidateCaches)
|
|
||||||
{
|
|
||||||
FspFsvolDeviceInvalidateVolumeInfo(FsvolDeviceObject);
|
|
||||||
if (0 == FileNode->MainFileNode)
|
|
||||||
{
|
|
||||||
if (sizeof(WCHAR) == FileNode->FileName.Length && L'\\' == FileNode->FileName.Buffer[0])
|
|
||||||
; /* root does not have a parent */
|
|
||||||
else
|
|
||||||
FspFileNodeInvalidateDirInfoByName(FsvolDeviceObject, &Parent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
FspFileNodeInvalidateStreamInfo(FileNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
FspNotifyReportChange(
|
FspNotifyReportChange(
|
||||||
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList,
|
FsvolDeviceExtension->NotifySync, &FsvolDeviceExtension->NotifyList,
|
||||||
&FileNode->FileName,
|
&FileNode->FileName,
|
||||||
(USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer),
|
(USHORT)((PUINT8)Suffix.Buffer - (PUINT8)FileNode->FileName.Buffer),
|
||||||
0, Filter, Action);
|
0, Filter, Action);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
IoMarkIrpPending(Irp);
|
||||||
|
FspFileNodeSetOwnerF(FileNode, FspIrpFlags(Irp), Irp);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Result = FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode);
|
FsRtlProcessFileLock(&FileNode->FileLock, Irp, FileNode);
|
||||||
}
|
}
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = GetExceptionCode();
|
Irp->IoStatus.Status = GetExceptionCode();
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
Result = FspFileNodeCompleteLockIrp(FileNode, Irp);
|
FspFileNodeCompleteLockIrp(FileNode, Irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp)
|
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FILE_NODE *FileNode = Context;
|
||||||
NTSTATUS Result = Irp->IoStatus.Status;
|
NTSTATUS Result = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
FspFileNodeReleaseOwnerF(FileNode, FspIrpFlags(Irp), Irp);
|
||||||
|
|
||||||
DEBUGLOGIRP(Irp, Result);
|
DEBUGLOGIRP(Irp, Result);
|
||||||
|
|
||||||
FspIopCompleteIrp(Irp, Result);
|
FspIopCompleteIrp(Irp, Result);
|
||||||
@ -2056,9 +1915,7 @@ NTSTATUS FspMainFileOpen(
|
|||||||
PFILE_OBJECT MainFileObject;
|
PFILE_OBJECT MainFileObject;
|
||||||
|
|
||||||
/* assert that the supplied name is actually a main file name */
|
/* assert that the supplied name is actually a main file name */
|
||||||
ASSERT(FspFileNameIsValid(MainFileName,
|
ASSERT(FspFileNameIsValid(MainFileName, 0, 0));
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength,
|
|
||||||
0, 0));
|
|
||||||
|
|
||||||
*PMainFileHandle = 0;
|
*PMainFileHandle = 0;
|
||||||
*PMainFileObject = 0;
|
*PMainFileObject = 0;
|
||||||
@ -2068,11 +1925,11 @@ NTSTATUS FspMainFileOpen(
|
|||||||
case FILE_CREATE:
|
case FILE_CREATE:
|
||||||
case FILE_OPEN_IF:
|
case FILE_OPEN_IF:
|
||||||
case FILE_OVERWRITE_IF:
|
case FILE_OVERWRITE_IF:
|
||||||
case FILE_SUPERSEDE:
|
|
||||||
Disposition = FILE_OPEN_IF;
|
Disposition = FILE_OPEN_IF;
|
||||||
break;
|
break;
|
||||||
case FILE_OPEN:
|
case FILE_OPEN:
|
||||||
case FILE_OVERWRITE:
|
case FILE_OVERWRITE:
|
||||||
|
case FILE_SUPERSEDE:
|
||||||
Disposition = FILE_OPEN;
|
Disposition = FILE_OPEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/fileinfo.c
|
* @file sys/fileinfo.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -134,7 +134,6 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
|
|||||||
|
|
||||||
PFILE_ALL_INFORMATION Info = (PFILE_ALL_INFORMATION)*PBuffer;
|
PFILE_ALL_INFORMATION Info = (PFILE_ALL_INFORMATION)*PBuffer;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
BOOLEAN DeletePending;
|
|
||||||
|
|
||||||
if (0 == FileInfo)
|
if (0 == FileInfo)
|
||||||
{
|
{
|
||||||
@ -145,9 +144,6 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
|
|||||||
return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd);
|
return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeletePending = 0 != FileNode->DeletePending;
|
|
||||||
MemoryBarrier();
|
|
||||||
|
|
||||||
Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime;
|
Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime;
|
||||||
Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime;
|
Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime;
|
||||||
Info->BasicInformation.LastWriteTime.QuadPart = FileInfo->LastWriteTime;
|
Info->BasicInformation.LastWriteTime.QuadPart = FileInfo->LastWriteTime;
|
||||||
@ -158,7 +154,7 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
|
|||||||
Info->StandardInformation.AllocationSize.QuadPart = FileInfo->AllocationSize;
|
Info->StandardInformation.AllocationSize.QuadPart = FileInfo->AllocationSize;
|
||||||
Info->StandardInformation.EndOfFile.QuadPart = FileInfo->FileSize;
|
Info->StandardInformation.EndOfFile.QuadPart = FileInfo->FileSize;
|
||||||
Info->StandardInformation.NumberOfLinks = 1;
|
Info->StandardInformation.NumberOfLinks = 1;
|
||||||
Info->StandardInformation.DeletePending = DeletePending || FileObject->DeletePending;
|
Info->StandardInformation.DeletePending = FileObject->DeletePending;
|
||||||
Info->StandardInformation.Directory = FileNode->IsDirectory;
|
Info->StandardInformation.Directory = FileNode->IsDirectory;
|
||||||
|
|
||||||
Info->InternalInformation.IndexNumber.QuadPart = FileNode->IndexNumber;
|
Info->InternalInformation.IndexNumber.QuadPart = FileNode->IndexNumber;
|
||||||
@ -367,7 +363,6 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
|
|||||||
|
|
||||||
PFILE_STANDARD_INFORMATION Info = (PFILE_STANDARD_INFORMATION)*PBuffer;
|
PFILE_STANDARD_INFORMATION Info = (PFILE_STANDARD_INFORMATION)*PBuffer;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
BOOLEAN DeletePending;
|
|
||||||
|
|
||||||
if (0 == FileInfo)
|
if (0 == FileInfo)
|
||||||
{
|
{
|
||||||
@ -377,13 +372,10 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeletePending = 0 != FileNode->DeletePending;
|
|
||||||
MemoryBarrier();
|
|
||||||
|
|
||||||
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
|
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
|
||||||
Info->EndOfFile.QuadPart = FileInfo->FileSize;
|
Info->EndOfFile.QuadPart = FileInfo->FileSize;
|
||||||
Info->NumberOfLinks = 1;
|
Info->NumberOfLinks = 1;
|
||||||
Info->DeletePending = DeletePending || FileObject->DeletePending;
|
Info->DeletePending = FileObject->DeletePending;
|
||||||
Info->Directory = FileNode->IsDirectory;
|
Info->Directory = FileNode->IsDirectory;
|
||||||
|
|
||||||
*PBuffer = (PVOID)(Info + 1);
|
*PBuffer = (PVOID)(Info + 1);
|
||||||
@ -627,7 +619,7 @@ static NTSTATUS FspFsvolQueryInformation(
|
|||||||
|
|
||||||
/* is this a valid FileObject? */
|
/* is this a valid FileObject? */
|
||||||
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
|
||||||
|
|
||||||
@ -671,7 +663,7 @@ static NTSTATUS FspFsvolQueryInformation(
|
|||||||
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer);
|
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer);
|
||||||
return Result;
|
return Result;
|
||||||
case FileHardLinkInformation:
|
case FileHardLinkInformation:
|
||||||
Result = STATUS_NOT_SUPPORTED; /* no hard link support */
|
Result = STATUS_INVALID_PARAMETER; /* no hard link support */
|
||||||
return Result;
|
return Result;
|
||||||
case FileInternalInformation:
|
case FileInternalInformation:
|
||||||
Result = FspFsvolQueryInternalInformation(FileObject, &Buffer, BufferEnd);
|
Result = FspFsvolQueryInternalInformation(FileObject, &Buffer, BufferEnd);
|
||||||
@ -682,9 +674,6 @@ static NTSTATUS FspFsvolQueryInformation(
|
|||||||
Result = FspFsvolQueryNameInformation(FileObject, &Buffer, BufferEnd);
|
Result = FspFsvolQueryNameInformation(FileObject, &Buffer, BufferEnd);
|
||||||
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer);
|
Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer);
|
||||||
return Result;
|
return Result;
|
||||||
case FileAlternateNameInformation:
|
|
||||||
Result = STATUS_OBJECT_NAME_NOT_FOUND; /* WinFsp does not support short names */
|
|
||||||
return Result;
|
|
||||||
case FileNetworkOpenInformation:
|
case FileNetworkOpenInformation:
|
||||||
Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, 0);
|
Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, 0);
|
||||||
break;
|
break;
|
||||||
@ -904,12 +893,13 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject,
|
|||||||
{
|
{
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
|
||||||
|
FileNode->TruncateOnClose = TRUE;
|
||||||
|
|
||||||
/* mark the file object as modified */
|
/* mark the file object as modified */
|
||||||
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
||||||
|
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -925,15 +915,6 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
|
|||||||
{
|
{
|
||||||
if (sizeof(FILE_BASIC_INFORMATION) > Length)
|
if (sizeof(FILE_BASIC_INFORMATION) > Length)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
PFILE_BASIC_INFORMATION Info = (PFILE_BASIC_INFORMATION)Buffer;
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
UINT32 FileAttributes = Info->FileAttributes;
|
|
||||||
|
|
||||||
/* do not allow the temporary bit on a directory */
|
|
||||||
if (FileNode->IsDirectory &&
|
|
||||||
FlagOn(FileAttributes, FILE_ATTRIBUTE_TEMPORARY))
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
}
|
||||||
else if (0 == Response)
|
else if (0 == Response)
|
||||||
{
|
{
|
||||||
@ -954,53 +935,23 @@ static NTSTATUS FspFsvolSetBasicInformation(PFILE_OBJECT FileObject,
|
|||||||
Request->Req.SetInformation.Info.Basic.CreationTime = Info->CreationTime.QuadPart;
|
Request->Req.SetInformation.Info.Basic.CreationTime = Info->CreationTime.QuadPart;
|
||||||
Request->Req.SetInformation.Info.Basic.LastAccessTime = Info->LastAccessTime.QuadPart;
|
Request->Req.SetInformation.Info.Basic.LastAccessTime = Info->LastAccessTime.QuadPart;
|
||||||
Request->Req.SetInformation.Info.Basic.LastWriteTime = Info->LastWriteTime.QuadPart;
|
Request->Req.SetInformation.Info.Basic.LastWriteTime = Info->LastWriteTime.QuadPart;
|
||||||
Request->Req.SetInformation.Info.Basic.ChangeTime = Info->ChangeTime.QuadPart;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
|
||||||
ULONG NotifyFilter = 0;
|
ULONG NotifyFilter = 0;
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
|
||||||
|
|
||||||
if (!FileNode->IsDirectory)
|
|
||||||
{
|
|
||||||
/* properly set temporary bit for lazy writer */
|
|
||||||
if (FlagOn(Response->Rsp.SetInformation.FileInfo.FileAttributes,
|
|
||||||
FILE_ATTRIBUTE_TEMPORARY))
|
|
||||||
SetFlag(FileObject->Flags, FO_TEMPORARY_FILE);
|
|
||||||
else
|
|
||||||
ClearFlag(FileObject->Flags, FO_TEMPORARY_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo, FALSE);
|
|
||||||
|
|
||||||
if ((UINT32)-1 != Request->Req.SetInformation.Info.Basic.FileAttributes)
|
if ((UINT32)-1 != Request->Req.SetInformation.Info.Basic.FileAttributes)
|
||||||
{
|
|
||||||
FileDesc->DidSetFileAttributes = TRUE;
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
|
NotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
|
||||||
}
|
|
||||||
if (0 != Request->Req.SetInformation.Info.Basic.CreationTime)
|
if (0 != Request->Req.SetInformation.Info.Basic.CreationTime)
|
||||||
{
|
|
||||||
FileDesc->DidSetCreationTime = TRUE;
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
|
NotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
|
||||||
}
|
|
||||||
if (0 != Request->Req.SetInformation.Info.Basic.LastAccessTime)
|
if (0 != Request->Req.SetInformation.Info.Basic.LastAccessTime)
|
||||||
{
|
|
||||||
FileDesc->DidSetLastAccessTime = TRUE;
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
|
||||||
}
|
|
||||||
if (0 != Request->Req.SetInformation.Info.Basic.LastWriteTime)
|
if (0 != Request->Req.SetInformation.Info.Basic.LastWriteTime)
|
||||||
{
|
|
||||||
FileDesc->DidSetLastWriteTime = TRUE;
|
|
||||||
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
NotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||||
}
|
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED);
|
||||||
if (0 != Request->Req.SetInformation.Info.Basic.ChangeTime)
|
|
||||||
FileDesc->DidSetChangeTime = TRUE;
|
|
||||||
|
|
||||||
FileDesc->DidSetMetadata = TRUE;
|
|
||||||
FspFileNodeNotifyChange(FileNode, NotifyFilter, FILE_ACTION_MODIFIED, TRUE/*FALSE*/);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -1045,12 +996,13 @@ static NTSTATUS FspFsvolSetEndOfFileInformation(PFILE_OBJECT FileObject,
|
|||||||
{
|
{
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo);
|
||||||
|
FileNode->TruncateOnClose = TRUE;
|
||||||
|
|
||||||
/* mark the file object as modified -- FastFat does this only for Allocation though! */
|
/* mark the file object as modified -- FastFat does this only for Allocation though! */
|
||||||
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
|
||||||
|
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -1199,7 +1151,6 @@ static NTSTATUS FspFsvolSetRenameInformation(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
PFILE_OBJECT TargetFileObject = IrpSp->Parameters.SetFile.FileObject;
|
PFILE_OBJECT TargetFileObject = IrpSp->Parameters.SetFile.FileObject;
|
||||||
BOOLEAN ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
|
BOOLEAN ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
|
||||||
@ -1225,9 +1176,7 @@ static NTSTATUS FspFsvolSetRenameInformation(
|
|||||||
if (FileNode->IsRootDirectory)
|
if (FileNode->IsRootDirectory)
|
||||||
/* cannot rename root directory */
|
/* cannot rename root directory */
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
if (!FspFileNameIsValid(&FileNode->FileName,
|
if (!FspFileNameIsValid(&FileNode->FileName, 0, 0))
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength,
|
|
||||||
0, 0))
|
|
||||||
/* cannot rename streams (WinFsp limitation) */
|
/* cannot rename streams (WinFsp limitation) */
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
@ -1261,12 +1210,7 @@ retry:
|
|||||||
}
|
}
|
||||||
Suffix.MaximumLength = Suffix.Length;
|
Suffix.MaximumLength = Suffix.Length;
|
||||||
|
|
||||||
if (!FspFileNameIsValid(&Remain,
|
if (!FspFileNameIsValid(&Remain, 0, 0) || !FspFileNameIsValid(&Suffix, 0, 0))
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength,
|
|
||||||
0, 0) ||
|
|
||||||
!FspFileNameIsValid(&Suffix,
|
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength,
|
|
||||||
0, 0))
|
|
||||||
{
|
{
|
||||||
/* cannot rename streams (WinFsp limitation) */
|
/* cannot rename streams (WinFsp limitation) */
|
||||||
Result = STATUS_INVALID_PARAMETER;
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
@ -1397,8 +1341,7 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
|||||||
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_RENAMED_OLD_NAME,
|
FILE_ACTION_RENAMED_OLD_NAME);
|
||||||
TRUE);
|
|
||||||
|
|
||||||
NewFileName.Length = NewFileName.MaximumLength =
|
NewFileName.Length = NewFileName.MaximumLength =
|
||||||
Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR);
|
Request->Req.SetInformation.Info.Rename.NewFileName.Size - sizeof(WCHAR);
|
||||||
@ -1409,8 +1352,7 @@ static NTSTATUS FspFsvolSetRenameInformationSuccess(
|
|||||||
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
/* fastfat has some really arcane rules on rename notifications; simplify! */
|
||||||
FspFileNodeNotifyChange(FileNode,
|
FspFileNodeNotifyChange(FileNode,
|
||||||
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
FileNode->IsDirectory ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
|
||||||
FILE_ACTION_RENAMED_NEW_NAME,
|
FILE_ACTION_RENAMED_NEW_NAME);
|
||||||
TRUE);
|
|
||||||
|
|
||||||
FspIopRequestContext(Request, RequestFileNode) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
FspIopRequestContext(Request, RequestDeviceObject) = 0;
|
||||||
@ -1429,7 +1371,7 @@ static NTSTATUS FspFsvolSetInformation(
|
|||||||
|
|
||||||
/* is this a valid FileObject? */
|
/* is this a valid FileObject? */
|
||||||
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
|
||||||
|
|
||||||
@ -1460,7 +1402,7 @@ static NTSTATUS FspFsvolSetInformation(
|
|||||||
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length, 0, 0);
|
Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length, 0, 0);
|
||||||
break;
|
break;
|
||||||
case FileLinkInformation:
|
case FileLinkInformation:
|
||||||
Result = STATUS_NOT_SUPPORTED; /* no hard link support */
|
Result = STATUS_INVALID_PARAMETER; /* no hard link support */
|
||||||
return Result;
|
return Result;
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
Result = FspFsvolSetPositionInformation(FileObject, Buffer, Length);
|
Result = FspFsvolSetPositionInformation(FileObject, Buffer, Length);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/flush.c
|
* @file sys/flush.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -58,7 +58,7 @@ static NTSTATUS FspFsvolFlushBuffers(
|
|||||||
*/
|
*/
|
||||||
if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory)
|
if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory)
|
||||||
{
|
{
|
||||||
Result = FspFileNodeCopyOpenList(FsvolDeviceObject, &FileNodes, &FileNodeCount);
|
Result = FspFileNodeCopyList(FsvolDeviceObject, &FileNodes, &FileNodeCount);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
@ -149,21 +149,7 @@ NTSTATUS FspFsvolFlushBuffersComplete(
|
|||||||
else if (!NT_SUCCESS(FlushResult))
|
else if (!NT_SUCCESS(FlushResult))
|
||||||
Result = FlushResult;
|
Result = FlushResult;
|
||||||
else
|
else
|
||||||
{
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A flush request on the volume (or the root directory according to FastFat)
|
|
||||||
* is a request to flush the whole volume.
|
|
||||||
*/
|
|
||||||
if (!FspFileNodeIsValid(FileNode) || FileNode->IsRootDirectory)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.FlushBuffers.FileInfo, TRUE);
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
FSP_LEAVE_IOC("FileObject=%p",
|
FSP_LEAVE_IOC("FileObject=%p",
|
||||||
IrpSp->FileObject);
|
IrpSp->FileObject);
|
||||||
|
230
src/sys/fsctl.c
230
src/sys/fsctl.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/fsctl.c
|
* @file sys/fsctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -29,12 +29,6 @@ static NTSTATUS FspFsvolFileSystemControlOplock(
|
|||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
static IO_COMPLETION_ROUTINE FspFsvolFileSystemControlOplockCompletion;
|
static IO_COMPLETION_ROUTINE FspFsvolFileSystemControlOplockCompletion;
|
||||||
static WORKER_THREAD_ROUTINE FspFsvolFileSystemControlOplockCompletionWork;
|
static WORKER_THREAD_ROUTINE FspFsvolFileSystemControlOplockCompletionWork;
|
||||||
static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
static NTSTATUS FspFsvolFileSystemControlGetStatistics(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
static NTSTATUS FspFsvolFileSystemControlGetRetrievalPointers(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
static NTSTATUS FspFsvolFileSystemControl(
|
static NTSTATUS FspFsvolFileSystemControl(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
|
||||||
@ -48,9 +42,6 @@ FSP_DRIVER_DISPATCH FspFileSystemControl;
|
|||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplock)
|
#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplock)
|
||||||
// !#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletion)
|
// !#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletion)
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletionWork)
|
#pragma alloc_text(PAGE, FspFsvolFileSystemControlOplockCompletionWork)
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlQueryPersistentVolumeState)
|
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlGetStatistics)
|
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlGetRetrievalPointers)
|
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControl)
|
#pragma alloc_text(PAGE, FspFsvolFileSystemControl)
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlComplete)
|
#pragma alloc_text(PAGE, FspFsvolFileSystemControlComplete)
|
||||||
#pragma alloc_text(PAGE, FspFsvolFileSystemControlRequestFini)
|
#pragma alloc_text(PAGE, FspFsvolFileSystemControlRequestFini)
|
||||||
@ -114,7 +105,7 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint(
|
|||||||
|
|
||||||
/* is this a valid FileObject? */
|
/* is this a valid FileObject? */
|
||||||
if (!FspFileNodeIsValid(FileObject->FsContext))
|
if (!FspFileNodeIsValid(FileObject->FsContext))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
@ -134,51 +125,17 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint(
|
|||||||
|
|
||||||
if (IsWrite)
|
if (IsWrite)
|
||||||
{
|
{
|
||||||
ASSERT(
|
if (0 == InputBuffer || 0 == InputBufferLength ||
|
||||||
FSCTL_SET_REPARSE_POINT == FsControlCode ||
|
FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMAX - (FileNode->FileName.Length + sizeof(WCHAR)) <
|
||||||
FSCTL_DELETE_REPARSE_POINT == FsControlCode);
|
InputBufferLength)
|
||||||
|
|
||||||
if (0 == InputBuffer || 0 == InputBufferLength)
|
|
||||||
return STATUS_INVALID_BUFFER_SIZE;
|
|
||||||
|
|
||||||
if (0 != OutputBufferLength)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FsRtlValidateReparsePointBuffer(InputBufferLength, InputBuffer);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
ReparseData = (PREPARSE_DATA_BUFFER)InputBuffer;
|
ReparseData = (PREPARSE_DATA_BUFFER)InputBuffer;
|
||||||
|
|
||||||
if (FSCTL_SET_REPARSE_POINT == FsControlCode)
|
|
||||||
{
|
|
||||||
if (FSP_FSCTL_TRANSACT_REQ_BUFFER_SIZEMAX - (FileNode->FileName.Length + sizeof(WCHAR)) <
|
|
||||||
InputBufferLength)
|
|
||||||
return STATUS_IO_REPARSE_DATA_INVALID;
|
|
||||||
|
|
||||||
Result = FsRtlValidateReparsePointBuffer(InputBufferLength, InputBuffer);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((ULONG)FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) != InputBufferLength &&
|
|
||||||
(ULONG)FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer) != InputBufferLength)
|
|
||||||
return STATUS_IO_REPARSE_DATA_INVALID;
|
|
||||||
|
|
||||||
if (0 != ReparseData->ReparseDataLength)
|
|
||||||
return STATUS_IO_REPARSE_DATA_INVALID;
|
|
||||||
|
|
||||||
if (IO_REPARSE_TAG_RESERVED_ZERO == ReparseData->ReparseTag ||
|
|
||||||
IO_REPARSE_TAG_RESERVED_ONE == ReparseData->ReparseTag)
|
|
||||||
return STATUS_IO_REPARSE_TAG_INVALID;
|
|
||||||
|
|
||||||
if (!IsReparseTagMicrosoft(ReparseData->ReparseTag) &&
|
|
||||||
(ULONG)FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer) != InputBufferLength)
|
|
||||||
return STATUS_IO_REPARSE_DATA_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NTFS seems to require one of these rights to allow FSCTL_{SET,DELETE}_REPARSE_POINT */
|
|
||||||
if (!FlagOn(FileDesc->GrantedAccess,
|
|
||||||
FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES))
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
|
|
||||||
if (IO_REPARSE_TAG_SYMLINK == ReparseData->ReparseTag)
|
if (IO_REPARSE_TAG_SYMLINK == ReparseData->ReparseTag)
|
||||||
{
|
{
|
||||||
/* NTFS severely limits symbolic links; we will not do that unless our file system asks */
|
/* NTFS severely limits symbolic links; we will not do that unless our file system asks */
|
||||||
@ -272,13 +229,8 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(FSCTL_GET_REPARSE_POINT == FsControlCode);
|
|
||||||
|
|
||||||
if (0 != InputBufferLength)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (0 == OutputBuffer || 0 == OutputBufferLength)
|
if (0 == OutputBuffer || 0 == OutputBufferLength)
|
||||||
return STATUS_INVALID_USER_BUFFER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtFsControlFile (IopXxxControlFile) will setup Irp->AssociatedIrp.SystemBuffer
|
* NtFsControlFile (IopXxxControlFile) will setup Irp->AssociatedIrp.SystemBuffer
|
||||||
@ -324,21 +276,7 @@ static NTSTATUS FspFsvolFileSystemControlReparsePointComplete(
|
|||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (IsWrite)
|
if (IsWrite)
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
FSP_FILE_DESC *FileDesc = IrpSp->FileObject->FsContext2;
|
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
|
||||||
|
|
||||||
FspFileNodeInvalidateFileInfo(FileNode);
|
|
||||||
|
|
||||||
FileDesc->DidSetReparsePoint = TRUE;
|
|
||||||
FileDesc->DidSetMetadata = TRUE;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
@ -495,15 +433,18 @@ static NTSTATUS FspFsvolFileSystemControlOplock(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* FspOplockFsctrl takes ownership of the IRP under all circumstances.
|
* FspOplockFsctrl takes ownership of the IRP under all circumstances.
|
||||||
|
*
|
||||||
|
* We mark the IRP pending so that we can safely return STATUS_PENDING.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IoSetTopLevelIrp(0);
|
IoSetTopLevelIrp(0);
|
||||||
|
|
||||||
|
IoMarkIrpPending(Irp);
|
||||||
Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount);
|
Result = FspFileNodeOplockFsctl(FileNode, Irp, OplockCount);
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(FileNode, Main);
|
||||||
|
|
||||||
return Result | FSP_STATUS_IGNORE_BIT;
|
return STATUS_PENDING;
|
||||||
|
|
||||||
unlock_exit:
|
unlock_exit:
|
||||||
FspFileNodeRelease(FileNode, Main);
|
FspFileNodeRelease(FileNode, Main);
|
||||||
@ -532,140 +473,6 @@ static VOID FspFsvolFileSystemControlOplockCompletionWork(PVOID Context)
|
|||||||
FspFree(CompletionContext);
|
FspFree(CompletionContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFileSystemControlQueryPersistentVolumeState(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
|
||||||
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
|
||||||
PFILE_FS_PERSISTENT_VOLUME_INFORMATION Info;
|
|
||||||
|
|
||||||
if (0 == Buffer)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION) > InputBufferLength ||
|
|
||||||
sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION) > OutputBufferLength)
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
|
|
||||||
Info = Buffer;
|
|
||||||
if (1 != Info->Version ||
|
|
||||||
!FlagOn(Info->FlagMask, PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED))
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
RtlZeroMemory(Info, sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION));
|
|
||||||
Info->VolumeFlags = PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = sizeof(FILE_FS_PERSISTENT_VOLUME_INFORMATION);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFileSystemControlGetStatistics(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
|
||||||
ULONG Length = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
|
||||||
|
|
||||||
Result = FspStatisticsCopy(FsvolDeviceExtension->Statistics, Buffer, &Length);
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = Length;
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFileSystemControlGetRetrievalPointers(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* FSCTL_GET_RETRIEVAL_POINTERS is normally used for defragmentation support,
|
|
||||||
* which WinFsp does NOT support. However some tools (notably IFSTEST) use it
|
|
||||||
* to determine whether files are "resident" or "non-resident" which is an NTFS
|
|
||||||
* concept. To support such tools we respond in a manner that indicates that
|
|
||||||
* WinFsp files are always non-resident.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
|
||||||
|
|
||||||
/* is this a valid FileObject? */
|
|
||||||
if (!FspFileNodeIsValid(FileObject->FsContext))
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
PSTARTING_VCN_INPUT_BUFFER InputBuffer = IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
|
|
||||||
PRETRIEVAL_POINTERS_BUFFER OutputBuffer = Irp->UserBuffer;
|
|
||||||
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
|
||||||
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
|
|
||||||
STARTING_VCN_INPUT_BUFFER StartingVcn;
|
|
||||||
RETRIEVAL_POINTERS_BUFFER RetrievalPointers;
|
|
||||||
UINT64 AllocationUnit;
|
|
||||||
|
|
||||||
if (0 == InputBuffer || 0 == OutputBuffer)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
if (sizeof(STARTING_VCN_INPUT_BUFFER) > InputBufferLength ||
|
|
||||||
sizeof(RETRIEVAL_POINTERS_BUFFER) > OutputBufferLength)
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
|
|
||||||
if (UserMode == Irp->RequestorMode)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProbeForRead(InputBuffer, InputBufferLength, sizeof(UCHAR)/*FastFat*/);
|
|
||||||
StartingVcn = *InputBuffer;
|
|
||||||
}
|
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
return GetExceptionCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
StartingVcn = *InputBuffer;
|
|
||||||
|
|
||||||
RetrievalPointers.ExtentCount = 1;
|
|
||||||
RetrievalPointers.StartingVcn.QuadPart = 0;
|
|
||||||
RetrievalPointers.Extents[0].NextVcn.QuadPart = 0;
|
|
||||||
RetrievalPointers.Extents[0].Lcn.QuadPart = -1LL;
|
|
||||||
|
|
||||||
AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize *
|
|
||||||
FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit;
|
|
||||||
|
|
||||||
FspFileNodeAcquireShared(FileNode, Main);
|
|
||||||
RetrievalPointers.Extents[0].NextVcn.QuadPart =
|
|
||||||
FileNode->Header.AllocationSize.QuadPart / AllocationUnit;
|
|
||||||
FspFileNodeRelease(FileNode, Main);
|
|
||||||
|
|
||||||
if (StartingVcn.StartingVcn.QuadPart > RetrievalPointers.Extents[0].NextVcn.QuadPart)
|
|
||||||
return STATUS_END_OF_FILE;
|
|
||||||
|
|
||||||
if (UserMode == Irp->RequestorMode)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(UCHAR)/*FastFat*/);
|
|
||||||
*OutputBuffer = RetrievalPointers;
|
|
||||||
}
|
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
return GetExceptionCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*OutputBuffer = RetrievalPointers;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = sizeof RetrievalPointers;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolFileSystemControl(
|
static NTSTATUS FspFsvolFileSystemControl(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
@ -699,15 +506,6 @@ static NTSTATUS FspFsvolFileSystemControl(
|
|||||||
case FSCTL_REQUEST_OPLOCK:
|
case FSCTL_REQUEST_OPLOCK:
|
||||||
Result = FspFsvolFileSystemControlOplock(FsvolDeviceObject, Irp, IrpSp);
|
Result = FspFsvolFileSystemControlOplock(FsvolDeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
case FSCTL_QUERY_PERSISTENT_VOLUME_STATE:
|
|
||||||
Result = FspFsvolFileSystemControlQueryPersistentVolumeState(FsvolDeviceObject, Irp, IrpSp);
|
|
||||||
break;
|
|
||||||
case FSCTL_FILESYSTEM_GET_STATISTICS:
|
|
||||||
Result = FspFsvolFileSystemControlGetStatistics(FsvolDeviceObject, Irp, IrpSp);
|
|
||||||
break;
|
|
||||||
case FSCTL_GET_RETRIEVAL_POINTERS:
|
|
||||||
Result = FspFsvolFileSystemControlGetRetrievalPointers(FsvolDeviceObject, Irp, IrpSp);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/iop.c
|
* @file sys/iop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -33,7 +33,7 @@ BOOLEAN FspIopRetryCompleteIrp(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
|
|||||||
VOID FspIopSetIrpResponse(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
VOID FspIopSetIrpResponse(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp);
|
FSP_FSCTL_TRANSACT_RSP *FspIopIrpResponse(PIRP Irp);
|
||||||
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
NTSTATUS FspIopDispatchComplete(PIRP Irp, FSP_FSCTL_TRANSACT_RSP *Response);
|
NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspIopCreateRequestFunnel)
|
#pragma alloc_text(PAGE, FspIopCreateRequestFunnel)
|
||||||
@ -281,32 +281,6 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference)
|
|||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
PDEVICE_OBJECT DeviceObject = IrpSp->DeviceObject;
|
||||||
|
|
||||||
/*
|
|
||||||
* HACK:
|
|
||||||
*
|
|
||||||
* We update the Create statistics here to avoid doing it in multiple places.
|
|
||||||
*/
|
|
||||||
if (IRP_MJ_CREATE == IrpSp->MajorFunction)
|
|
||||||
{
|
|
||||||
/* only update statistics if we actually have a reference to the DeviceObject */
|
|
||||||
if (DeviceDereference)
|
|
||||||
{
|
|
||||||
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject);
|
|
||||||
|
|
||||||
if (FspFsvolDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind)
|
|
||||||
{
|
|
||||||
FSP_STATISTICS *Statistics = FspStatistics(
|
|
||||||
((FSP_FSVOL_DEVICE_EXTENSION *)DeviceExtension)->Statistics);
|
|
||||||
|
|
||||||
FspStatisticsInc(Statistics, Specific.CreateHits);
|
|
||||||
if (STATUS_SUCCESS == Result)
|
|
||||||
FspStatisticsInc(Statistics, Specific.SuccessfulCreates);
|
|
||||||
else
|
|
||||||
FspStatisticsInc(Statistics, Specific.FailedCreates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/*
|
/*
|
||||||
* HACK:
|
* HACK:
|
||||||
*
|
*
|
||||||
@ -448,7 +422,7 @@ NTSTATUS FspIopDispatchPrepare(PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspIopDispatchComplete(PIRP Irp, FSP_FSCTL_TRANSACT_RSP *Response)
|
NTSTATUS FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
@ -457,9 +431,6 @@ NTSTATUS FspIopDispatchComplete(PIRP Irp, FSP_FSCTL_TRANSACT_RSP *Response)
|
|||||||
ASSERT(IRP_MJ_MAXIMUM_FUNCTION >= IrpSp->MajorFunction);
|
ASSERT(IRP_MJ_MAXIMUM_FUNCTION >= IrpSp->MajorFunction);
|
||||||
ASSERT(0 != FspIopCompleteFunction[IrpSp->MajorFunction]);
|
ASSERT(0 != FspIopCompleteFunction[IrpSp->MajorFunction]);
|
||||||
|
|
||||||
if (STATUS_PENDING == Response->IoStatus.Status ||
|
|
||||||
FlagOn(Response->IoStatus.Status, FSP_STATUS_PRIVATE_BIT | FSP_STATUS_IGNORE_BIT))
|
|
||||||
Response->IoStatus.Status = (UINT32)STATUS_INTERNAL_ERROR;
|
|
||||||
return FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response);
|
return FspIopCompleteFunction[IrpSp->MajorFunction](Irp, Response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/ioq.c
|
* @file sys/ioq.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/lockctl.c
|
* @file sys/lockctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -61,15 +61,10 @@ static NTSTATUS FspFsvolLockControlRetry(
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG IrpFlags = FspIrpFlags(Irp);
|
|
||||||
IoSetTopLevelIrp(0);
|
|
||||||
|
|
||||||
/* let the FSRTL package handle this one! */
|
/* let the FSRTL package handle this one! */
|
||||||
Result = FspFileNodeProcessLockIrp(FileNode, Irp);
|
Result = FspFileNodeProcessLockIrp(FileNode, Irp);
|
||||||
|
|
||||||
FspFileNodeReleaseF(FileNode, IrpFlags);
|
return Result;
|
||||||
|
|
||||||
return Result | FSP_STATUS_IGNORE_BIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvolLockControl(
|
static NTSTATUS FspFsvolLockControl(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/meta.c
|
* @file sys/meta.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/name.c
|
* @file sys/name.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -17,9 +17,8 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType);
|
||||||
PUNICODE_STRING StreamPart, PULONG StreamType);
|
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern);
|
||||||
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Pattern, ULONG MaxComponentLength);
|
|
||||||
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
VOID FspFileNameSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix);
|
||||||
NTSTATUS FspFileNameInExpression(
|
NTSTATUS FspFileNameInExpression(
|
||||||
PUNICODE_STRING Expression,
|
PUNICODE_STRING Expression,
|
||||||
@ -35,8 +34,7 @@ NTSTATUS FspFileNameInExpression(
|
|||||||
#pragma alloc_text(PAGE, FspFileNameInExpression)
|
#pragma alloc_text(PAGE, FspFileNameInExpression)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, PUNICODE_STRING StreamPart, PULONG StreamType)
|
||||||
PUNICODE_STRING StreamPart, PULONG StreamType)
|
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
@ -46,7 +44,7 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
|||||||
if (0 == Path->Length || 0 != Path->Length % sizeof(WCHAR))
|
if (0 == Path->Length || 0 != Path->Length % sizeof(WCHAR))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
PWSTR PathBgn, PathEnd, PathPtr, ComponentPtr, StreamTypeStr = 0;
|
PWSTR PathBgn, PathEnd, PathPtr, StreamTypeStr = 0;
|
||||||
UCHAR Flags = FSRTL_NTFS_LEGAL;
|
UCHAR Flags = FSRTL_NTFS_LEGAL;
|
||||||
ULONG Colons = 0;
|
ULONG Colons = 0;
|
||||||
WCHAR Char;
|
WCHAR Char;
|
||||||
@ -54,7 +52,6 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
|||||||
PathBgn = Path->Buffer;
|
PathBgn = Path->Buffer;
|
||||||
PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length);
|
PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length);
|
||||||
PathPtr = PathBgn;
|
PathPtr = PathBgn;
|
||||||
ComponentPtr = PathPtr;
|
|
||||||
|
|
||||||
while (PathEnd > PathPtr)
|
while (PathEnd > PathPtr)
|
||||||
{
|
{
|
||||||
@ -66,12 +63,7 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
|||||||
if (0 < Colons)
|
if (0 < Colons)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* path component cannot be longer than MaxComponentLength */
|
|
||||||
if ((ULONG)(PathPtr - ComponentPtr) > MaxComponentLength)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
PathPtr++;
|
PathPtr++;
|
||||||
ComponentPtr = PathPtr;
|
|
||||||
|
|
||||||
/* don't like multiple backslashes */
|
/* don't like multiple backslashes */
|
||||||
if (PathEnd > PathPtr && L'\\' == *PathPtr)
|
if (PathEnd > PathPtr && L'\\' == *PathPtr)
|
||||||
@ -114,10 +106,6 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
|||||||
PathPtr++;
|
PathPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* path component cannot be longer than MaxComponentLength */
|
|
||||||
if ((ULONG)(PathPtr - ComponentPtr) > MaxComponentLength)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* if we had no colons the path is valid */
|
/* if we had no colons the path is valid */
|
||||||
if (0 == Colons)
|
if (0 == Colons)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -145,20 +133,19 @@ BOOLEAN FspFileNameIsValid(PUNICODE_STRING Path, ULONG MaxComponentLength,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Path, ULONG MaxComponentLength)
|
BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Path)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (0 != Path->Length % sizeof(WCHAR))
|
if (0 != Path->Length % sizeof(WCHAR))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
PWSTR PathBgn, PathEnd, PathPtr, ComponentPtr;
|
PWSTR PathBgn, PathEnd, PathPtr;
|
||||||
WCHAR Char;
|
WCHAR Char;
|
||||||
|
|
||||||
PathBgn = Path->Buffer;
|
PathBgn = Path->Buffer;
|
||||||
PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length);
|
PathEnd = (PWSTR)((PUINT8)PathBgn + Path->Length);
|
||||||
PathPtr = PathBgn;
|
PathPtr = PathBgn;
|
||||||
ComponentPtr = PathPtr;
|
|
||||||
|
|
||||||
while (PathEnd > PathPtr)
|
while (PathEnd > PathPtr)
|
||||||
{
|
{
|
||||||
@ -180,10 +167,6 @@ BOOLEAN FspFileNameIsValidPattern(PUNICODE_STRING Path, ULONG MaxComponentLength
|
|||||||
PathPtr++;
|
PathPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* path component cannot be longer than MaxComponentLength */
|
|
||||||
if ((ULONG)(PathPtr - ComponentPtr) > MaxComponentLength)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/read.c
|
* @file sys/read.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -324,20 +324,6 @@ static NTSTATUS FspFsvolReadNonCached(
|
|||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
|
||||||
FSP_STATISTICS *Statistics = FspFsvolDeviceStatistics(FsvolDeviceObject);
|
|
||||||
if (PagingIo)
|
|
||||||
{
|
|
||||||
FspStatisticsInc(Statistics, Base.UserFileReads);
|
|
||||||
FspStatisticsAdd(Statistics, Base.UserFileReadBytes, ReadLength);
|
|
||||||
FspStatisticsInc(Statistics, Base.UserDiskReads);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FspStatisticsInc(Statistics, Specific.NonCachedReads);
|
|
||||||
FspStatisticsAdd(Statistics, Specific.NonCachedReadBytes, ReadLength);
|
|
||||||
FspStatisticsInc(Statistics, Specific.NonCachedDiskReads);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FSP_STATUS_IOQ_POST;
|
return FSP_STATUS_IOQ_POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/security.c
|
* @file sys/security.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -254,11 +254,8 @@ NTSTATUS FspFsvolSetSecurityComplete(
|
|||||||
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
|
||||||
|
|
||||||
/* if the security descriptor that we got back is valid */
|
/* if the security descriptor that we got back is valid */
|
||||||
if (0 < Response->Rsp.SetSecurity.SecurityDescriptor.Size &&
|
if (0 < Response->Rsp.SetSecurity.SecurityDescriptor.Size &&
|
||||||
Response->Buffer + Response->Rsp.SetSecurity.SecurityDescriptor.Size <=
|
Response->Buffer + Response->Rsp.SetSecurity.SecurityDescriptor.Size <=
|
||||||
@ -276,11 +273,6 @@ NTSTATUS FspFsvolSetSecurityComplete(
|
|||||||
FspFileNodeSetSecurity(FileNode, 0, 0);
|
FspFileNodeSetSecurity(FileNode, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDesc->DidSetSecurity = TRUE;
|
|
||||||
FileDesc->DidSetMetadata = TRUE;
|
|
||||||
|
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SECURITY, FILE_ACTION_MODIFIED, FALSE);
|
|
||||||
|
|
||||||
FspIopRequestContext(Request, RequestFileNode) = 0;
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/shutdown.c
|
* @file sys/shutdown.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sys/statistics.c
|
|
||||||
*
|
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of WinFsp.
|
|
||||||
*
|
|
||||||
* You can redistribute it and/or modify it under the terms of the GNU
|
|
||||||
* General Public License version 3 as published by the Free Software
|
|
||||||
* Foundation.
|
|
||||||
*
|
|
||||||
* Licensees holding a valid commercial license may use this file in
|
|
||||||
* accordance with the commercial license agreement provided with the
|
|
||||||
* software.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/driver.h>
|
|
||||||
|
|
||||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics);
|
|
||||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics);
|
|
||||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength);
|
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
|
||||||
#pragma alloc_text(PAGE, FspStatisticsCreate)
|
|
||||||
#pragma alloc_text(PAGE, FspStatisticsDelete)
|
|
||||||
#pragma alloc_text(PAGE, FspStatisticsCopy)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NTSTATUS FspStatisticsCreate(FSP_STATISTICS **PStatistics)
|
|
||||||
{
|
|
||||||
*PStatistics = FspAllocNonPaged(sizeof(FSP_STATISTICS) * FspProcessorCount);
|
|
||||||
if (0 == *PStatistics)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
RtlZeroMemory(*PStatistics, sizeof(FSP_STATISTICS) * FspProcessorCount);
|
|
||||||
for (ULONG Index = 0; FspProcessorCount > Index; Index++)
|
|
||||||
{
|
|
||||||
FSP_STATISTICS *Statistics = *PStatistics + Index;
|
|
||||||
|
|
||||||
/* pretend that we are FAT when it comes to stats */
|
|
||||||
Statistics->Base.FileSystemType = FILESYSTEM_STATISTICS_TYPE_FAT;
|
|
||||||
Statistics->Base.Version = 1;
|
|
||||||
Statistics->Base.SizeOfCompleteStructure = sizeof(FSP_STATISTICS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspStatisticsDelete(FSP_STATISTICS *Statistics)
|
|
||||||
{
|
|
||||||
FspFree(Statistics);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspStatisticsCopy(FSP_STATISTICS *Statistics, PVOID Buffer, PULONG PLength)
|
|
||||||
{
|
|
||||||
NTSTATUS Result;
|
|
||||||
ULONG StatLength;
|
|
||||||
|
|
||||||
if (0 == Buffer)
|
|
||||||
{
|
|
||||||
*PLength = 0;
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sizeof(FILESYSTEM_STATISTICS) > *PLength)
|
|
||||||
{
|
|
||||||
*PLength = 0;
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
StatLength = sizeof(FSP_STATISTICS) * FspProcessorCount;
|
|
||||||
if (*PLength >= StatLength)
|
|
||||||
{
|
|
||||||
*PLength = StatLength;
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Result = STATUS_BUFFER_OVERFLOW;
|
|
||||||
|
|
||||||
RtlCopyMemory(Buffer, Statistics, *PLength);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/util.c
|
* @file sys/util.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -22,7 +22,7 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", STR(MyCompanyName)
|
VALUE "CompanyName", STR(MyCompanyName)
|
||||||
VALUE "FileDescription", STR(MyDescription)
|
VALUE "FileDescription", STR(MyDescription)
|
||||||
VALUE "FileVersion", STR(MyFullVersion)
|
VALUE "FileVersion", STR(MyVersion)
|
||||||
VALUE "InternalName", "winfsp.sys"
|
VALUE "InternalName", "winfsp.sys"
|
||||||
VALUE "LegalCopyright", STR(MyCopyright)
|
VALUE "LegalCopyright", STR(MyCopyright)
|
||||||
VALUE "OriginalFilename", "winfsp.sys"
|
VALUE "OriginalFilename", "winfsp.sys"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/volinfo.c
|
* @file sys/volinfo.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -98,22 +98,16 @@ static NTSTATUS FspFsvolQueryFsAttributeInformation(
|
|||||||
|
|
||||||
RtlInitUnicodeString(&FileSystemName, FsvolDeviceExtension->VolumeParams.FileSystemName);
|
RtlInitUnicodeString(&FileSystemName, FsvolDeviceExtension->VolumeParams.FileSystemName);
|
||||||
|
|
||||||
if (0 == FileSystemName.Length ||
|
CopyLength = sizeof L"" DRIVER_NAME - sizeof(WCHAR);
|
||||||
(L'-' == FileSystemName.Buffer[0] ||
|
RtlCopyMemory(FileSystemNameBuf, L"" DRIVER_NAME, CopyLength);
|
||||||
L'/' == FileSystemName.Buffer[0] ||
|
if (0 != FileSystemName.Length)
|
||||||
L'\\' == FileSystemName.Buffer[0]))
|
|
||||||
{
|
{
|
||||||
CopyLength = sizeof L"" DRIVER_NAME - sizeof(WCHAR);
|
FileSystemNameBuf[CopyLength / sizeof(WCHAR)] = L'-';
|
||||||
RtlCopyMemory(FileSystemNameBuf, L"" DRIVER_NAME, CopyLength);
|
CopyLength += sizeof(WCHAR);
|
||||||
RtlCopyMemory(FileSystemNameBuf + CopyLength / sizeof(WCHAR), FileSystemName.Buffer,
|
RtlCopyMemory(FileSystemNameBuf + CopyLength / sizeof(WCHAR), FileSystemName.Buffer,
|
||||||
FileSystemName.Length);
|
FileSystemName.Length);
|
||||||
CopyLength += FileSystemName.Length;
|
CopyLength += FileSystemName.Length;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
CopyLength = FileSystemName.Length;
|
|
||||||
RtlCopyMemory(FileSystemNameBuf, FileSystemName.Buffer, CopyLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
Info->FileSystemNameLength = CopyLength;
|
Info->FileSystemNameLength = CopyLength;
|
||||||
if (Buffer + CopyLength > BufferEnd)
|
if (Buffer + CopyLength > BufferEnd)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/volume.c
|
* @file sys/volume.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -294,9 +294,9 @@ VOID FspVolumeDelete(
|
|||||||
FspDeviceGlobalUnlock();
|
FspDeviceGlobalUnlock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call MmForceSectionClosed on active files to ensure that Mm removes them from Standby List.
|
* Call MmForceSectionClosed on open files to ensure that Mm removes them from Standby List.
|
||||||
*/
|
*/
|
||||||
Result = FspFileNodeCopyActiveList(FsvolDeviceObject, &FileNodes, &FileNodeCount);
|
Result = FspFileNodeCopyList(FsvolDeviceObject, &FileNodes, &FileNodeCount);
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
for (Index = FileNodeCount - 1; FileNodeCount > Index; Index--)
|
for (Index = FileNodeCount - 1; FileNodeCount > Index; Index--)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/wq.c
|
* @file sys/wq.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -145,7 +145,7 @@ static VOID FspWqWorkRoutine(PVOID Context)
|
|||||||
IoSetTopLevelIrp(Irp);
|
IoSetTopLevelIrp(Irp);
|
||||||
|
|
||||||
Result = WorkRoutine(DeviceObject, Irp, IrpSp, TRUE);
|
Result = WorkRoutine(DeviceObject, Irp, IrpSp, TRUE);
|
||||||
if (STATUS_PENDING != Result && !(FSP_STATUS_IGNORE_BIT & Result))
|
if (STATUS_PENDING != Result)
|
||||||
{
|
{
|
||||||
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||
|
ASSERT(0 == (FSP_STATUS_PRIVATE_BIT & Result) ||
|
||||||
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);
|
FSP_STATUS_IOQ_POST == Result || FSP_STATUS_IOQ_POST_BEST_EFFORT == Result);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/write.c
|
* @file sys/write.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -195,7 +195,6 @@ static NTSTATUS FspFsvolWriteCached(
|
|||||||
{
|
{
|
||||||
ASSERT(CanWait);
|
ASSERT(CanWait);
|
||||||
|
|
||||||
/* send EndOfFileInformation IRP; this will also set TruncateOnClose, etc. */
|
|
||||||
EndOfFileInformation.EndOfFile.QuadPart = WriteEndOffset;
|
EndOfFileInformation.EndOfFile.QuadPart = WriteEndOffset;
|
||||||
Result = FspSendSetInformationIrp(FsvolDeviceObject/* bypass filters */, FileObject,
|
Result = FspSendSetInformationIrp(FsvolDeviceObject/* bypass filters */, FileObject,
|
||||||
FileEndOfFileInformation, &EndOfFileInformation, sizeof EndOfFileInformation);
|
FileEndOfFileInformation, &EndOfFileInformation, sizeof EndOfFileInformation);
|
||||||
@ -394,20 +393,6 @@ static NTSTATUS FspFsvolWriteNonCached(
|
|||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
|
||||||
FSP_STATISTICS *Statistics = FspFsvolDeviceStatistics(FsvolDeviceObject);
|
|
||||||
if (PagingIo)
|
|
||||||
{
|
|
||||||
FspStatisticsInc(Statistics, Base.UserFileWrites);
|
|
||||||
FspStatisticsAdd(Statistics, Base.UserFileWriteBytes, WriteLength);
|
|
||||||
FspStatisticsInc(Statistics, Base.UserDiskWrites);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FspStatisticsInc(Statistics, Specific.NonCachedWrites);
|
|
||||||
FspStatisticsAdd(Statistics, Specific.NonCachedWriteBytes, WriteLength);
|
|
||||||
FspStatisticsInc(Statistics, Specific.NonCachedDiskWrites);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FSP_STATUS_IOQ_POST;
|
return FSP_STATUS_IOQ_POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,10 +469,10 @@ NTSTATUS FspFsvolWriteComplete(
|
|||||||
UINT64 OriginalFileSize = FileNode->Header.FileSize.QuadPart;
|
UINT64 OriginalFileSize = FileNode->Header.FileSize.QuadPart;
|
||||||
|
|
||||||
/* update file info */
|
/* update file info */
|
||||||
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo, TRUE);
|
FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Write.FileInfo);
|
||||||
|
|
||||||
if (OriginalFileSize != Response->Rsp.Write.FileInfo.FileSize)
|
if (OriginalFileSize != Response->Rsp.Write.FileInfo.FileSize)
|
||||||
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED, FALSE);
|
FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_SIZE, FILE_ACTION_MODIFIED);
|
||||||
|
|
||||||
/* update the current file offset if synchronous I/O (and not paging I/O) */
|
/* update the current file offset if synchronous I/O (and not paging I/O) */
|
||||||
if (SynchronousIo && !PagingIo)
|
if (SynchronousIo && !PagingIo)
|
||||||
|
@ -2,81 +2,40 @@
|
|||||||
|
|
||||||
setlocal
|
setlocal
|
||||||
|
|
||||||
|
set Configuration=Release
|
||||||
set MsiName="WinFsp - Windows File System Proxy"
|
set MsiName="WinFsp - Windows File System Proxy"
|
||||||
set CrossCert="%~dp0DigiCert High Assurance EV Root CA.crt"
|
set CrossCert="%~dp0DigiCert High Assurance EV Root CA.crt"
|
||||||
set Issuer="DigiCert"
|
set Issuer="DigiCert"
|
||||||
set Subject="Navimatics Corporation"
|
set Subject="Navimatics Corporation"
|
||||||
|
|
||||||
set Configuration=Release
|
|
||||||
set SignedPackage=
|
|
||||||
|
|
||||||
if not X%1==X set Configuration=%1
|
if not X%1==X set Configuration=%1
|
||||||
if not X%2==X set SignedPackage=%2
|
|
||||||
|
|
||||||
call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
|
call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
|
||||||
|
|
||||||
if not X%SignedPackage%==X (
|
|
||||||
if not exist "%~dp0..\build\VStudio\build\%Configuration%\winfsp-*.msi" (echo previous build not found >&2 & exit /b 1)
|
|
||||||
if not exist "%SignedPackage%" (echo signed package not found >&2 & exit /b 1)
|
|
||||||
del "%~dp0..\build\VStudio\build\%Configuration%\winfsp-*.msi"
|
|
||||||
for /R "%SignedPackage%" %%f in (*.sys) do (
|
|
||||||
copy "%%f" "%~dp0..\build\VStudio\build\%Configuration%" >nul
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
cd %~dp0..\build\VStudio
|
cd %~dp0..\build\VStudio
|
||||||
|
if exist build\ del /s/q build >nul
|
||||||
|
|
||||||
|
devenv winfsp.sln /build "%Configuration%|x64"
|
||||||
|
if errorlevel 1 goto fail
|
||||||
|
devenv winfsp.sln /build "%Configuration%|x86"
|
||||||
|
if errorlevel 1 goto fail
|
||||||
|
|
||||||
set signfail=0
|
set signfail=0
|
||||||
|
for %%f in (build\%Configuration%\winfsp-x64.sys build\%Configuration%\winfsp-x86.sys) do (
|
||||||
if X%SignedPackage%==X (
|
signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha1 /t http://timestamp.digicert.com %%f
|
||||||
if exist build\ for /R build\ %%d in (%Configuration%) do (
|
if errorlevel 1 set /a signfail=signfail+1
|
||||||
if exist "%%d" rmdir /s/q "%%d"
|
signtool sign /as /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha256 /tr http://timestamp.digicert.com /td sha256 %%f
|
||||||
)
|
if errorlevel 1 set /a signfail=signfail+1
|
||||||
|
|
||||||
devenv winfsp.sln /build "%Configuration%|x64"
|
|
||||||
if errorlevel 1 goto fail
|
|
||||||
devenv winfsp.sln /build "%Configuration%|x86"
|
|
||||||
if errorlevel 1 goto fail
|
|
||||||
|
|
||||||
for %%f in (build\%Configuration%\winfsp-x64.sys build\%Configuration%\winfsp-x86.sys) do (
|
|
||||||
signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha1 /t http://timestamp.digicert.com %%f
|
|
||||||
if errorlevel 1 set /a signfail=signfail+1
|
|
||||||
signtool sign /as /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha256 /tr http://timestamp.digicert.com /td sha256 %%f
|
|
||||||
if errorlevel 1 set /a signfail=signfail+1
|
|
||||||
)
|
|
||||||
|
|
||||||
pushd build\%Configuration%
|
|
||||||
echo .OPTION EXPLICIT >driver.ddf
|
|
||||||
echo .Set CabinetFileCountThreshold=0 >>driver.ddf
|
|
||||||
echo .Set FolderFileCountThreshold=0 >>driver.ddf
|
|
||||||
echo .Set FolderSizeThreshold=0 >>driver.ddf
|
|
||||||
echo .Set MaxCabinetSize=0 >>driver.ddf
|
|
||||||
echo .Set MaxDiskFileCount=0 >>driver.ddf
|
|
||||||
echo .Set MaxDiskSize=0 >>driver.ddf
|
|
||||||
echo .Set CompressionType=MSZIP >>driver.ddf
|
|
||||||
echo .Set Cabinet=on >>driver.ddf
|
|
||||||
echo .Set Compress=on >>driver.ddf
|
|
||||||
echo .Set CabinetNameTemplate=driver.cab >>driver.ddf
|
|
||||||
echo .Set DiskDirectory1=. >>driver.ddf
|
|
||||||
echo .Set DestinationDir=x64 >>driver.ddf
|
|
||||||
echo driver-x64.inf >>driver.ddf
|
|
||||||
echo winfsp-x64.sys >>driver.ddf
|
|
||||||
echo .Set DestinationDir=x86 >>driver.ddf
|
|
||||||
echo driver-x86.inf >>driver.ddf
|
|
||||||
echo winfsp-x86.sys >>driver.ddf
|
|
||||||
makecab /F driver.ddf
|
|
||||||
signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /t http://timestamp.digicert.com driver.cab
|
|
||||||
if errorlevel 1 set /a signfail=signfail+1
|
|
||||||
popd
|
|
||||||
)
|
)
|
||||||
|
|
||||||
devenv winfsp.sln /build "Installer.%Configuration%|x86"
|
devenv winfsp.sln /build "Installer.%Configuration%|x86"
|
||||||
if errorlevel 1 goto fail
|
if errorlevel 1 goto fail
|
||||||
|
|
||||||
for %%f in (build\%Configuration%\winfsp-*.msi) do (
|
for %%f in (build\%Configuration%\winfsp-*.msi) do (
|
||||||
signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha1 /t http://timestamp.digicert.com /d %MsiName% %%f
|
signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha1 /t http://timestamp.digicert.com /d %MsiName% %%f
|
||||||
if errorlevel 1 set /a signfail=signfail+1
|
if errorlevel 1 set /a signfail=signfail+1
|
||||||
REM signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha256 /tr http://timestamp.digicert.com /td sha256 /d %MsiName% %%f
|
REM signtool sign /ac %CrossCert% /i %Issuer% /n %Subject% /fd sha256 /tr http://timestamp.digicert.com /td sha256 /d %MsiName% %%f
|
||||||
REM if errorlevel 1 set /a signfail=signfail+1
|
REM if errorlevel 1 set /a signfail=signfail+1
|
||||||
)
|
)
|
||||||
|
|
||||||
if not %signfail%==0 echo SIGNING FAILED! The product has been successfully built, but not signed.
|
if not %signfail%==0 echo SIGNING FAILED! The product has been successfully built, but not signed.
|
||||||
|
@ -13,7 +13,6 @@ mkdir %TARGET% 2>nul
|
|||||||
for %%f in (winfsp-%SUFFIX%.sys winfsp-%SUFFIX%.dll winfsp-tests-%SUFFIX%.exe fsbench-%SUFFIX%.exe fscrash-%SUFFIX%.exe memfs-%SUFFIX%.exe) do (
|
for %%f in (winfsp-%SUFFIX%.sys winfsp-%SUFFIX%.dll winfsp-tests-%SUFFIX%.exe fsbench-%SUFFIX%.exe fscrash-%SUFFIX%.exe memfs-%SUFFIX%.exe) do (
|
||||||
copy build\VStudio\build\%CONFIG%\%%f %TARGET% >nul
|
copy build\VStudio\build\%CONFIG%\%%f %TARGET% >nul
|
||||||
)
|
)
|
||||||
copy tools\ifstest.bat %TARGET% >nul
|
|
||||||
echo sc create WinFsp type=filesys binPath=%%~dp0%DRIVER% >%TARGET%sc-create.bat
|
echo sc create WinFsp type=filesys binPath=%%~dp0%DRIVER% >%TARGET%sc-create.bat
|
||||||
echo sc start WinFsp >%TARGET%sc-start.bat
|
echo sc start WinFsp >%TARGET%sc-start.bat
|
||||||
echo sc stop WinFsp >%TARGET%sc-stop.bat
|
echo sc stop WinFsp >%TARGET%sc-stop.bat
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
setlocal
|
|
||||||
setlocal EnableDelayedExpansion
|
|
||||||
|
|
||||||
set Arch=amd64
|
|
||||||
|
|
||||||
set RegKey="HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots"
|
|
||||||
set RegVal="KitsRoot10"
|
|
||||||
reg query %RegKey% /v %RegVal% >nul 2>&1
|
|
||||||
if !ERRORLEVEL! equ 0 (
|
|
||||||
for /f "tokens=2,*" %%i in ('reg query %RegKey% /v %RegVal% ^| findstr %RegVal%') do (
|
|
||||||
set KitRoot=%%jHardware Lab Kit\
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not exist "%KitRoot%" set "KitRoot=C:\Program Files (x86)\Windows Kits\8.1\Hardware Certification Kit\"
|
|
||||||
|
|
||||||
set BaseDir=%KitRoot%Tests\%Arch%
|
|
||||||
set PATH=%BaseDir%\nttest\commontest\ntlog;%BaseDir%\nttest\basetest\core_file_services\shared_libs\fbslog;%PATH%
|
|
||||||
"%BaseDir%\nttest\basetest\core_file_services\ifs_test_kit\ifstest.exe" %*
|
|
@ -24,62 +24,40 @@ cd N: >nul 2>nul || (echo === Unable to find drive N: >&2 & goto fail)
|
|||||||
cd O: >nul 2>nul || (echo === Unable to find drive O: >&2 & goto fail)
|
cd O: >nul 2>nul || (echo === Unable to find drive O: >&2 & goto fail)
|
||||||
cd P: >nul 2>nul || (echo === Unable to find drive P: >&2 & goto fail)
|
cd P: >nul 2>nul || (echo === Unable to find drive P: >&2 & goto fail)
|
||||||
|
|
||||||
set dfl_tests=^
|
|
||||||
winfsp-tests-x64 ^
|
|
||||||
winfsp-tests-x64-case-randomize ^
|
|
||||||
winfsp-tests-x64-mountpoint-drive ^
|
|
||||||
winfsp-tests-x64-mountpoint-dir ^
|
|
||||||
winfsp-tests-x64-no-traverse ^
|
|
||||||
winfsp-tests-x64-oplock ^
|
|
||||||
winfsp-tests-x64-external-share ^
|
|
||||||
fsx-memfs-x64-disk ^
|
|
||||||
fsx-memfs-x64-net ^
|
|
||||||
standby-memfs-x64-disk ^
|
|
||||||
standby-memfs-x64-net ^
|
|
||||||
net-use-memfs-x64 ^
|
|
||||||
winfstest-memfs-x64-disk ^
|
|
||||||
winfstest-memfs-x64-net ^
|
|
||||||
fscrash-x64 ^
|
|
||||||
winfsp-tests-x86 ^
|
|
||||||
winfsp-tests-x86-case-randomize ^
|
|
||||||
winfsp-tests-x86-mountpoint-drive ^
|
|
||||||
winfsp-tests-x86-mountpoint-dir ^
|
|
||||||
winfsp-tests-x86-no-traverse ^
|
|
||||||
winfsp-tests-x86-oplock ^
|
|
||||||
winfsp-tests-x86-external-share ^
|
|
||||||
fsx-memfs-x86-disk ^
|
|
||||||
fsx-memfs-x86-net ^
|
|
||||||
standby-memfs-x86-disk ^
|
|
||||||
standby-memfs-x86-net ^
|
|
||||||
net-use-memfs-x86 ^
|
|
||||||
winfstest-memfs-x86-disk ^
|
|
||||||
winfstest-memfs-x86-net ^
|
|
||||||
fscrash-x86
|
|
||||||
set opt_tests=^
|
|
||||||
ifstest-memfs-x64-disk ^
|
|
||||||
ifstest-memfs-x86-disk
|
|
||||||
|
|
||||||
set tests=
|
|
||||||
for %%f in (%dfl_tests%) do (
|
|
||||||
if X%2==X (
|
|
||||||
set tests=!tests! %%f
|
|
||||||
) else (
|
|
||||||
set test=%%f
|
|
||||||
if not "X!test:%2=!"=="X!test!" set tests=!tests! %%f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for %%f in (%opt_tests%) do (
|
|
||||||
if X%2==X (
|
|
||||||
rem
|
|
||||||
) else (
|
|
||||||
set test=%%f
|
|
||||||
if not "X!test:%2=!"=="X!test!" set tests=!tests! %%f
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
set testpass=0
|
set testpass=0
|
||||||
set testfail=0
|
set testfail=0
|
||||||
for %%f in (%tests%) do (
|
for %%f in (^
|
||||||
|
:winfsp-tests-x64 ^
|
||||||
|
:winfsp-tests-x64-case-randomize ^
|
||||||
|
:winfsp-tests-x64-mountpoint-drive ^
|
||||||
|
:winfsp-tests-x64-mountpoint-dir ^
|
||||||
|
:winfsp-tests-x64-no-traverse ^
|
||||||
|
:winfsp-tests-x64-oplock ^
|
||||||
|
:winfsp-tests-x64-external-share ^
|
||||||
|
:fsx-memfs-x64-disk ^
|
||||||
|
:fsx-memfs-x64-net ^
|
||||||
|
:standby-memfs-x64-disk ^
|
||||||
|
:standby-memfs-x64-net ^
|
||||||
|
:net-use-memfs-x64 ^
|
||||||
|
:winfstest-memfs-x64-disk ^
|
||||||
|
:winfstest-memfs-x64-net ^
|
||||||
|
:fscrash-x64 ^
|
||||||
|
:winfsp-tests-x86 ^
|
||||||
|
:winfsp-tests-x86-case-randomize ^
|
||||||
|
:winfsp-tests-x86-mountpoint-drive ^
|
||||||
|
:winfsp-tests-x86-mountpoint-dir ^
|
||||||
|
:winfsp-tests-x86-no-traverse ^
|
||||||
|
:winfsp-tests-x86-oplock ^
|
||||||
|
:winfsp-tests-x86-external-share ^
|
||||||
|
:fsx-memfs-x86-disk ^
|
||||||
|
:fsx-memfs-x86-net ^
|
||||||
|
:standby-memfs-x86-disk ^
|
||||||
|
:standby-memfs-x86-net ^
|
||||||
|
:net-use-memfs-x86 ^
|
||||||
|
:winfstest-memfs-x86-disk ^
|
||||||
|
:winfstest-memfs-x86-net ^
|
||||||
|
:fscrash-x86 ^
|
||||||
|
) do (
|
||||||
echo === Running %%f
|
echo === Running %%f
|
||||||
|
|
||||||
if defined APPVEYOR (
|
if defined APPVEYOR (
|
||||||
@ -87,7 +65,7 @@ for %%f in (%tests%) do (
|
|||||||
)
|
)
|
||||||
|
|
||||||
pushd %cd%
|
pushd %cd%
|
||||||
call :%%f
|
call %%f
|
||||||
popd
|
popd
|
||||||
|
|
||||||
if !ERRORLEVEL! neq 0 (
|
if !ERRORLEVEL! neq 0 (
|
||||||
@ -344,139 +322,6 @@ fscrash-x86 --huge-alloc-size --cached >nul 2>&1
|
|||||||
if !ERRORLEVEL! neq 1 goto fail
|
if !ERRORLEVEL! neq 1 goto fail
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
:ifstest-memfs-x64-disk
|
|
||||||
call :__ifstest-memfs M: \Device\WinFsp.Disk C:
|
|
||||||
if !ERRORLEVEL! neq 0 goto fail
|
|
||||||
exit /b 0
|
|
||||||
|
|
||||||
:ifstest-memfs-x86-disk
|
|
||||||
call :__ifstest-memfs O: \Device\WinFsp.Disk C:
|
|
||||||
if !ERRORLEVEL! neq 0 goto fail
|
|
||||||
exit /b 0
|
|
||||||
|
|
||||||
:__ifstest-memfs
|
|
||||||
%1
|
|
||||||
set IfsTestDirectories=^
|
|
||||||
securit^
|
|
||||||
opcreatg^
|
|
||||||
opcreatp^
|
|
||||||
closedel^
|
|
||||||
volinfo^
|
|
||||||
fileinfo^
|
|
||||||
dirinfo^
|
|
||||||
filelock^
|
|
||||||
oplocks^
|
|
||||||
chgnotif^
|
|
||||||
readwr^
|
|
||||||
seccache^
|
|
||||||
reparspt^
|
|
||||||
estream
|
|
||||||
set IfsTestMemfsExit=0
|
|
||||||
call :__ifstest %1 /g Security
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
rem OpenCreateGeneral.FileOpenByIDTest: FILE_OPEN_BY_FILE_ID not implemented
|
|
||||||
rem OpenCreateGeneral.OpenVolumeTest: volume handles can be opened/closed but no other support
|
|
||||||
call :__ifstest %1 /d %2 /g OpenCreateGeneral -t FileOpenByIDTest -t OpenVolumeTest
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g OpenCreateParameters
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
rem CloseCleanupDelete.UpdateOnCloseTest: WinFsp updates size information in directories immediately
|
|
||||||
rem CloseCleanupDelete.TunnelingTest: short names and tunneling not supported
|
|
||||||
call :__ifstest %1 /g CloseCleanupDelete -t UpdateOnCloseTest -t TunnelingTest
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g VolumeInformation
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
rem FileInformation.LinkInformationTest: WinFsp does not support hard links
|
|
||||||
rem FileInformation.StreamStandardInformationTest: test requires FileLinkInformation support (no hard links)
|
|
||||||
call :__ifstest %1 /g FileInformation -t LinkInformationTest -t StreamStandardInformationTest /r %3
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g DirectoryInformation
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g FileLocking
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g OpLocks
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g ChangeNotification
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g ReadWrite
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
call :__ifstest %1 /g SectionsCaching
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
rem ReparsePoints.SetPointEASNotSupportedTest: EA's not supported
|
|
||||||
rem ReparsePoints.EnumReparsePointsTest: enumeration of reparse points not supported
|
|
||||||
rem ReparsePoints.ChangeNotificationReparseTest: change notifications of reparse points not supported
|
|
||||||
call :__ifstest %1 /g ReparsePoints -t SetPointEASNotSupportedTest -t EnumReparsePointsTest -t ChangeNotificationReparseTest /c
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
rem IfsTest ReparsePoints seems to have a bug in that it cannot handle STATUS_PENDING for FSCTL_GET_REPARSE_POINT
|
|
||||||
rmdir /s/q reparspt
|
|
||||||
rem StreamEnhancements.StreamRenameTest: WinFsp does not support stream renaming
|
|
||||||
rem StreamEnhancements.StreamNotifyNameTest: WinFsp does not notify when streams are deleted because main file is deleted
|
|
||||||
call :__ifstest %1 /g StreamEnhancements -t StreamRenameTest -t StreamNotifyNameTest
|
|
||||||
if !ERRORLEVEL! neq 0 set IfsTestMemfsExit=1
|
|
||||||
for %%d in (!IfsTestDirectories!) do (
|
|
||||||
if exist %%d (echo :ifstest directory %%d still exists & set IfsTestMemfsExit=1)
|
|
||||||
)
|
|
||||||
exit /b !IfsTestMemfsExit!
|
|
||||||
|
|
||||||
:__ifstest
|
|
||||||
set IfsTestFound=
|
|
||||||
set IfsTestName=
|
|
||||||
set IfsTestGroup=
|
|
||||||
set IfsTestStatus=
|
|
||||||
set IfsTestLines=
|
|
||||||
set IfsTestExit=0
|
|
||||||
(SET LF=^
|
|
||||||
%=this line is empty=%
|
|
||||||
)
|
|
||||||
for /F "delims=" %%l in ('call "%ProjRoot%\tools\ifstest.bat" %* /z /v ^| findstr /n "^"') do (
|
|
||||||
set IfsTestLine=%%l
|
|
||||||
set IfsTestLine=!IfsTestLine:*:=!
|
|
||||||
|
|
||||||
for /F "tokens=1,2,3 delims=:" %%h in ("%%l") do (
|
|
||||||
set FieldName=%%i
|
|
||||||
set FieldName=!FieldName: =!
|
|
||||||
set FieldValue=%%j
|
|
||||||
|
|
||||||
if not X!IfsTestLine!==X (
|
|
||||||
set IfsTestLines=!IfsTestLines!!LF! !IfsTestLine!
|
|
||||||
|
|
||||||
if X!FieldName!==XTest (
|
|
||||||
set IfsTestName=!FieldValue!
|
|
||||||
set IfsTestFound=YES
|
|
||||||
) else if X!FieldName!==XGroup (
|
|
||||||
set IfsTestGroup=!FieldValue!
|
|
||||||
) else if X!FieldName!==XStatus (
|
|
||||||
set IfsTestStatus=!FieldValue!
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
set IfsTestPrefix=!IfsTestGroup!.!IfsTestName!..............................................................
|
|
||||||
set IfsTestPrefix=!IfsTestPrefix:~0,63!
|
|
||||||
if X!IfsTestName!==X (
|
|
||||||
rem
|
|
||||||
) else if X!IfsTestStatus!==X (
|
|
||||||
rem
|
|
||||||
) else if not "X!IfsTestStatus:(IFSTEST_SUCCESS)=!"=="X!IfsTestStatus!" (
|
|
||||||
echo !IfsTestPrefix! OK
|
|
||||||
) else if not "X!IfsTestStatus:(IFSTEST_TEST_NOT_SUPPORTED)=!"=="X!IfsTestStatus!" (
|
|
||||||
echo !IfsTestPrefix! SKIP
|
|
||||||
) else if not "X!IfsTestStatus:(IFSTEST_SUCCESS_NOT_SUPPORTED)=!"=="X!IfsTestStatus!" (
|
|
||||||
echo !IfsTestPrefix! SKIP
|
|
||||||
) else if not "X!IfsTestStatus:(IFSTEST_INFO_END_OF_GROUP)=!"=="X!IfsTestStatus!" (
|
|
||||||
rem
|
|
||||||
) else (
|
|
||||||
echo !IfsTestPrefix! KO!IfsTestLines!
|
|
||||||
set IfsTestExit=1
|
|
||||||
)
|
|
||||||
set IfsTestName=
|
|
||||||
set IfsTestGroup=
|
|
||||||
set IfsTestStatus=
|
|
||||||
set IfsTestLines=
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if not X!IfsTestFound!==XYES set IfsTestExit=1
|
|
||||||
exit /b !IfsTestExit!
|
|
||||||
|
|
||||||
:leak-test
|
:leak-test
|
||||||
for /F "tokens=1,2 delims=:" %%i in ('verifier /query ^| findstr ^
|
for /F "tokens=1,2 delims=:" %%i in ('verifier /query ^| findstr ^
|
||||||
/c:"Current Pool Allocations:" ^
|
/c:"Current Pool Allocations:" ^
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file fsbench.c
|
* @file fsbench.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file fscrash-main.c
|
* @file fscrash-main.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file fscrash.c
|
* @file fscrash.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file fscrash.h
|
* @file fscrash.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2016 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user