mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-02 17:02:57 -05:00
Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
8320160d73 | |||
ce057b49b8 | |||
a60c989089 | |||
0f6371f0d8 | |||
1a4bbbe09a | |||
4e891dc2a8 | |||
18a77d63c3 | |||
4ea9c6e362 | |||
9d77c192a8 | |||
6d5401d911 | |||
330d6e79f8 | |||
ed58b7a63c | |||
f6853114c1 | |||
8ec7285d32 | |||
c183c0fe89 | |||
38ad8fd27d | |||
de85070e73 | |||
5b8ebd6e1d | |||
db530cb5e5 | |||
7cd4d4faab | |||
2560a513dc | |||
1ee95be5d7 | |||
bd7546559c | |||
d18a2c8b75 | |||
0ebae0adc1 | |||
d70c49ccd0 | |||
5846939116 | |||
f124e74f01 | |||
05abb93e4b | |||
5839d46b7a | |||
bce0d63f7d | |||
14b9f5affc | |||
035a430470 | |||
0af9e46e76 | |||
c4530f1252 | |||
9f78a17583 | |||
eea0b1bc79 | |||
8338a6e066 | |||
ddba49dbea | |||
a6ff8a87de | |||
bf64bcf9ba | |||
8c5d9bda20 | |||
f1ac28b0aa | |||
ff725f931d | |||
31519ba416 | |||
0bca8f851c | |||
acf175da60 | |||
23eac24c84 | |||
0f9ef3bd51 | |||
2bdd54536e | |||
060ebcca0d | |||
b38a89e485 | |||
b5bfeee027 | |||
f36cacaf84 | |||
4278cec465 | |||
151627091b | |||
2ee3f02928 | |||
d77d3ccccf | |||
1e0c91658e |
@ -1,11 +1,14 @@
|
||||
= Changelog
|
||||
|
||||
v1.1B3 (2017.1 B3)::
|
||||
|
||||
v1.1 (2017.1)::
|
||||
v1.1B2 (2017.1 B2)::
|
||||
|
||||
v1.1B1 (2017.1 BETA)::
|
||||
|
||||
This release brings some major new components and improvements.
|
||||
|
||||
- A .NET layer that allows the creation of file systems in managed mode. This is contained in the new `winfsp-msil.dll`.
|
||||
- A .NET layer that allows the creation of file systems in managed mode. This is contained in the new `winfsp-msil.dll`. The new .NET layer is being tested with the WinFsp test suites and Microsoft's ifstest.
|
||||
- A simple C++ layer can be found in `inc/winfsp/winfsp.hpp`.
|
||||
- FUSE for Cygwin is now included with the installer.
|
||||
- FUSE now has a `-ovolname=VOLNAME` parameter that allows setting the volume label. Thanks @samkelly.
|
||||
|
@ -42,7 +42,8 @@ The project source code is organized as follows:
|
||||
* src/launcher: Source code to the launcher service and the launchctl utility.
|
||||
* src/sys: Source code to the WinFsp FSD.
|
||||
* opt/cygfuse: Source code for the Cygwin FUSE package.
|
||||
* tst/memfs: Source code to an example file system written in C++ (memfs).
|
||||
* tst/memfs*: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet).
|
||||
* tst/passthrough*: Source code to additional example file systems.
|
||||
* tst/winfsp-tests: WinFsp test suite.
|
||||
|
||||
## Building and Running
|
||||
@ -72,7 +73,7 @@ WinFsp is designed to run on Windows 7 and above. It has been tested on the foll
|
||||
I am looking for help in the following areas:
|
||||
|
||||
* If you have a file system that runs on FUSE please consider porting it to WinFsp. WinFsp has a native API, but it also has a FUSE (high-level) API.
|
||||
* If you are working with a language other than C/C++ (e.g. Delphi, C#, etc.) and you are interested in porting/wrapping WinFsp I would love to hear from you.
|
||||
* If you are working with a language other than C/C++ (e.g. Delphi, Java, 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.
|
||||
|
||||
In all cases I can provide ideas and/or support.
|
||||
|
1
build/VStudio/.gitignore
vendored
1
build/VStudio/.gitignore
vendored
@ -3,3 +3,4 @@ build
|
||||
*.suo
|
||||
*.vcproj.*
|
||||
*.vcxproj.user
|
||||
*.csproj.user
|
||||
|
@ -25,6 +25,8 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml</DocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -36,6 +38,8 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DocumentationFile>$(BaseIntermediateOutputPath)$(Configuration)\winfsp-msil.xml</DocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
|
@ -92,6 +92,9 @@
|
||||
<Component Id="C.winfsp_msil.dll" Guid="0D8BA6AE-9F87-402B-AE1A-95B0AE3BE179">
|
||||
<File Id="FILE.winfsp_msil.dll" Name="winfsp-msil.dll" KeyPath="yes" />
|
||||
</Component>
|
||||
<Component Id="C.winfsp_msil.xml" Guid="1657F707-C112-454C-91AE-0FDEBBF454AB">
|
||||
<File Id="FILE.winfsp_msil.xml" Name="winfsp-msil.xml" KeyPath="yes" />
|
||||
</Component>
|
||||
<!--
|
||||
<Component Id="C.winfsp_msil.dll.GAC" Guid="6469467D-8C90-4889-8138-4028F9DA6E85">
|
||||
<File Id="FILE.winfsp_msil.dll.GAC" Name="winfsp-msil.dll" KeyPath="yes" Assembly=".net" />
|
||||
@ -214,6 +217,32 @@
|
||||
</RegistryKey>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
<Component Id="C.memfs_dotnet_msil.exe">
|
||||
<File Name="memfs-dotnet-msil.exe" KeyPath="yes" />
|
||||
<RegistryKey
|
||||
Root="HKLM"
|
||||
Key="[P.LauncherRegistryKey]">
|
||||
<RegistryKey
|
||||
Key="memfs-dotnet">
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="Executable"
|
||||
Value="[BINDIR]memfs-dotnet-msil.exe" />
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="CommandLine"
|
||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||
<RegistryValue
|
||||
Type="string"
|
||||
Name="Security"
|
||||
Value="D:P(A;;RPWPLC;;;WD)" />
|
||||
<RegistryValue
|
||||
Type="integer"
|
||||
Name="JobControl"
|
||||
Value="1" />
|
||||
</RegistryKey>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="INCDIR" FileSource="..\..\..\inc">
|
||||
<Directory Id="INCDIR.winfsp" Name="winfsp">
|
||||
@ -272,9 +301,16 @@
|
||||
</DirectoryRef>
|
||||
<DirectoryRef Id="OPTDIR">
|
||||
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
|
||||
<Component Id="C.fuse.tar.xz">
|
||||
<File Name="fuse-2.8-4.tar.xz" KeyPath="yes" />
|
||||
</Component>
|
||||
<Directory Id="OPTDIR.cygfuse.x64" Name="x64">
|
||||
<Component Id="C.fuse.tar.xz.x64">
|
||||
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-5.tar.xz" KeyPath="yes" />
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="OPTDIR.cygfuse.x86" Name="x86">
|
||||
<Component Id="C.fuse.tar.xz.x86">
|
||||
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-5.tar.xz" KeyPath="yes" />
|
||||
</Component>
|
||||
</Directory>
|
||||
<Component Id="C.fuse.install.sh">
|
||||
<File Name="install.sh" KeyPath="yes" />
|
||||
</Component>
|
||||
@ -295,6 +331,11 @@
|
||||
<File Name="memfs-main.c" KeyPath="yes" />
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="SMPDIR.memfs_dotnet" Name="memfs-dotnet">
|
||||
<Component Id="C.memfs_dotnet.Program.cs">
|
||||
<File Id="FILE.memfs_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
|
||||
</Component>
|
||||
</Directory>
|
||||
<Directory Id="SMPDIR.passthrough" Name="passthrough">
|
||||
<Component Id="C.passthrough.c">
|
||||
<File Name="passthrough.c" KeyPath="yes" />
|
||||
@ -351,7 +392,7 @@
|
||||
</Directory>
|
||||
<Directory Id="SMPDIR.passthrough_dotnet" Name="passthrough-dotnet">
|
||||
<Component Id="C.passthrough_dotnet.Program.cs">
|
||||
<File Name="Program.cs" KeyPath="yes" />
|
||||
<File Id="FILE.passthrough_dotnet.Program.cs" Name="Program.cs" KeyPath="yes" />
|
||||
</Component>
|
||||
<Component Id="C.passthrough_dotnet.sln">
|
||||
<File Name="passthrough-dotnet.sln" KeyPath="yes" />
|
||||
@ -426,7 +467,8 @@
|
||||
<ComponentRef Id="C.fuse_x86.pc" />
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="C.WinFsp.opt.fuse">
|
||||
<ComponentRef Id="C.fuse.tar.xz" />
|
||||
<ComponentRef Id="C.fuse.tar.xz.x64" />
|
||||
<ComponentRef Id="C.fuse.tar.xz.x86" />
|
||||
<ComponentRef Id="C.fuse.install.sh" />
|
||||
<ComponentRef Id="C.fuse.uninstall.sh" />
|
||||
</ComponentGroup>
|
||||
@ -467,12 +509,15 @@
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="C.WinFsp.net">
|
||||
<ComponentRef Id="C.winfsp_msil.dll" />
|
||||
<ComponentRef Id="C.winfsp_msil.xml" />
|
||||
<!--
|
||||
<ComponentRef Id="C.winfsp_msil.dll.GAC" />
|
||||
<ComponentRef Id="C.policy.winfsp_msil.dll.GAC" />
|
||||
-->
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="C.WinFsp.smp.net">
|
||||
<ComponentRef Id="C.memfs_dotnet_msil.exe" />
|
||||
<ComponentRef Id="C.memfs_dotnet.Program.cs" />
|
||||
<ComponentRef Id="C.passthrough_dotnet.Program.cs" />
|
||||
<ComponentRef Id="C.passthrough_dotnet.sln" />
|
||||
<ComponentRef Id="C.passthrough_dotnet.csproj" />
|
||||
@ -531,7 +576,7 @@
|
||||
Id="F.Cygfuse"
|
||||
Level="1000"
|
||||
Title="FUSE for Cygwin"
|
||||
Description="From a Cygwin prompt change to $InstallDir/opt/cygfuse and run install.sh."
|
||||
Description="From a Cygwin prompt change to <InstallDir>/opt/cygfuse and run install.sh."
|
||||
AllowAdvertise="no"
|
||||
InstallDefault="local"
|
||||
Absent="allow">
|
||||
|
63
build/VStudio/testing/memfs-dotnet.csproj
Normal file
63
build/VStudio/testing/memfs-dotnet.csproj
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{4920E350-D496-4652-AE98-6C4208AEC1D8}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<ProjectName>memfs-dotnet</ProjectName>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>memfs</RootNamespace>
|
||||
<AssemblyName>memfs-dotnet-msil</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\..\..\tst\memfs-dotnet\Program.cs">
|
||||
<Link>Program.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\dotnet\winfsp.net.csproj">
|
||||
<Project>{94580219-cc8d-4fe5-a3be-437b0b3481e1}</Project>
|
||||
<Name>winfsp.net</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
@ -17,7 +17,7 @@
|
||||
|
||||
<MyCanonicalVersion>1.1</MyCanonicalVersion>
|
||||
|
||||
<MyProductVersion>2017.1 BETA</MyProductVersion>
|
||||
<MyProductVersion>2017.1 B3</MyProductVersion>
|
||||
<MyProductStage>Beta</MyProductStage>
|
||||
|
||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||
|
@ -61,6 +61,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "winfsp.net", "dotnet\winfsp
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{A998CEC4-4B34-43DC-8457-F7761228BA67}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "memfs-dotnet", "testing\memfs-dotnet.csproj", "{4920E350-D496-4652-AE98-6C4208AEC1D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -259,6 +261,30 @@ Global
|
||||
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{94580219-CC8D-4FE5-A3BE-437B0B3481E1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -273,5 +299,6 @@ Global
|
||||
{10757011-749D-4954-873B-AE38D8145472} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
{94580219-CC8D-4FE5-A3BE-437B0B3481E1} = {A998CEC4-4B34-43DC-8457-F7761228BA67}
|
||||
{4920E350-D496-4652-AE98-6C4208AEC1D8} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -5,12 +5,15 @@ This document contains a list of known file systems and file system libraries th
|
||||
== File Systems
|
||||
|
||||
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
|
||||
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage
|
||||
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
|
||||
- https://github.com/billziss-gh/redditfs[redditfs] - ls -l /r/programming
|
||||
- https://github.com/netheril96/securefs[securefs] - Filesystem in userspace (FUSE) with transparent authenticated encryption
|
||||
- https://github.com/billziss-gh/sshfs-win[sshfs-win] - SSHFS for Windows
|
||||
|
||||
== File System Libraries
|
||||
|
||||
- https://github.com/billziss-gh/cgofuse[cgofuse] - Cross-platform FUSE library for Go
|
||||
- https://github.com/DuroSoft/fuse-bindings[fuse-bindings] - Fully maintained FUSE bindings for Node that aims to cover the entire FUSE api
|
||||
- https://github.com/ui4j/fuse-jna[fuse-jna] - No-nonsense, actually-working Java bindings to FUSE using JNA
|
||||
- https://github.com/billziss-gh/fusepy[fusepy] - Simple ctypes bindings for FUSE
|
||||
|
@ -118,6 +118,8 @@ FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_loop_mt)(struct fsp_fuse_env *env,
|
||||
struct fuse *f);
|
||||
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_exit)(struct fsp_fuse_env *env,
|
||||
struct fuse *f);
|
||||
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env,
|
||||
struct fuse *f);
|
||||
FSP_FUSE_API struct fuse_context *FSP_FUSE_API_NAME(fsp_fuse_get_context)(struct fsp_fuse_env *env);
|
||||
|
||||
FSP_FUSE_SYM(
|
||||
@ -171,6 +173,13 @@ void fuse_exit(struct fuse *f),
|
||||
(fsp_fuse_env(), f);
|
||||
})
|
||||
|
||||
FSP_FUSE_SYM(
|
||||
int fuse_exited(struct fuse *f),
|
||||
{
|
||||
return FSP_FUSE_API_CALL(fsp_fuse_exited)
|
||||
(fsp_fuse_env(), f);
|
||||
})
|
||||
|
||||
FSP_FUSE_SYM(
|
||||
struct fuse_context *fuse_get_context(void),
|
||||
{
|
||||
|
@ -178,6 +178,7 @@ struct fuse_flock
|
||||
fsp_fuse_daemonize, \
|
||||
fsp_fuse_set_signal_handlers, \
|
||||
0/*conv_to_win_path*/, \
|
||||
{ 0 }, \
|
||||
}
|
||||
#else
|
||||
#define FSP_FUSE_ENV_INIT \
|
||||
@ -187,6 +188,7 @@ struct fuse_flock
|
||||
fsp_fuse_daemonize, \
|
||||
fsp_fuse_set_signal_handlers, \
|
||||
0/*conv_to_win_path*/, \
|
||||
{ 0 }, \
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -229,6 +231,7 @@ struct fuse_flock
|
||||
fsp_fuse_daemonize, \
|
||||
fsp_fuse_set_signal_handlers, \
|
||||
fsp_fuse_conv_to_win_path, \
|
||||
{ 0 }, \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -18,3 +18,11 @@ cygport:
|
||||
> opt/cygfuse/winfsp-work.tar.gz\
|
||||
)
|
||||
CYGPORT_SRC_URI=winfsp-work.tar.gz CYGPORT_SRC_DIR=winfsp-work cygport fuse.cygport download prep compile install package
|
||||
|
||||
dist: cygport
|
||||
case $(shell uname -m) in \
|
||||
x86_64)\
|
||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\
|
||||
*)\
|
||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\
|
||||
esac
|
||||
|
@ -17,22 +17,39 @@
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/cygwin.h>
|
||||
|
||||
static void *cygfuse_init_slow(int force);
|
||||
static void *cygfuse_init_winfsp();
|
||||
static void *cygfuse_init_fail();
|
||||
|
||||
static pthread_mutex_t cygfuse_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void *cygfuse_handle = 0;
|
||||
|
||||
static inline void cygfuse_init(int force)
|
||||
static inline void *cygfuse_init_fast(void)
|
||||
{
|
||||
void *handle = cygfuse_handle;
|
||||
__sync_synchronize(); /* memory barrier */
|
||||
if (0 == handle)
|
||||
handle = cygfuse_init_slow(0);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void *cygfuse_init_slow(int force)
|
||||
{
|
||||
void *handle;
|
||||
pthread_mutex_lock(&cygfuse_mutex);
|
||||
if (force || 0 == cygfuse_handle)
|
||||
cygfuse_handle = cygfuse_init_winfsp();
|
||||
handle = cygfuse_handle;
|
||||
if (force || 0 == handle)
|
||||
{
|
||||
handle = cygfuse_init_winfsp();
|
||||
__sync_synchronize(); /* memory barrier */
|
||||
cygfuse_handle = handle;
|
||||
}
|
||||
pthread_mutex_unlock(&cygfuse_mutex);
|
||||
return handle;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -50,7 +67,7 @@ static inline int cygfuse_daemon(int nochdir, int noclose)
|
||||
return -1;
|
||||
|
||||
/* force reload of WinFsp DLL to workaround fork() problems */
|
||||
cygfuse_init(1);
|
||||
cygfuse_init_slow(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -58,7 +75,7 @@ static inline int cygfuse_daemon(int nochdir, int noclose)
|
||||
|
||||
#define FSP_FUSE_API static
|
||||
#define FSP_FUSE_API_NAME(api) (* pfn_ ## api)
|
||||
#define FSP_FUSE_API_CALL(api) (cygfuse_init(0), pfn_ ## api)
|
||||
#define FSP_FUSE_API_CALL(api) (cygfuse_init_fast(), pfn_ ## api)
|
||||
#define FSP_FUSE_SYM(proto, ...) __attribute__ ((visibility("default"))) proto { __VA_ARGS__ }
|
||||
#include <fuse_common.h>
|
||||
#include <fuse.h>
|
||||
@ -74,6 +91,7 @@ static inline int cygfuse_daemon(int nochdir, int noclose)
|
||||
if (0 == (*(void **)&(pfn_ ## n) = dlsym(h, #n)))\
|
||||
return cygfuse_init_fail();
|
||||
|
||||
static void *cygfuse_init_fail();
|
||||
static void *cygfuse_init_winfsp()
|
||||
{
|
||||
void *h;
|
||||
@ -125,6 +143,7 @@ static void *cygfuse_init_winfsp()
|
||||
CYGFUSE_GET_API(h, fsp_fuse_loop);
|
||||
CYGFUSE_GET_API(h, fsp_fuse_loop_mt);
|
||||
CYGFUSE_GET_API(h, fsp_fuse_exit);
|
||||
CYGFUSE_GET_API(h, fsp_fuse_exited);
|
||||
CYGFUSE_GET_API(h, fsp_fuse_get_context);
|
||||
|
||||
/* fuse_opt.h */
|
||||
@ -141,6 +160,7 @@ static void *cygfuse_init_winfsp()
|
||||
|
||||
static void *cygfuse_init_fail()
|
||||
{
|
||||
abort();
|
||||
fprintf(stderr, "cygfuse: initialization failed: " CYGFUSE_WINFSP_NAME " not found\n");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
BIN
opt/cygfuse/dist/fuse-2.8-4.tar.xz
vendored
BIN
opt/cygfuse/dist/fuse-2.8-4.tar.xz
vendored
Binary file not shown.
9
opt/cygfuse/dist/install.sh
vendored
9
opt/cygfuse/dist/install.sh
vendored
@ -1 +1,8 @@
|
||||
tar -C/ -xaf fuse-2.8-*.tar.xz
|
||||
cd "$(dirname "$0")"
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
tar -C/ -xaf x64/fuse-2.8-*.tar.xz ;;
|
||||
*)
|
||||
tar -C/ -xaf x86/fuse-2.8-*.tar.xz ;;
|
||||
esac
|
||||
echo FUSE for Cygwin installed.
|
||||
|
9
opt/cygfuse/dist/uninstall.sh
vendored
9
opt/cygfuse/dist/uninstall.sh
vendored
@ -1 +1,8 @@
|
||||
tar -taf fuse-2.8-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f
|
||||
cd "$(dirname "$0")"
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
tar -taf x64/fuse-2.8-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f ;;
|
||||
*)
|
||||
tar -taf x86/fuse-2.8-*.tar.xz | sed -e '/\/$/d' -e 's/.*/\/&/' | xargs rm -f ;;
|
||||
esac
|
||||
echo FUSE for Cygwin uninstalled.
|
||||
|
BIN
opt/cygfuse/dist/x64/fuse-2.8-5.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x64/fuse-2.8-5.tar.xz
vendored
Normal file
Binary file not shown.
BIN
opt/cygfuse/dist/x86/fuse-2.8-5.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x86/fuse-2.8-5.tar.xz
vendored
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
NAME="fuse"
|
||||
VERSION=2.8
|
||||
RELEASE=4
|
||||
RELEASE=5
|
||||
CATEGORY="Utils"
|
||||
SUMMARY="WinFsp-FUSE compatibility layer"
|
||||
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin."
|
||||
|
@ -96,8 +96,11 @@ static struct fuse_opt fsp_fuse_core_opts[] =
|
||||
FSP_FUSE_CORE_OPT("VolumeSerialNumber=%lx", VolumeParams.VolumeSerialNumber, 0),
|
||||
FSP_FUSE_CORE_OPT("FileInfoTimeout=", set_FileInfoTimeout, 1),
|
||||
FSP_FUSE_CORE_OPT("FileInfoTimeout=%d", VolumeParams.FileInfoTimeout, 0),
|
||||
FUSE_OPT_KEY("UNC=", 'U'),
|
||||
FUSE_OPT_KEY("--UNC=", 'U'),
|
||||
FUSE_OPT_KEY("VolumePrefix=", 'U'),
|
||||
FUSE_OPT_KEY("--VolumePrefix=", 'U'),
|
||||
FUSE_OPT_KEY("FileSystemName=", 'F'),
|
||||
FUSE_OPT_KEY("--FileSystemName=", 'F'),
|
||||
|
||||
FUSE_OPT_END,
|
||||
@ -457,17 +460,26 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
|
||||
default:
|
||||
return 1;
|
||||
case 'h':
|
||||
/* Note: The limit on FspServiceLog messages is 1024 bytes. This is getting close. */
|
||||
FspServiceLog(EVENTLOG_ERROR_TYPE, L""
|
||||
FSP_FUSE_LIBRARY_NAME " options:\n"
|
||||
" -o DebugLog=FILE debug log file (deflt: stderr)\n"
|
||||
" -o umask=MASK set file permissions (octal)\n"
|
||||
" -o uid=N set file owner (-1 for mounting user id)\n"
|
||||
" -o gid=N set file group (-1 for mounting user group)\n"
|
||||
" -o rellinks interpret absolute symlinks as volume relative\n"
|
||||
" -o volname=NAME set volume label\n"
|
||||
" -o VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n"
|
||||
" -o FileSystemName=NAME set file system name\n"
|
||||
" -o DebugLog=FILE debug log file (requires -d)\n"
|
||||
"\n"
|
||||
FSP_FUSE_LIBRARY_NAME " advanced options:\n"
|
||||
" -o FileInfoTimeout=N metadata timeout (millis, -1 for data caching)\n"
|
||||
" -o SectorSize=N sector size for Windows (512-4096, deflt: 4096)\n"
|
||||
" -o SectorsPerAllocationUnit=N sectors per allocation unit (deflt: 1)\n"
|
||||
" -o MaxComponentLength=N max file name component length (deflt: 255)\n"
|
||||
" -o VolumeCreationTime=T volume creation time (FILETIME hex format)\n"
|
||||
" -o VolumeSerialNumber=N 32-bit wide\n"
|
||||
" -o FileInfoTimeout=N FileInfo/Security/VolumeInfo timeout (millisec)\n"
|
||||
" --UNC=U --VolumePrefix=U UNC prefix (\\Server\\Share)\n"
|
||||
" --FileSystemName=FSN Name of user mode file system\n");
|
||||
" -o VolumeSerialNumber=N volume serial number (32-bit wide)\n"
|
||||
);
|
||||
opt_data->help = 1;
|
||||
return 1;
|
||||
case 'V':
|
||||
@ -488,8 +500,12 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
|
||||
0);
|
||||
return 0;
|
||||
case 'U':
|
||||
if ('U' == arg[2])
|
||||
if ('U' == arg[0])
|
||||
arg += sizeof "UNC=" - 1;
|
||||
else if ('U' == arg[2])
|
||||
arg += sizeof "--UNC=" - 1;
|
||||
else if ('V' == arg[0])
|
||||
arg += sizeof "VolumePrefix=" - 1;
|
||||
else if ('V' == arg[2])
|
||||
arg += sizeof "--VolumePrefix=" - 1;
|
||||
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1,
|
||||
@ -501,6 +517,8 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
|
||||
case 'F':
|
||||
if ('f' == arg[0])
|
||||
arg += sizeof "fstypename=" - 1;
|
||||
else if ('F' == arg[0])
|
||||
arg += sizeof "FileSystemName=" - 1;
|
||||
else if ('F' == arg[2])
|
||||
arg += sizeof "--FileSystemName=" - 1;
|
||||
if (0 == MultiByteToWideChar(CP_UTF8, 0, arg, -1,
|
||||
@ -687,6 +705,13 @@ FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env,
|
||||
{
|
||||
if (0 != f->Service)
|
||||
FspServiceStop(f->Service);
|
||||
f->exited = 1;
|
||||
}
|
||||
|
||||
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_exited)(struct fsp_fuse_env *env,
|
||||
struct fuse *f)
|
||||
{
|
||||
return f->exited;
|
||||
}
|
||||
|
||||
FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *env)
|
||||
|
@ -50,6 +50,7 @@ struct fuse
|
||||
PWSTR MountPoint;
|
||||
FSP_FILE_SYSTEM *FileSystem;
|
||||
FSP_SERVICE *Service; /* weak */
|
||||
volatile int exited;
|
||||
};
|
||||
|
||||
struct fsp_fuse_context_header
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dotnet/FileSystemBase+Const.cs
|
||||
/*
|
||||
* dotnet/FileSystemBase+Const.cs
|
||||
*
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
* Copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dotnet/FileSystemBase.cs
|
||||
/*
|
||||
* dotnet/FileSystemBase.cs
|
||||
*
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
* Copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -24,6 +24,9 @@ using Fsp.Interop;
|
||||
namespace Fsp
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provides the base class that user mode file systems must inherit from.
|
||||
/// </summary>
|
||||
public partial class FileSystemBase
|
||||
{
|
||||
/* types */
|
||||
@ -48,27 +51,73 @@ namespace Fsp
|
||||
}
|
||||
|
||||
/* operations */
|
||||
/// <summary>
|
||||
/// Provides a means to customize the returned status code when an exception happens.
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 ExceptionHandler(Exception ex)
|
||||
{
|
||||
Api.FspDebugLog("%s\n", ex.ToString());
|
||||
return STATUS_UNEXPECTED_IO_ERROR;
|
||||
}
|
||||
/// <summary>
|
||||
/// Occurs just before the file system is mounted.
|
||||
/// File systems may override this method to configure the file system host.
|
||||
/// </summary>
|
||||
/// <param name="Host">
|
||||
/// The file system host that is mounting this file system.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Init(Object Host)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/// <summary>
|
||||
/// Occurs just after the file system is mounted,
|
||||
/// but prior to receiving any file system operation.
|
||||
/// </summary>
|
||||
/// <param name="Host">
|
||||
/// The file system host that is mounting this file system.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Mounted(Object Host)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/// <summary>
|
||||
/// Occurs just after the file system is unmounted.
|
||||
/// No other file system operations will be received on this file system.
|
||||
/// </summary>
|
||||
/// <param name="Host">
|
||||
/// The file system host that is mounting this file system.
|
||||
/// </param>
|
||||
public virtual void Unmounted(Object Host)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the volume information.
|
||||
/// </summary>
|
||||
/// <param name="VolumeInfo">
|
||||
/// Receives the volume information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 GetVolumeInfo(
|
||||
out VolumeInfo VolumeInfo)
|
||||
{
|
||||
VolumeInfo = default(VolumeInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the volume label.
|
||||
/// </summary>
|
||||
/// <param name="VolumeLabel">
|
||||
/// The new label for the volume.
|
||||
/// </param>
|
||||
/// <param name="VolumeInfo">
|
||||
/// Receives the updated volume information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 SetVolumeLabel(
|
||||
String VolumeLabel,
|
||||
out VolumeInfo VolumeInfo)
|
||||
@ -76,6 +125,27 @@ namespace Fsp
|
||||
VolumeInfo = default(VolumeInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets file or directory attributes and security descriptor given a file name.
|
||||
/// </summary>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to get the attributes and security descriptor for.
|
||||
/// </param>
|
||||
/// <param name="FileAttributes">
|
||||
/// Receives the file attributes on successful return.
|
||||
/// If this call returns STATUS_REPARSE, the file system may place here the index of the
|
||||
/// first reparse point within FileName.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// Receives the file security descriptor. If the SecurityDescriptor parameter is null
|
||||
/// on input the file system should not fill this value.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// STATUS_SUCCESS, STATUS_REPARSE or error code.
|
||||
/// STATUS_REPARSE should be returned by file systems that support reparse points when
|
||||
/// they encounter a FileName that contains reparse points anywhere but the final path
|
||||
/// component.
|
||||
/// </returns>
|
||||
public virtual Int32 GetSecurityByName(
|
||||
String FileName,
|
||||
out UInt32 FileAttributes/* or ReparsePointIndex */,
|
||||
@ -84,6 +154,40 @@ namespace Fsp
|
||||
FileAttributes = default(UInt32);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new file or directory.
|
||||
/// </summary>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to be created.
|
||||
/// </param>
|
||||
/// <param name="CreateOptions">
|
||||
/// Create options for this request.
|
||||
/// </param>
|
||||
/// <param name="GrantedAccess">
|
||||
/// Determines the specific access rights that have been granted for this request.
|
||||
/// </param>
|
||||
/// <param name="FileAttributes">
|
||||
/// File attributes to apply to the newly created file or directory.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// Security descriptor to apply to the newly created file or directory.
|
||||
/// </param>
|
||||
/// <param name="AllocationSize">
|
||||
/// Allocation size for the newly created file.
|
||||
/// </param>
|
||||
/// <param name="FileNode">
|
||||
/// Receives the file node for the newly created file.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// Receives the file descriptor for the newly created file.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the file information for the newly created file.
|
||||
/// </param>
|
||||
/// <param name="NormalizedName">
|
||||
/// Receives the normalized name for the newly created file.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Create(
|
||||
String FileName,
|
||||
UInt32 CreateOptions,
|
||||
@ -102,6 +206,31 @@ namespace Fsp
|
||||
NormalizedName = default(String);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Opens a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to be opened.
|
||||
/// </param>
|
||||
/// <param name="CreateOptions">
|
||||
/// Create options for this request.
|
||||
/// </param>
|
||||
/// <param name="GrantedAccess">
|
||||
/// Determines the specific access rights that have been granted for this request.
|
||||
/// </param>
|
||||
/// <param name="FileNode">
|
||||
/// Receives the file node for the newly opened file.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// Receives the file descriptor for the newly opened file.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the file information for the newly opened file.
|
||||
/// </param>
|
||||
/// <param name="NormalizedName">
|
||||
/// Receives the normalized name for the newly opened file.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Open(
|
||||
String FileName,
|
||||
UInt32 CreateOptions,
|
||||
@ -117,6 +246,29 @@ namespace Fsp
|
||||
NormalizedName = default(String);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Overwrites a file.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node for the file to be overwritten.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor for the file to be overwritten.
|
||||
/// </param>
|
||||
/// <param name="FileAttributes">
|
||||
/// File attributes to apply to the overwritten file.
|
||||
/// </param>
|
||||
/// <param name="ReplaceFileAttributes">
|
||||
/// When true the existing file attributes should be replaced with the new ones.
|
||||
/// When false the existing file attributes should be merged (or'ed) with the new ones.
|
||||
/// </param>
|
||||
/// <param name="AllocationSize">
|
||||
/// Allocation size for the overwritten file.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the updated file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Overwrite(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -128,6 +280,64 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Cleans up a file or directory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// When CreateFile is used to open or create a file the kernel creates a kernel mode file
|
||||
/// object (type FILE_OBJECT) and a handle for it, which it returns to user-mode. The handle may
|
||||
/// be duplicated (using DuplicateHandle), but all duplicate handles always refer to the same
|
||||
/// file object. When all handles for a particular file object get closed (using CloseHandle)
|
||||
/// the system sends a Cleanup request to the file system.
|
||||
/// </para><para>
|
||||
/// 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.
|
||||
/// The file system must be ready to receive additional operations until close time. This is true
|
||||
/// even when the file is being deleted!
|
||||
/// </para><para>
|
||||
/// The Flags parameter contains information about the cleanup operation:
|
||||
/// <list>
|
||||
/// <item>CleanupDelete -
|
||||
/// An important function of the Cleanup operation is to complete a delete operation. Deleting
|
||||
/// a file or directory in Windows is a three-stage process where the file is first opened, then
|
||||
/// tested to see if the delete can proceed and if the answer is positive the file is then
|
||||
/// deleted during Cleanup.
|
||||
/// When this flag is set, this is the last outstanding cleanup for this particular file node.
|
||||
/// </item>
|
||||
/// <item>CleanupSetAllocationSize -
|
||||
/// 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.
|
||||
/// </item>
|
||||
/// <item>CleanupSetArchiveBit -
|
||||
/// File systems that support the archive bit should set the file node's archive bit when this
|
||||
/// flag is set.
|
||||
/// </item>
|
||||
/// <item>CleanupSetLastAccessTime, CleanupSetLastWriteTime, CleanupSetChangeTime -
|
||||
/// 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.
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </para><para>
|
||||
/// There is no way to report failure of this operation. This is a Windows limitation.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to cleanup.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to cleanup.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to cleanup. Sent only when a Delete is requested.
|
||||
/// </param>
|
||||
/// <param name="Flags">
|
||||
/// These flags determine whether the file was modified and whether to delete the file.
|
||||
/// </param>
|
||||
/// <seealso cref="CanDelete"/>
|
||||
/// <seealso cref="Close"/>
|
||||
public virtual void Cleanup(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -135,11 +345,42 @@ namespace Fsp
|
||||
UInt32 Flags)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Closes a file or directory.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to close.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to close.
|
||||
/// </param>
|
||||
public virtual void Close(
|
||||
Object FileNode,
|
||||
Object FileDesc)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a file.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to read.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to read.
|
||||
/// </param>
|
||||
/// <param name="Buffer">
|
||||
/// Pointer to a buffer that receives the results of the read operation.
|
||||
/// </param>
|
||||
/// <param name="Offset">
|
||||
/// Offset within the file to read from.
|
||||
/// </param>
|
||||
/// <param name="Length">
|
||||
/// Length of data to read.
|
||||
/// </param>
|
||||
/// <param name="BytesTransferred">
|
||||
/// Receives the actual number of bytes read.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Read(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -151,6 +392,38 @@ namespace Fsp
|
||||
BytesTransferred = default(UInt32);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes a file.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to write.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to write.
|
||||
/// </param>
|
||||
/// <param name="Buffer">
|
||||
/// Pointer to a buffer that receives the results of the write operation.
|
||||
/// </param>
|
||||
/// <param name="Offset">
|
||||
/// Offset within the file to write to.
|
||||
/// </param>
|
||||
/// <param name="Length">
|
||||
/// Length of data to write.
|
||||
/// </param>
|
||||
/// <param name="WriteToEndOfFile">
|
||||
/// When true the file system must write to the current end of file. In this case the Offset
|
||||
/// parameter will contain the value -1.
|
||||
/// </param>
|
||||
/// <param name="ConstrainedIo">
|
||||
/// When true the file system must not extend the file (i.e. change the file size).
|
||||
/// </param>
|
||||
/// <param name="BytesTransferred">
|
||||
/// Receives the actual number of bytes written.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the updated file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Write(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -166,6 +439,24 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Flushes a file or volume.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that the FSD will also flush all file/volume caches prior to invoking this operation.
|
||||
/// </remarks>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to flush.
|
||||
/// When this and the FileDesc parameter are null the whole volume is being flushed.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to flush.
|
||||
/// When this and the FileNode parameter are null the whole volume is being flushed.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the updated file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Flush(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -174,6 +465,19 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets file or directory information.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to get information for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to get information for.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 GetFileInfo(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -182,6 +486,39 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets file or directory basic information.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to set information for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to set information for.
|
||||
/// </param>
|
||||
/// <param name="FileAttributes">
|
||||
/// File attributes to apply to the file or directory.
|
||||
/// If the value -1 is sent, the file attributes should not be changed.
|
||||
/// </param>
|
||||
/// <param name="CreationTime">
|
||||
/// Creation time to apply to the file or directory.
|
||||
/// If the value 0 is sent, the creation time should not be changed.
|
||||
/// </param>
|
||||
/// <param name="LastAccessTime">
|
||||
/// Last access time to apply to the file or directory.
|
||||
/// If the value 0 is sent, the last access time should not be changed.
|
||||
/// </param>
|
||||
/// <param name="LastWriteTime">
|
||||
/// Last write time to apply to the file or directory.
|
||||
/// If the value 0 is sent, the last write time should not be changed.
|
||||
/// </param>
|
||||
/// <param name="ChangeTime">
|
||||
/// Change time to apply to the file or directory.
|
||||
/// If the value 0 is sent, the change time should not be changed.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the updated file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 SetBasicInfo(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -195,6 +532,52 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets file/allocation size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This function is used to change a file's sizes. Windows file systems maintain two kinds
|
||||
/// of sizes: the file size is where the End Of File (EOF) is, and the allocation size is the
|
||||
/// actual size that a file takes up on the "disk".
|
||||
/// </para><para>
|
||||
/// The rules regarding file/allocation size are:
|
||||
/// <list>
|
||||
/// <item>
|
||||
/// Allocation size must always be aligned to the allocation unit boundary. The allocation
|
||||
/// unit is the product SectorSize * SectorsPerAllocationUnit. The FSD will always send
|
||||
/// properly aligned allocation sizes when setting the allocation size.
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// Allocation size is always greater or equal to the file size.
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// A file size of more than the current allocation size will also extend the allocation
|
||||
/// size to the next allocation unit boundary.
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// An allocation size of less than the current file size should also truncate the current
|
||||
/// file size.
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file to set the file/allocation size for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file to set the file/allocation size for.
|
||||
/// </param>
|
||||
/// <param name="NewSize">
|
||||
/// New file/allocation size to apply to the file.
|
||||
/// </param>
|
||||
/// <param name="SetAllocationSize">
|
||||
/// If true, then the allocation size is being set. if false, then the file size is being set.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the updated file information.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 SetFileSize(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -205,6 +588,20 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Determines whether a file or directory can be deleted.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to test for deletion.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to test for deletion.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to test for deletion.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
/// <seealso cref="Cleanup"/>
|
||||
public virtual Int32 CanDelete(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -212,6 +609,37 @@ namespace Fsp
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Renames a file or directory.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The kernel mode FSD provides certain guarantees prior to posting a rename operation:
|
||||
/// <list>
|
||||
/// <item>
|
||||
/// A file cannot be renamed if a file with the same name exists and has open handles.
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// A directory cannot be renamed if it or any of its subdirectories contains a file that
|
||||
/// has open handles.
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to be renamed.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to be renamed.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The current name of the file or directory to rename.
|
||||
/// </param>
|
||||
/// <param name="NewFileName">
|
||||
/// The new name for the file or directory.
|
||||
/// </param>
|
||||
/// <param name="ReplaceIfExists">
|
||||
/// Whether to replace a file that already exists at NewFileName.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 Rename(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -221,6 +649,19 @@ namespace Fsp
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets file or directory security descriptor.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to get the security descriptor for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to get the security descriptor for.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// Receives the file security descriptor.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 GetSecurity(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -228,6 +669,23 @@ namespace Fsp
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets file or directory security descriptor.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to set the security descriptor for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to set the security descriptor for.
|
||||
/// </param>
|
||||
/// <param name="Sections">
|
||||
/// Describes what parts of the file or directory security descriptor should be modified.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// Describes the modifications to apply to the file or directory security descriptor.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
/// <seealso cref="ModifySecurityDescriptor"/>
|
||||
public virtual Int32 SetSecurity(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -236,6 +694,10 @@ namespace Fsp
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a directory.
|
||||
/// </summary>
|
||||
/// <seealso cref="ReadDirectoryEntry"/>
|
||||
public virtual Int32 ReadDirectory(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -248,6 +710,36 @@ namespace Fsp
|
||||
return SeekableReadDirectory(FileNode, FileDesc, Pattern, Marker, Buffer, Length,
|
||||
out BytesTransferred);
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads a directory entry.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the directory to be read.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the directory to be read.
|
||||
/// </param>
|
||||
/// <param name="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
|
||||
/// matching on the returned results.
|
||||
/// </param>
|
||||
/// <param name="Marker">
|
||||
/// A file name that marks where in the directory to start reading. Files with names
|
||||
/// that are greater than (not equal to) this marker (in the directory order determined
|
||||
/// by the file system) should be returned. Can be null.
|
||||
/// </param>
|
||||
/// <param name="Context">
|
||||
/// Can be used by the file system to track the ReadDirectory operation.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// Receives the file name for the directory entry.
|
||||
/// </param>
|
||||
/// <param name="FileInfo">
|
||||
/// Receives the file information for the directory entry.
|
||||
/// </param>
|
||||
/// <returns>True if there are additional directory entries to return. False otherwise.</returns>
|
||||
/// <seealso cref="ReadDirectory"/>
|
||||
public virtual Boolean ReadDirectoryEntry(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -261,13 +753,16 @@ namespace Fsp
|
||||
FileInfo = default(FileInfo);
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Resolves reparse points.
|
||||
/// </summary>
|
||||
public virtual Int32 ResolveReparsePoints(
|
||||
String FileName,
|
||||
UInt32 ReparsePointIndex,
|
||||
Boolean ResolveLastPathComponent,
|
||||
out IoStatusBlock IoStatus,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr Size)
|
||||
IntPtr PSize)
|
||||
{
|
||||
GCHandle Handle = GCHandle.Alloc(this, GCHandleType.Normal);
|
||||
try
|
||||
@ -281,49 +776,108 @@ namespace Fsp
|
||||
ResolveLastPathComponent,
|
||||
out IoStatus,
|
||||
Buffer,
|
||||
ref Size);
|
||||
PSize);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Handle.Free();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a reparse point given a file name.
|
||||
/// </summary>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory to get the reparse point for.
|
||||
/// </param>
|
||||
/// <param name="IsDirectory">
|
||||
/// Determines whether the passed file name is assumed to be a directory.
|
||||
/// </param>
|
||||
/// <param name="ReparseData">
|
||||
/// Receives the reparse data for the file or directory.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 GetReparsePointByName(
|
||||
String FileName,
|
||||
Boolean IsDirectory,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr Size)
|
||||
ref Byte[] ReparseData)
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a reparse point.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The file name of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="ReparseData">
|
||||
/// Receives the reparse data for the reparse point.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 GetReparsePoint(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
String FileName,
|
||||
IntPtr Buffer,
|
||||
out UIntPtr Size)
|
||||
ref Byte[] ReparseData)
|
||||
{
|
||||
Size = default(UIntPtr);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets a reparse point.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The file name of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="ReparseData">
|
||||
/// The new reparse data for the reparse point.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 SetReparsePoint(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
String FileName,
|
||||
IntPtr Buffer,
|
||||
UIntPtr Size)
|
||||
Byte[] ReparseData)
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Deletes a reparse point.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="FileName">
|
||||
/// The file name of the reparse point.
|
||||
/// </param>
|
||||
/// <param name="ReparseData">
|
||||
/// The reparse data for the reparse point.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public virtual Int32 DeleteReparsePoint(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
String FileName,
|
||||
IntPtr Buffer,
|
||||
UIntPtr Size)
|
||||
Byte[] ReparseData)
|
||||
{
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets named streams information.
|
||||
/// </summary>
|
||||
public virtual Int32 GetStreamInfo(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -331,19 +885,108 @@ namespace Fsp
|
||||
UInt32 Length,
|
||||
out UInt32 BytesTransferred)
|
||||
{
|
||||
Object Context = null;
|
||||
String StreamName;
|
||||
StreamInfo StreamInfo = default(StreamInfo);
|
||||
BytesTransferred = default(UInt32);
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
while (GetStreamEntry(FileNode, FileDesc, ref Context,
|
||||
out StreamName, out StreamInfo.StreamSize, out StreamInfo.StreamAllocationSize))
|
||||
{
|
||||
StreamInfo.SetStreamNameBuf(StreamName);
|
||||
if (!Api.FspFileSystemAddStreamInfo(ref StreamInfo, Buffer, Length,
|
||||
out BytesTransferred))
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
Api.FspFileSystemEndStreamInfo(Buffer, Length, out BytesTransferred);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets named streams information entry.
|
||||
/// </summary>
|
||||
/// <param name="FileNode">
|
||||
/// The file node of the file or directory to get stream information for.
|
||||
/// </param>
|
||||
/// <param name="FileDesc">
|
||||
/// The file descriptor of the file or directory to get stream information for.
|
||||
/// </param>
|
||||
/// <param name="Context">
|
||||
/// Can be used by the file system to track the GetStreamInfo operation.
|
||||
/// </param>
|
||||
/// <param name="StreamName">
|
||||
/// Receives the stream name for the stream entry.
|
||||
/// </param>
|
||||
/// <param name="StreamSize">
|
||||
/// Receives the stream size for the stream entry.
|
||||
/// </param>
|
||||
/// <param name="StreamAllocationSize">
|
||||
/// Receives the stream allocation size for the stream entry.
|
||||
/// </param>
|
||||
/// <returns>True if there are additional stream entries to return. False otherwise.</returns>
|
||||
public virtual Boolean GetStreamEntry(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
ref Object Context,
|
||||
out String StreamName,
|
||||
out UInt64 StreamSize,
|
||||
out UInt64 StreamAllocationSize)
|
||||
{
|
||||
StreamName = default(String);
|
||||
StreamSize = default(UInt64);
|
||||
StreamAllocationSize = default(UInt64);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* helpers */
|
||||
/// <summary>
|
||||
/// Converts a Win32 error code to a Windows kernel status code.
|
||||
/// </summary>
|
||||
public static Int32 NtStatusFromWin32(UInt32 Error)
|
||||
{
|
||||
return Api.FspNtStatusFromWin32(Error);
|
||||
}
|
||||
/// <summary>
|
||||
/// Converts a Windows kernel status code to a Win32 error code.
|
||||
/// </summary>
|
||||
public static UInt32 Win32FromNtStatus(Int32 Status)
|
||||
{
|
||||
return Api.FspWin32FromNtStatus(Status);
|
||||
}
|
||||
/// <summary>
|
||||
/// Modifies a security descriptor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a helper for implementing the SetSecurity operation.
|
||||
/// </remarks>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// The original security descriptor.
|
||||
/// </param>
|
||||
/// <param name="Sections">
|
||||
/// Describes what parts of the file or directory security descriptor should be modified.
|
||||
/// </param>
|
||||
/// <param name="ModificationDescriptor">
|
||||
/// Describes the modifications to apply to the file or directory security descriptor.
|
||||
/// </param>
|
||||
/// <returns>The modified security descriptor.</returns>
|
||||
/// <seealso cref="SetSecurity"/>
|
||||
public static byte[] ModifySecurityDescriptor(
|
||||
Byte[] SecurityDescriptor,
|
||||
AccessControlSections Sections,
|
||||
Byte[] ModificationDescriptor)
|
||||
{
|
||||
UInt32 SecurityInformation = 0;
|
||||
if (0 != (Sections & AccessControlSections.Owner))
|
||||
SecurityInformation |= 1/*OWNER_SECURITY_INFORMATION*/;
|
||||
if (0 != (Sections & AccessControlSections.Group))
|
||||
SecurityInformation |= 2/*GROUP_SECURITY_INFORMATION*/;
|
||||
if (0 != (Sections & AccessControlSections.Access))
|
||||
SecurityInformation |= 4/*DACL_SECURITY_INFORMATION*/;
|
||||
if (0 != (Sections & AccessControlSections.Audit))
|
||||
SecurityInformation |= 8/*SACL_SECURITY_INFORMATION*/;
|
||||
return Api.ModifySecurityDescriptor(
|
||||
SecurityDescriptor,
|
||||
SecurityInformation,
|
||||
ModificationDescriptor);
|
||||
}
|
||||
public Int32 SeekableReadDirectory(
|
||||
Object FileNode,
|
||||
Object FileDesc,
|
||||
@ -363,8 +1006,9 @@ namespace Fsp
|
||||
DirInfo.SetFileNameBuf(FileName);
|
||||
if (!Api.FspFileSystemAddDirInfo(ref DirInfo, Buffer, Length,
|
||||
out BytesTransferred))
|
||||
break;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
Api.FspFileSystemEndDirInfo(Buffer, Length, out BytesTransferred);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
public Int32 BufferedReadDirectory(
|
||||
@ -408,7 +1052,22 @@ namespace Fsp
|
||||
Marker, Buffer, Length, out BytesTransferred);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
public Int32 FindReparsePoint(
|
||||
/// <summary>
|
||||
/// Finds a reparse point in file name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a helper for implementing the GetSecurityByName operation in file systems
|
||||
/// that support reparse points.
|
||||
/// </remarks>
|
||||
/// <param name="FileName">
|
||||
/// The name of the file or directory.
|
||||
/// </param>
|
||||
/// <param name="ReparsePointIndex">
|
||||
/// Receives the index of the first reparse point within FileName.
|
||||
/// </param>
|
||||
/// <returns>True if a reparse point was found, false otherwise.</returns>
|
||||
/// <seealso cref="GetSecurityByName"/>
|
||||
public Boolean FindReparsePoint(
|
||||
String FileName,
|
||||
out UInt32 ReparsePointIndex)
|
||||
{
|
||||
@ -427,22 +1086,62 @@ namespace Fsp
|
||||
Handle.Free();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the reparse tag from reparse data.
|
||||
/// </summary>
|
||||
/// <param name="ReparseData">
|
||||
/// The reparse data to extract the reparse tag from.
|
||||
/// </param>
|
||||
/// <returns>The reparse tag.</returns>
|
||||
public static UInt32 GetReparseTag(
|
||||
Byte[] ReparseData)
|
||||
{
|
||||
return BitConverter.ToUInt32(ReparseData, 0);
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests whether reparse data can be replaced.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a helper for implementing the SetReparsePoint/DeleteReparsePoint operation
|
||||
/// in file systems that support reparse points.
|
||||
/// </remarks>
|
||||
/// <param name="CurrentReparseData">
|
||||
/// The current reparse data.
|
||||
/// </param>
|
||||
/// <param name="ReplaceReparseData">
|
||||
/// The replacement reparse data.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
/// <seealso cref="SetReparsePoint"/>
|
||||
/// <seealso cref="DeleteReparsePoint"/>
|
||||
public static Int32 CanReplaceReparsePoint(
|
||||
Byte[] CurrentReparseData,
|
||||
Byte[] ReplaceReparseData)
|
||||
{
|
||||
return Api.FspFileSystemCanReplaceReparsePoint(CurrentReparseData, ReplaceReparseData);
|
||||
}
|
||||
private static Int32 GetReparsePointByName(
|
||||
IntPtr FileSystem,
|
||||
IntPtr Context,
|
||||
String FileName,
|
||||
Boolean IsDirectory,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr Size)
|
||||
IntPtr PSize)
|
||||
{
|
||||
FileSystemBase self = (FileSystemBase)GCHandle.FromIntPtr(Context).Target;
|
||||
try
|
||||
{
|
||||
return self.GetReparsePointByName(
|
||||
Byte[] ReparseData;
|
||||
Int32 Result;
|
||||
ReparseData = null;
|
||||
Result = self.GetReparsePointByName(
|
||||
FileName,
|
||||
IsDirectory,
|
||||
Buffer,
|
||||
ref Size);
|
||||
ref ReparseData);
|
||||
if (0 <= Result)
|
||||
Result = Api.CopyReparsePoint(ReparseData, Buffer, PSize);
|
||||
return Result;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dotnet/FileSystemHost.cs
|
||||
/*
|
||||
* dotnet/FileSystemHost.cs
|
||||
*
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
* Copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -24,9 +24,16 @@ using Fsp.Interop;
|
||||
namespace Fsp
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provides a means to host (mount) a file system.
|
||||
/// </summary>
|
||||
public class FileSystemHost : IDisposable
|
||||
{
|
||||
/* ctor/dtor */
|
||||
/// <summary>
|
||||
/// Creates an instance of the FileSystemHost class.
|
||||
/// </summary>
|
||||
/// <param name="FileSystem">The file system to host.</param>
|
||||
public FileSystemHost(FileSystemBase FileSystem)
|
||||
{
|
||||
_VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext;
|
||||
@ -36,6 +43,9 @@ namespace Fsp
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Unmounts the file system and releases all associated resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
lock (this)
|
||||
@ -56,73 +66,114 @@ namespace Fsp
|
||||
{
|
||||
ExceptionHandler(_FileSystem, ex);
|
||||
}
|
||||
Api.SetUserContext(_FileSystemPtr, null);
|
||||
Api.DisposeUserContext(_FileSystemPtr);
|
||||
Api.FspFileSystemDelete(_FileSystemPtr);
|
||||
_FileSystemPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/* properties */
|
||||
/// <summary>
|
||||
/// Gets or sets the sector size used by the file system.
|
||||
/// </summary>
|
||||
public UInt16 SectorSize
|
||||
{
|
||||
get { return _VolumeParams.SectorSize; }
|
||||
set { _VolumeParams.SectorSize = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the sectors per allocation unit used by the file system.
|
||||
/// </summary>
|
||||
public UInt16 SectorsPerAllocationUnit
|
||||
{
|
||||
get { return _VolumeParams.SectorsPerAllocationUnit; }
|
||||
set { _VolumeParams.SectorsPerAllocationUnit = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum path component length used by the file system.
|
||||
/// </summary>
|
||||
public UInt16 MaxComponentLength
|
||||
{
|
||||
get { return _VolumeParams.MaxComponentLength; }
|
||||
set { _VolumeParams.MaxComponentLength = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the volume creation time.
|
||||
/// </summary>
|
||||
public UInt64 VolumeCreationTime
|
||||
{
|
||||
get { return _VolumeParams.VolumeCreationTime; }
|
||||
set { _VolumeParams.VolumeCreationTime = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the volume serial number.
|
||||
/// </summary>
|
||||
public UInt32 VolumeSerialNumber
|
||||
{
|
||||
get { return _VolumeParams.VolumeSerialNumber; }
|
||||
set { _VolumeParams.VolumeSerialNumber = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the file information timeout.
|
||||
/// </summary>
|
||||
public UInt32 FileInfoTimeout
|
||||
{
|
||||
get { return _VolumeParams.FileInfoTimeout; }
|
||||
set { _VolumeParams.FileInfoTimeout = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the file system is case sensitive.
|
||||
/// </summary>
|
||||
public Boolean CaseSensitiveSearch
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.CaseSensitiveSearch); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.CaseSensitiveSearch : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether a case insensitive file system
|
||||
/// preserves case in file names.
|
||||
/// </summary>
|
||||
public Boolean CasePreservedNames
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.CasePreservedNames); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.CasePreservedNames : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether file names support unicode characters.
|
||||
/// </summary>
|
||||
public Boolean UnicodeOnDisk
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.UnicodeOnDisk); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.UnicodeOnDisk : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the file system supports ACL security.
|
||||
/// </summary>
|
||||
public Boolean PersistentAcls
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.PersistentAcls); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.PersistentAcls : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the file system supports reparse points.
|
||||
/// </summary>
|
||||
public Boolean ReparsePoints
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.ReparsePoints); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.ReparsePoints : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the file system allows creation of
|
||||
/// symbolic links without additional privileges.
|
||||
/// </summary>
|
||||
public Boolean ReparsePointsAccessCheck
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.ReparsePointsAccessCheck); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.ReparsePointsAccessCheck : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines whether the file system supports named streams.
|
||||
/// </summary>
|
||||
public Boolean NamedStreams
|
||||
{
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.NamedStreams); }
|
||||
@ -138,11 +189,17 @@ namespace Fsp
|
||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryPattern); }
|
||||
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryPattern : 0); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the prefix for a network file system.
|
||||
/// </summary>
|
||||
public String Prefix
|
||||
{
|
||||
get { return _VolumeParams.GetPrefix(); }
|
||||
set { _VolumeParams.SetPrefix(value); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the file system name.
|
||||
/// </summary>
|
||||
public String FileSystemName
|
||||
{
|
||||
get { return _VolumeParams.GetFileSystemName(); }
|
||||
@ -150,12 +207,42 @@ namespace Fsp
|
||||
}
|
||||
|
||||
/* control */
|
||||
/// <summary>
|
||||
/// Checks whether mounting a file system is possible.
|
||||
/// </summary>
|
||||
/// <param name="MountPoint">
|
||||
/// The mount point for the new file system. A value of null means that
|
||||
/// the file system should use the next available drive letter counting
|
||||
/// downwards from Z: as its mount point.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public Int32 Preflight(String MountPoint)
|
||||
{
|
||||
return Api.FspFileSystemPreflight(
|
||||
_VolumeParams.IsPrefixEmpty() ? "WinFsp.Disk" : "WinFsp.Net",
|
||||
MountPoint);
|
||||
}
|
||||
/// <summary>
|
||||
/// Mounts a file system.
|
||||
/// </summary>
|
||||
/// <param name="MountPoint">
|
||||
/// The mount point for the new file system. A value of null means that
|
||||
/// the file system should use the next available drive letter counting
|
||||
/// downwards from Z: as its mount point.
|
||||
/// </param>
|
||||
/// <param name="SecurityDescriptor">
|
||||
/// Security descriptor to use if mounting on (newly created) directory.
|
||||
/// A value of null means the directory should be created with default
|
||||
/// security.
|
||||
/// </param>
|
||||
/// <param name="Synchronized">
|
||||
/// If true file system operations are synchronized using an exclusive lock.
|
||||
/// </param>
|
||||
/// <param name="DebugLog">
|
||||
/// A value of 0 disables all debug logging.
|
||||
/// A value of -1 enables all debug logging.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public Int32 Mount(String MountPoint,
|
||||
Byte[] SecurityDescriptor = null,
|
||||
Boolean Synchronized = false,
|
||||
@ -210,16 +297,23 @@ namespace Fsp
|
||||
}
|
||||
if (0 > Result)
|
||||
{
|
||||
Api.SetUserContext(_FileSystemPtr, null);
|
||||
Api.DisposeUserContext(_FileSystemPtr);
|
||||
Api.FspFileSystemDelete(_FileSystemPtr);
|
||||
_FileSystemPtr = IntPtr.Zero;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
/// <summary>
|
||||
/// Unmounts the file system and releases all associated resources.
|
||||
/// </summary>
|
||||
public void Unmount()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the file system mount point.
|
||||
/// </summary>
|
||||
/// <returns>The file system mount point.</returns>
|
||||
public String MountPoint()
|
||||
{
|
||||
return IntPtr.Zero != _FileSystemPtr ?
|
||||
@ -229,17 +323,28 @@ namespace Fsp
|
||||
{
|
||||
return _FileSystemPtr;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the hosted file system.
|
||||
/// </summary>
|
||||
/// <returns>The hosted file system.</returns>
|
||||
public FileSystemBase FileSystem()
|
||||
{
|
||||
return _FileSystem;
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the debug log file to use when debug logging is enabled.
|
||||
/// </summary>
|
||||
/// <param name="FileName">
|
||||
/// The debug log file name. A value of "-" means standard error output.
|
||||
/// </param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
public static Int32 SetDebugLogFile(String FileName)
|
||||
{
|
||||
return Api.SetDebugLogFile(FileName);
|
||||
}
|
||||
|
||||
/* FSP_FILE_SYSTEM_INTERFACE */
|
||||
private static Byte[] SecurityDescriptorNotNull = new Byte[0];
|
||||
private static Byte[] ByteBufferNotNull = new Byte[0];
|
||||
private static Int32 ExceptionHandler(
|
||||
FileSystemBase FileSystem,
|
||||
Exception ex)
|
||||
@ -301,12 +406,12 @@ namespace Fsp
|
||||
Byte[] SecurityDescriptorBytes = null;
|
||||
Int32 Result;
|
||||
if (IntPtr.Zero != PSecurityDescriptorSize)
|
||||
SecurityDescriptorBytes = SecurityDescriptorNotNull;
|
||||
SecurityDescriptorBytes = ByteBufferNotNull;
|
||||
Result = FileSystem.GetSecurityByName(
|
||||
FileName,
|
||||
out FileAttributes,
|
||||
ref SecurityDescriptorBytes);
|
||||
if (0 <= Result)
|
||||
if (0 <= Result && 260/*STATUS_REPARSE*/ != Result)
|
||||
{
|
||||
if (IntPtr.Zero != PFileAttributes)
|
||||
Marshal.WriteInt32(PFileAttributes, (Int32)FileAttributes);
|
||||
@ -457,7 +562,7 @@ namespace Fsp
|
||||
FileSystem.Close(
|
||||
FileNode,
|
||||
FileDesc);
|
||||
Api.SetFullContext(ref FullContext, null, null);
|
||||
Api.DisposeFullContext(ref FullContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -680,13 +785,15 @@ namespace Fsp
|
||||
Byte[] SecurityDescriptorBytes;
|
||||
Int32 Result;
|
||||
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
|
||||
SecurityDescriptorBytes = SecurityDescriptorNotNull;
|
||||
SecurityDescriptorBytes = ByteBufferNotNull;
|
||||
Result = FileSystem.GetSecurity(
|
||||
FileNode,
|
||||
FileDesc,
|
||||
ref SecurityDescriptorBytes);
|
||||
return Api.CopySecurityDescriptor(SecurityDescriptorBytes,
|
||||
SecurityDescriptor, PSecurityDescriptorSize);
|
||||
if (0 <= Result)
|
||||
Result = Api.CopySecurityDescriptor(SecurityDescriptorBytes,
|
||||
SecurityDescriptor, PSecurityDescriptorSize);
|
||||
return Result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -761,7 +868,7 @@ namespace Fsp
|
||||
Boolean ResolveLastPathComponent,
|
||||
out IoStatusBlock PIoStatus,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr PSize)
|
||||
IntPtr PSize)
|
||||
{
|
||||
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
||||
try
|
||||
@ -772,7 +879,7 @@ namespace Fsp
|
||||
ResolveLastPathComponent,
|
||||
out PIoStatus,
|
||||
Buffer,
|
||||
ref PSize);
|
||||
PSize);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -785,23 +892,27 @@ namespace Fsp
|
||||
ref FullContext FullContext,
|
||||
String FileName,
|
||||
IntPtr Buffer,
|
||||
out UIntPtr PSize)
|
||||
IntPtr PSize)
|
||||
{
|
||||
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
||||
try
|
||||
{
|
||||
Byte[] ReparseData;
|
||||
Object FileNode, FileDesc;
|
||||
Int32 Result;
|
||||
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
|
||||
return FileSystem.GetReparsePoint(
|
||||
ReparseData = null;
|
||||
Result = FileSystem.GetReparsePoint(
|
||||
FileNode,
|
||||
FileDesc,
|
||||
FileName,
|
||||
Buffer,
|
||||
out PSize);
|
||||
ref ReparseData);
|
||||
if (0 <= Result)
|
||||
Result = Api.CopyReparsePoint(ReparseData, Buffer, PSize);
|
||||
return Result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PSize = default(UIntPtr);
|
||||
return ExceptionHandler(FileSystem, ex);
|
||||
}
|
||||
}
|
||||
@ -821,8 +932,7 @@ namespace Fsp
|
||||
FileNode,
|
||||
FileDesc,
|
||||
FileName,
|
||||
Buffer,
|
||||
Size);
|
||||
Api.MakeReparsePoint(Buffer, Size));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -845,8 +955,7 @@ namespace Fsp
|
||||
FileNode,
|
||||
FileDesc,
|
||||
FileName,
|
||||
Buffer,
|
||||
Size);
|
||||
Api.MakeReparsePoint(Buffer, Size));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -913,8 +1022,8 @@ namespace Fsp
|
||||
private static FileSystemInterface _FileSystemInterface;
|
||||
private static IntPtr _FileSystemInterfacePtr;
|
||||
private VolumeParams _VolumeParams;
|
||||
private IntPtr _FileSystemPtr;
|
||||
private FileSystemBase _FileSystem;
|
||||
private IntPtr _FileSystemPtr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dotnet/Interop.cs
|
||||
/*
|
||||
* dotnet/Interop.cs
|
||||
*
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
* Copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -102,16 +102,28 @@ namespace Fsp.Interop
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains volume information about a file system.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct VolumeInfo
|
||||
{
|
||||
internal const int VolumeLabelSize = 32;
|
||||
|
||||
/// <summary>
|
||||
/// Total size of volume in bytes.
|
||||
/// </summary>
|
||||
public UInt64 TotalSize;
|
||||
/// <summary>
|
||||
/// Free size of volume in bytes.
|
||||
/// </summary>
|
||||
public UInt64 FreeSize;
|
||||
internal UInt16 VolumeLabelLength;
|
||||
internal unsafe fixed UInt16 VolumeLabel[VolumeLabelSize];
|
||||
|
||||
/// <summary>
|
||||
/// Sets the volume label.
|
||||
/// </summary>
|
||||
public unsafe void SetVolumeLabel(String Value)
|
||||
{
|
||||
fixed (UInt16 *P = VolumeLabel)
|
||||
@ -121,23 +133,59 @@ namespace Fsp.Interop
|
||||
Size = VolumeLabelSize;
|
||||
for (int I = 0; Size > I; I++)
|
||||
P[I] = Value[I];
|
||||
VolumeLabelLength = (UInt16)Size;
|
||||
VolumeLabelLength = (UInt16)(Size * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains metadata information about a file or directory.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FileInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The file or directory attributes.
|
||||
/// </summary>
|
||||
public UInt32 FileAttributes;
|
||||
/// <summary>
|
||||
/// The reparse tag of the file or directory.
|
||||
/// This value is 0 if the file or directory is not a reparse point.
|
||||
/// </summary>
|
||||
public UInt32 ReparseTag;
|
||||
/// <summary>
|
||||
/// The allocation size of the file.
|
||||
/// </summary>
|
||||
public UInt64 AllocationSize;
|
||||
/// <summary>
|
||||
/// The file size of the file (end of file).
|
||||
/// </summary>
|
||||
public UInt64 FileSize;
|
||||
/// <summary>
|
||||
/// The time that the file or directory was created.
|
||||
/// </summary>
|
||||
public UInt64 CreationTime;
|
||||
/// <summary>
|
||||
/// The time that the file or directory was last accessed.
|
||||
/// </summary>
|
||||
public UInt64 LastAccessTime;
|
||||
/// <summary>
|
||||
/// The time that the file or direcotry was last modified.
|
||||
/// </summary>
|
||||
public UInt64 LastWriteTime;
|
||||
/// <summary>
|
||||
/// The time that the file or directory metadata was last modified.
|
||||
/// </summary>
|
||||
public UInt64 ChangeTime;
|
||||
/// <summary>
|
||||
/// A unique identifier that is associated with the file or directory.
|
||||
/// Not all file systems support this value.
|
||||
/// </summary>
|
||||
public UInt64 IndexNumber;
|
||||
/// <summary>
|
||||
/// The number of hard links.
|
||||
/// Not currently implemented. Set to 0.
|
||||
/// </summary>
|
||||
public UInt32 HardLinks;
|
||||
}
|
||||
|
||||
@ -156,7 +204,7 @@ namespace Fsp.Interop
|
||||
Size = NormalizedNameSize;
|
||||
for (int I = 0; Size > I; I++)
|
||||
P[I] = Value[I];
|
||||
NormalizedNameSize = (UInt16)Size;
|
||||
NormalizedNameSize = (UInt16)(Size * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,7 +212,8 @@ namespace Fsp.Interop
|
||||
internal struct DirInfo
|
||||
{
|
||||
internal const int FileNameBufSize = 255;
|
||||
internal static int FileNameBufOffset = (int)Marshal.OffsetOf(typeof(DirInfo), "FileNameBuf");
|
||||
internal static int FileNameBufOffset =
|
||||
(int)Marshal.OffsetOf(typeof(DirInfo), "FileNameBuf");
|
||||
|
||||
internal UInt16 Size;
|
||||
internal FileInfo FileInfo;
|
||||
@ -172,7 +221,7 @@ namespace Fsp.Interop
|
||||
//internal unsafe fixed UInt16 FileNameBuf[];
|
||||
internal unsafe fixed UInt16 FileNameBuf[FileNameBufSize];
|
||||
|
||||
public unsafe void SetFileNameBuf(String Value)
|
||||
internal unsafe void SetFileNameBuf(String Value)
|
||||
{
|
||||
fixed (UInt16 *P = FileNameBuf)
|
||||
{
|
||||
@ -189,10 +238,28 @@ namespace Fsp.Interop
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct StreamInfo
|
||||
{
|
||||
internal const int StreamNameBufSize = 255;
|
||||
internal static int StreamNameBufOffset =
|
||||
(int)Marshal.OffsetOf(typeof(StreamInfo), "StreamNameBuf");
|
||||
|
||||
internal UInt16 Size;
|
||||
internal UInt64 StreamSize;
|
||||
internal UInt64 StreamAllocationSize;
|
||||
//internal unsafe fixed UInt16 StreamNameBuf[];
|
||||
internal unsafe fixed UInt16 StreamNameBuf[StreamNameBufSize];
|
||||
|
||||
internal unsafe void SetStreamNameBuf(String Value)
|
||||
{
|
||||
fixed (UInt16 *P = StreamNameBuf)
|
||||
{
|
||||
int Size = null != Value ? Value.Length : 0;
|
||||
if (Size > StreamNameBufSize)
|
||||
Size = StreamNameBufSize;
|
||||
for (int I = 0; Size > I; I++)
|
||||
P[I] = Value[I];
|
||||
this.Size = (UInt16)(StreamNameBufOffset + Size * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@ -354,14 +421,14 @@ namespace Fsp.Interop
|
||||
[MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent,
|
||||
out IoStatusBlock PIoStatus,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr PSize);
|
||||
IntPtr PSize);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 GetReparsePoint(
|
||||
IntPtr FileSystem,
|
||||
ref FullContext FullContext,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
||||
IntPtr Buffer,
|
||||
out UIntPtr PSize);
|
||||
IntPtr PSize);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 SetReparsePoint(
|
||||
IntPtr FileSystem,
|
||||
@ -471,7 +538,8 @@ namespace Fsp.Interop
|
||||
UInt32 Length,
|
||||
out UInt32 PBytesTransferred);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 FspFileSystemFindReparsePoint(
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal delegate Boolean FspFileSystemFindReparsePoint(
|
||||
IntPtr FileSystem,
|
||||
GetReparsePointByName GetReparsePointByName,
|
||||
IntPtr Context,
|
||||
@ -487,7 +555,7 @@ namespace Fsp.Interop
|
||||
[MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent,
|
||||
out IoStatusBlock PIoStatus,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr PSize);
|
||||
IntPtr PSize);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 FspFileSystemCanReplaceReparsePoint(
|
||||
IntPtr CurrentReparseData,
|
||||
@ -526,6 +594,16 @@ namespace Fsp.Interop
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void FspFileSystemDeleteDirectoryBuffer(
|
||||
ref IntPtr PDirBuffer);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 FspSetSecurityDescriptor(
|
||||
IntPtr InputDescriptor,
|
||||
UInt32 SecurityInformation,
|
||||
IntPtr ModificationDescriptor,
|
||||
out IntPtr PSecurityDescriptor);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void FspDeleteSecurityDescriptor(
|
||||
IntPtr SecurityDescriptor,
|
||||
IntPtr CreateFunc);
|
||||
|
||||
/* Service */
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
@ -575,6 +653,10 @@ namespace Fsp.Interop
|
||||
internal delegate UInt32 FspWin32FromNtStatus(
|
||||
Int32 Status);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void FspDebugLog(
|
||||
[MarshalAs(UnmanagedType.LPStr)] String Format,
|
||||
[MarshalAs(UnmanagedType.LPStr)] String Message);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void FspDebugLogSetHandle(
|
||||
IntPtr Handle);
|
||||
|
||||
@ -586,7 +668,7 @@ namespace Fsp.Interop
|
||||
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
||||
[MarshalAs(UnmanagedType.U1)] Boolean IsDirectory,
|
||||
IntPtr Buffer,
|
||||
ref UIntPtr PSize);
|
||||
IntPtr PSize);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate Int32 ServiceStart(
|
||||
IntPtr Service,
|
||||
@ -619,13 +701,16 @@ namespace Fsp.Interop
|
||||
internal static Proto.FspFileSystemAddDirInfo _FspFileSystemAddDirInfo;
|
||||
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
||||
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
||||
internal static Proto.FspFileSystemCanReplaceReparsePoint FspFileSystemCanReplaceReparsePoint;
|
||||
internal static Proto.FspFileSystemAddStreamInfo FspFileSystemAddStreamInfo;
|
||||
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
|
||||
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
||||
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
||||
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
||||
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
||||
internal static Proto.FspFileSystemReadDirectoryBuffer FspFileSystemReadDirectoryBuffer;
|
||||
internal static Proto.FspFileSystemDeleteDirectoryBuffer FspFileSystemDeleteDirectoryBuffer;
|
||||
internal static Proto.FspSetSecurityDescriptor FspSetSecurityDescriptor;
|
||||
internal static IntPtr _FspSetSecurityDescriptorPtr;
|
||||
internal static Proto.FspDeleteSecurityDescriptor FspDeleteSecurityDescriptor;
|
||||
internal static Proto.FspServiceCreate FspServiceCreate;
|
||||
internal static Proto.FspServiceDelete FspServiceDelete;
|
||||
internal static Proto.FspServiceAllowConsoleMode FspServiceAllowConsoleMode;
|
||||
@ -638,6 +723,7 @@ namespace Fsp.Interop
|
||||
internal static Proto.FspVersion FspVersion;
|
||||
internal static Proto.FspNtStatusFromWin32 FspNtStatusFromWin32;
|
||||
internal static Proto.FspWin32FromNtStatus FspWin32FromNtStatus;
|
||||
internal static Proto.FspDebugLog FspDebugLog;
|
||||
internal static Proto.FspDebugLogSetHandle FspDebugLogSetHandle;
|
||||
|
||||
internal static unsafe Int32 FspFileSystemSetMountPointEx(
|
||||
@ -662,6 +748,29 @@ namespace Fsp.Interop
|
||||
fixed (DirInfo *P = &DirInfo)
|
||||
return _FspFileSystemAddDirInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
||||
}
|
||||
internal static unsafe Boolean FspFileSystemEndDirInfo(
|
||||
IntPtr Buffer,
|
||||
UInt32 Length,
|
||||
out UInt32 PBytesTransferred)
|
||||
{
|
||||
return _FspFileSystemAddDirInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
||||
}
|
||||
internal static unsafe Boolean FspFileSystemAddStreamInfo(
|
||||
ref StreamInfo StreamInfo,
|
||||
IntPtr Buffer,
|
||||
UInt32 Length,
|
||||
out UInt32 PBytesTransferred)
|
||||
{
|
||||
fixed (StreamInfo *P = &StreamInfo)
|
||||
return _FspFileSystemAddStreamInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
||||
}
|
||||
internal static unsafe Boolean FspFileSystemEndStreamInfo(
|
||||
IntPtr Buffer,
|
||||
UInt32 Length,
|
||||
out UInt32 PBytesTransferred)
|
||||
{
|
||||
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
||||
}
|
||||
|
||||
internal unsafe static Object GetUserContext(
|
||||
IntPtr NativePtr)
|
||||
@ -673,61 +782,61 @@ namespace Fsp.Interop
|
||||
IntPtr NativePtr,
|
||||
Object Obj)
|
||||
{
|
||||
if (null != Obj)
|
||||
Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)));
|
||||
GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak);
|
||||
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle;
|
||||
}
|
||||
internal unsafe static void DisposeUserContext(
|
||||
IntPtr NativePtr)
|
||||
{
|
||||
IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr));
|
||||
Debug.Assert(IntPtr.Zero != UserContext);
|
||||
if (IntPtr.Zero != UserContext)
|
||||
{
|
||||
Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)));
|
||||
GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak);
|
||||
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr));
|
||||
if (IntPtr.Zero != UserContext)
|
||||
{
|
||||
GCHandle.FromIntPtr(UserContext).Free();
|
||||
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero;
|
||||
}
|
||||
GCHandle.FromIntPtr(UserContext).Free();
|
||||
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private class FullContextHolder
|
||||
{
|
||||
public Object FileNode;
|
||||
public Object FileDesc;
|
||||
}
|
||||
internal static void GetFullContext(ref FullContext FullContext,
|
||||
out Object FileNode, out Object FileDesc)
|
||||
{
|
||||
FileNode = 0 != FullContext.UserContext ?
|
||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Target : null;
|
||||
FileDesc = 0 != FullContext.UserContext2 ?
|
||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target : null;
|
||||
FullContextHolder Holder = 0 != FullContext.UserContext2 ?
|
||||
(FullContextHolder)GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target :
|
||||
null;
|
||||
if (null != Holder)
|
||||
{
|
||||
FileNode = Holder.FileNode;
|
||||
FileDesc = Holder.FileDesc;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileNode = null;
|
||||
FileDesc = null;
|
||||
}
|
||||
}
|
||||
internal static void SetFullContext(ref FullContext FullContext,
|
||||
Object FileNode, Object FileDesc)
|
||||
{
|
||||
if (null != FileNode)
|
||||
Debug.Assert(0 == FullContext.UserContext && 0 == FullContext.UserContext2);
|
||||
FullContextHolder Holder = new FullContextHolder();
|
||||
Holder.FileNode = FileNode;
|
||||
Holder.FileDesc = FileDesc;
|
||||
GCHandle Handle = GCHandle.Alloc(Holder, GCHandleType.Normal);
|
||||
FullContext.UserContext2 = (UInt64)(IntPtr)Handle;
|
||||
}
|
||||
internal static void DisposeFullContext(ref FullContext FullContext)
|
||||
{
|
||||
Debug.Assert(0 == FullContext.UserContext && 0 != FullContext.UserContext2);
|
||||
if (0 != FullContext.UserContext2)
|
||||
{
|
||||
Debug.Assert(0 == FullContext.UserContext);
|
||||
GCHandle Handle = GCHandle.Alloc(FileNode, GCHandleType.Normal);
|
||||
FullContext.UserContext = (UInt64)(IntPtr)Handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != FullContext.UserContext)
|
||||
{
|
||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Free();
|
||||
FullContext.UserContext = 0;
|
||||
}
|
||||
}
|
||||
if (null != FileDesc)
|
||||
{
|
||||
Debug.Assert(0 == FullContext.UserContext2);
|
||||
GCHandle Handle = GCHandle.Alloc(FileDesc, GCHandleType.Normal);
|
||||
FullContext.UserContext2 = (UInt64)(IntPtr)Handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != FullContext.UserContext2)
|
||||
{
|
||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free();
|
||||
FullContext.UserContext2 = 0;
|
||||
}
|
||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free();
|
||||
FullContext.UserContext2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,6 +877,67 @@ namespace Fsp.Interop
|
||||
else
|
||||
return null;
|
||||
}
|
||||
internal unsafe static byte[] ModifySecurityDescriptor(
|
||||
Byte[] SecurityDescriptorBytes,
|
||||
UInt32 SecurityInformation,
|
||||
Byte[] ModificationDescriptorBytes)
|
||||
{
|
||||
fixed (Byte *S = SecurityDescriptorBytes)
|
||||
fixed (Byte *M = ModificationDescriptorBytes)
|
||||
{
|
||||
IntPtr SecurityDescriptor;
|
||||
Int32 Result = FspSetSecurityDescriptor(
|
||||
(IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
|
||||
if (0 > Result)
|
||||
return null;
|
||||
SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
|
||||
FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
|
||||
return SecurityDescriptorBytes;
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe static Int32 CopyReparsePoint(
|
||||
Byte[] ReparseData,
|
||||
IntPtr Buffer,
|
||||
IntPtr PSize)
|
||||
{
|
||||
if (IntPtr.Zero != Buffer)
|
||||
{
|
||||
if (null != ReparseData)
|
||||
{
|
||||
if (ReparseData.Length > (int)*(UIntPtr *)PSize)
|
||||
return unchecked((Int32)0xc0000023)/*STATUS_BUFFER_TOO_SMALL*/;
|
||||
*(UIntPtr *)PSize = (UIntPtr)ReparseData.Length;
|
||||
Marshal.Copy(ReparseData, 0, Buffer, ReparseData.Length);
|
||||
}
|
||||
else
|
||||
*(UIntPtr *)PSize = UIntPtr.Zero;
|
||||
}
|
||||
return 0/*STATUS_SUCCESS*/;
|
||||
}
|
||||
internal static Byte[] MakeReparsePoint(
|
||||
IntPtr Buffer,
|
||||
UIntPtr Size)
|
||||
{
|
||||
if (IntPtr.Zero != Buffer)
|
||||
{
|
||||
Byte[] ReparseData = new Byte[(int)Size];
|
||||
Marshal.Copy(Buffer, ReparseData, 0, ReparseData.Length);
|
||||
return ReparseData;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
internal unsafe static Int32 FspFileSystemCanReplaceReparsePoint(
|
||||
Byte[] CurrentReparseData,
|
||||
Byte[] ReplaceReparseData)
|
||||
{
|
||||
fixed (Byte *C = CurrentReparseData)
|
||||
fixed (Byte *R = ReplaceReparseData)
|
||||
return _FspFileSystemCanReplaceReparsePoint(
|
||||
(IntPtr)C, (UIntPtr)CurrentReparseData.Length,
|
||||
(IntPtr)R, (UIntPtr)ReplaceReparseData.Length);
|
||||
}
|
||||
|
||||
internal static Int32 SetDebugLogFile(String FileName)
|
||||
{
|
||||
@ -812,17 +982,17 @@ namespace Fsp.Interop
|
||||
}
|
||||
return Module;
|
||||
}
|
||||
private static IntPtr GetEntryPointPtr(IntPtr Module, String Name)
|
||||
{
|
||||
IntPtr Proc = GetProcAddress(Module, Name);
|
||||
if (IntPtr.Zero == Proc)
|
||||
throw new EntryPointNotFoundException("cannot get entry point " + Name);
|
||||
return Proc;
|
||||
}
|
||||
private static T GetEntryPoint<T>(IntPtr Module)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T)(object)Marshal.GetDelegateForFunctionPointer(
|
||||
GetProcAddress(Module, typeof(T).Name), typeof(T));
|
||||
}
|
||||
catch (ArgumentNullException)
|
||||
{
|
||||
throw new EntryPointNotFoundException("cannot get entry point " + typeof(T).Name);
|
||||
}
|
||||
return (T)(object)Marshal.GetDelegateForFunctionPointer(
|
||||
GetEntryPointPtr(Module, typeof(T).Name), typeof(T));
|
||||
}
|
||||
private static void LoadProto(IntPtr Module)
|
||||
{
|
||||
@ -840,13 +1010,16 @@ namespace Fsp.Interop
|
||||
_FspFileSystemAddDirInfo = GetEntryPoint<Proto.FspFileSystemAddDirInfo>(Module);
|
||||
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
||||
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
||||
FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
|
||||
FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
||||
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
|
||||
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
||||
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
||||
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
||||
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
||||
FspFileSystemReadDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReadDirectoryBuffer>(Module);
|
||||
FspFileSystemDeleteDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemDeleteDirectoryBuffer>(Module);
|
||||
FspSetSecurityDescriptor = GetEntryPoint<Proto.FspSetSecurityDescriptor>(Module);
|
||||
_FspSetSecurityDescriptorPtr = GetEntryPointPtr(Module, "FspSetSecurityDescriptor");
|
||||
FspDeleteSecurityDescriptor = GetEntryPoint<Proto.FspDeleteSecurityDescriptor>(Module);
|
||||
FspServiceCreate = GetEntryPoint<Proto.FspServiceCreate>(Module);
|
||||
FspServiceDelete = GetEntryPoint<Proto.FspServiceDelete>(Module);
|
||||
FspServiceAllowConsoleMode = GetEntryPoint<Proto.FspServiceAllowConsoleMode>(Module);
|
||||
@ -859,6 +1032,7 @@ namespace Fsp.Interop
|
||||
FspVersion = GetEntryPoint<Proto.FspVersion>(Module);
|
||||
FspNtStatusFromWin32 = GetEntryPoint<Proto.FspNtStatusFromWin32>(Module);
|
||||
FspWin32FromNtStatus = GetEntryPoint<Proto.FspWin32FromNtStatus>(Module);
|
||||
FspDebugLog = GetEntryPoint<Proto.FspDebugLog>(Module);
|
||||
FspDebugLogSetHandle = GetEntryPoint<Proto.FspDebugLogSetHandle>(Module);
|
||||
}
|
||||
private static void CheckVersion()
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file dotnet/Service.cs
|
||||
/*
|
||||
* dotnet/Service.cs
|
||||
*
|
||||
* @copyright 2015-2017 Bill Zissimopoulos
|
||||
* Copyright 2015-2017 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
@ -16,13 +16,16 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Fsp.Interop;
|
||||
|
||||
namespace Fsp
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provides the base class for a process that can be run as a service,
|
||||
/// command line application or under the control of the WinFsp launcher.
|
||||
/// </summary>
|
||||
public class Service
|
||||
{
|
||||
/* const */
|
||||
@ -31,25 +34,33 @@ namespace Fsp
|
||||
public const UInt32 EVENTLOG_INFORMATION_TYPE = 0x0004;
|
||||
|
||||
/* ctor/dtor */
|
||||
/// <summary>
|
||||
/// Creates an instance of the Service class.
|
||||
/// </summary>
|
||||
/// <param name="ServiceName">The name of the service.</param>
|
||||
public Service(String ServiceName)
|
||||
{
|
||||
Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _Service);
|
||||
if (IntPtr.Zero != _Service)
|
||||
Api.SetUserContext(_Service, this);
|
||||
Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _ServicePtr);
|
||||
if (IntPtr.Zero != _ServicePtr)
|
||||
Api.SetUserContext(_ServicePtr, this);
|
||||
}
|
||||
~Service()
|
||||
{
|
||||
if (IntPtr.Zero != _Service)
|
||||
if (IntPtr.Zero != _ServicePtr)
|
||||
{
|
||||
Api.SetUserContext(_Service, null);
|
||||
Api.FspServiceDelete(_Service);
|
||||
Api.DisposeUserContext(_ServicePtr);
|
||||
Api.FspServiceDelete(_ServicePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/* control */
|
||||
/// <summary>
|
||||
/// Runs a service.
|
||||
/// </summary>
|
||||
/// <returns>Service process exit code.</returns>
|
||||
public int Run()
|
||||
{
|
||||
if (IntPtr.Zero == _Service)
|
||||
if (IntPtr.Zero == _ServicePtr)
|
||||
{
|
||||
const Int32 STATUS_INSUFFICIENT_RESOURCES = unchecked((Int32)0xc000009a);
|
||||
Log(EVENTLOG_ERROR_TYPE,
|
||||
@ -57,9 +68,9 @@ namespace Fsp
|
||||
GetType().FullName, STATUS_INSUFFICIENT_RESOURCES));
|
||||
return (int)Api.FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
Api.FspServiceAllowConsoleMode(_Service);
|
||||
Int32 Result = Api.FspServiceLoop(_Service);
|
||||
int ExitCode = (int)Api.FspServiceGetExitCode(_Service);
|
||||
Api.FspServiceAllowConsoleMode(_ServicePtr);
|
||||
Int32 Result = Api.FspServiceLoop(_ServicePtr);
|
||||
int ExitCode = (int)Api.FspServiceGetExitCode(_ServicePtr);
|
||||
if (0 > Result)
|
||||
{
|
||||
Log(EVENTLOG_ERROR_TYPE,
|
||||
@ -69,36 +80,42 @@ namespace Fsp
|
||||
}
|
||||
return ExitCode;
|
||||
}
|
||||
/// <summary>
|
||||
/// Stops a running service.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (IntPtr.Zero == _Service)
|
||||
if (IntPtr.Zero == _ServicePtr)
|
||||
throw new InvalidOperationException();
|
||||
Api.FspServiceStop(_Service);
|
||||
Api.FspServiceStop(_ServicePtr);
|
||||
}
|
||||
public void RequestTime(UInt32 Time)
|
||||
{
|
||||
if (IntPtr.Zero == _Service)
|
||||
if (IntPtr.Zero == _ServicePtr)
|
||||
throw new InvalidOperationException();
|
||||
Api.FspServiceRequestTime(_Service, Time);
|
||||
Api.FspServiceRequestTime(_ServicePtr, Time);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the service process exit code.
|
||||
/// </summary>
|
||||
public int ExitCode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IntPtr.Zero == _Service)
|
||||
if (IntPtr.Zero == _ServicePtr)
|
||||
throw new InvalidOperationException();
|
||||
return (int)Api.FspServiceGetExitCode(_Service);
|
||||
return (int)Api.FspServiceGetExitCode(_ServicePtr);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (IntPtr.Zero == _Service)
|
||||
if (IntPtr.Zero == _ServicePtr)
|
||||
throw new InvalidOperationException();
|
||||
Api.FspServiceSetExitCode(_Service, (UInt32)value);
|
||||
Api.FspServiceSetExitCode(_ServicePtr, (UInt32)value);
|
||||
}
|
||||
}
|
||||
public IntPtr ServiceHandle
|
||||
{
|
||||
get { return _Service; }
|
||||
get { return _ServicePtr; }
|
||||
}
|
||||
public static void Log(UInt32 Type, String Message)
|
||||
{
|
||||
@ -106,13 +123,25 @@ namespace Fsp
|
||||
}
|
||||
|
||||
/* start/stop */
|
||||
/// <summary>
|
||||
/// Provides a means to customize the returned status code when an exception happens.
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||
protected virtual Int32 ExceptionHandler(Exception ex)
|
||||
{
|
||||
return unchecked((Int32)0xE0434f4D)/*STATUS_CLR_EXCEPTION*/;
|
||||
}
|
||||
/// <summary>
|
||||
/// Occurs when the service starts.
|
||||
/// </summary>
|
||||
/// <param name="Args">Command line arguments passed to the service.</param>
|
||||
protected virtual void OnStart(String[] Args)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Occurs when the service stops.
|
||||
/// </summary>
|
||||
protected virtual void OnStop()
|
||||
{
|
||||
}
|
||||
@ -152,7 +181,7 @@ namespace Fsp
|
||||
|
||||
private static Api.Proto.ServiceStart _OnStart = OnStart;
|
||||
private static Api.Proto.ServiceStop _OnStop = OnStop;
|
||||
private IntPtr _Service;
|
||||
private IntPtr _ServicePtr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,16 @@ launchctl-x64 start memfs64 testdsk "" M: >nul
|
||||
launchctl-x64 start memfs64 testnet \memfs64\test N: >nul
|
||||
launchctl-x64 start memfs32 testdsk "" O: >nul
|
||||
launchctl-x64 start memfs32 testnet \memfs32\test P: >nul
|
||||
launchctl-x64 start memfs-dotnet testdsk "" Q: >nul
|
||||
launchctl-x64 start memfs-dotnet testnet \memfs-dotnet\test R: >nul
|
||||
rem Cannot use timeout under cygwin/mintty: "Input redirection is not supported"
|
||||
waitfor 7BF47D72F6664550B03248ECFE77C7DD /t 3 2>nul
|
||||
cd M: >nul 2>nul || (echo === Unable to find drive M: >&2 & goto fail)
|
||||
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 P: >nul 2>nul || (echo === Unable to find drive P: >&2 & goto fail)
|
||||
cd Q: >nul 2>nul || (echo === Unable to find drive Q: >&2 & goto fail)
|
||||
cd R: >nul 2>nul || (echo === Unable to find drive R: >&2 & goto fail)
|
||||
|
||||
set dfl_tests=^
|
||||
winfsp-tests-x64 ^
|
||||
@ -31,6 +35,7 @@ set dfl_tests=^
|
||||
winfsp-tests-x64-mountpoint-dir ^
|
||||
winfsp-tests-x64-no-traverse ^
|
||||
winfsp-tests-x64-oplock ^
|
||||
winfsp-tests-x64-external ^
|
||||
winfsp-tests-x64-external-share ^
|
||||
fsx-memfs-x64-disk ^
|
||||
fsx-memfs-x64-net ^
|
||||
@ -46,6 +51,7 @@ set dfl_tests=^
|
||||
winfsp-tests-x86-mountpoint-dir ^
|
||||
winfsp-tests-x86-no-traverse ^
|
||||
winfsp-tests-x86-oplock ^
|
||||
winfsp-tests-x86-external ^
|
||||
winfsp-tests-x86-external-share ^
|
||||
fsx-memfs-x86-disk ^
|
||||
fsx-memfs-x86-net ^
|
||||
@ -54,10 +60,17 @@ set dfl_tests=^
|
||||
net-use-memfs-x86 ^
|
||||
winfstest-memfs-x86-disk ^
|
||||
winfstest-memfs-x86-net ^
|
||||
fscrash-x86
|
||||
fscrash-x86 ^
|
||||
winfsp-tests-dotnet-external ^
|
||||
winfsp-tests-dotnet-external-share ^
|
||||
fsx-memfs-dotnet-disk ^
|
||||
fsx-memfs-dotnet-net ^
|
||||
winfstest-memfs-dotnet-disk ^
|
||||
winfstest-memfs-dotnet-net
|
||||
set opt_tests=^
|
||||
ifstest-memfs-x64-disk ^
|
||||
ifstest-memfs-x86-disk ^
|
||||
ifstest-memfs-dotnet-disk ^
|
||||
sample-passthrough-x64 ^
|
||||
sample-passthrough-x86 ^
|
||||
sample-passthrough-cpp-x64 ^
|
||||
@ -121,6 +134,8 @@ launchctl-x64 stop memfs64 testdsk >nul
|
||||
launchctl-x64 stop memfs64 testnet >nul
|
||||
launchctl-x64 stop memfs32 testdsk >nul
|
||||
launchctl-x64 stop memfs32 testnet >nul
|
||||
launchctl-x64 stop memfs-dotnet testdsk >nul
|
||||
launchctl-x64 stop memfs-dotnet testnet >nul
|
||||
rem Cannot use timeout under cygwin/mintty: "Input redirection is not supported"
|
||||
waitfor 7BF47D72F6664550B03248ECFE77C7DD /t 3 2>nul
|
||||
|
||||
@ -195,6 +210,12 @@ winfsp-tests-x86 --oplock=filter --resilient
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-x64-external
|
||||
M:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x64.exe" --external --resilient
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-x64-external-share
|
||||
M:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x64.exe" --external --share=winfsp-tests-share=M:\ --resilient ^
|
||||
@ -242,6 +263,12 @@ net use L: /delete
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-x86-external
|
||||
O:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x86.exe" --external --resilient
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-x86-external-share
|
||||
O:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x86.exe" --external --share=winfsp-tests-share=O:\ --resilient ^
|
||||
@ -351,6 +378,47 @@ fscrash-x86 --huge-alloc-size --cached >nul 2>&1
|
||||
if !ERRORLEVEL! neq 1 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-dotnet-external
|
||||
Q:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x64.exe" --external --resilient
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfsp-tests-dotnet-external-share
|
||||
Q:
|
||||
"%ProjRoot%\build\VStudio\build\%Configuration%\winfsp-tests-x64.exe" --external --share=winfsp-tests-share=Q:\ --resilient ^
|
||||
-reparse_symlink*
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:fsx-memfs-dotnet-disk
|
||||
Q:
|
||||
"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -f foo -N 5000 test xxxxxx
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:fsx-memfs-dotnet-net
|
||||
R:
|
||||
"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -f foo -N 5000 test xxxxxx
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfstest-memfs-dotnet-disk
|
||||
Q:
|
||||
call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat"
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:winfstest-memfs-dotnet-net
|
||||
R:
|
||||
call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat"
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:ifstest-memfs-x64-disk
|
||||
call :__ifstest-memfs M: \Device\WinFsp.Disk C:
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
@ -361,6 +429,11 @@ call :__ifstest-memfs O: \Device\WinFsp.Disk C:
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:ifstest-memfs-dotnet-disk
|
||||
call :__ifstest-memfs Q: \Device\WinFsp.Disk C:
|
||||
if !ERRORLEVEL! neq 0 goto fail
|
||||
exit /b 0
|
||||
|
||||
:__ifstest-memfs
|
||||
%1
|
||||
set IfsTestDirectories=^
|
||||
|
0
tools/version-info.bat
Normal file → Executable file
0
tools/version-info.bat
Normal file → Executable file
1156
tst/memfs-dotnet/Program.cs
Normal file
1156
tst/memfs-dotnet/Program.cs
Normal file
File diff suppressed because it is too large
Load Diff
@ -316,6 +316,9 @@ static void dirbuf_fill_test(void)
|
||||
|
||||
void dirbuf_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(dirbuf_empty_test);
|
||||
TEST(dirbuf_dots_test);
|
||||
TEST(dirbuf_fill_test);
|
||||
|
@ -31,5 +31,8 @@ void eventlog_test(void)
|
||||
|
||||
void eventlog_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST_OPT(eventlog_test);
|
||||
}
|
||||
|
@ -370,5 +370,8 @@ void fuse_opt_parse_test(void)
|
||||
|
||||
void fuse_opt_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(fuse_opt_parse_test);
|
||||
}
|
||||
|
@ -102,5 +102,8 @@ void memfs_test(void)
|
||||
|
||||
void memfs_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(memfs_test);
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ void mount_preflight_test(void)
|
||||
|
||||
void mount_tests(void)
|
||||
{
|
||||
if (NtfsTests || OptOplock)
|
||||
if (OptExternal || OptOplock)
|
||||
return;
|
||||
|
||||
TEST_OPT(mount_invalid_test);
|
||||
|
@ -126,6 +126,9 @@ void path_suffix_test(void)
|
||||
|
||||
void path_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(path_prefix_test);
|
||||
TEST(path_suffix_test);
|
||||
}
|
||||
|
@ -265,6 +265,9 @@ void posix_map_path_test(void)
|
||||
|
||||
void posix_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(posix_map_sid_test);
|
||||
TEST(posix_map_sd_test);
|
||||
TEST(posix_map_path_test);
|
||||
|
@ -262,7 +262,7 @@ void timeout_transact_test(void)
|
||||
|
||||
void timeout_tests(void)
|
||||
{
|
||||
if (NtfsTests || OptOplock)
|
||||
if (OptExternal || OptOplock)
|
||||
return;
|
||||
|
||||
TEST_OPT(timeout_pending_test);
|
||||
|
@ -38,5 +38,8 @@ static void version_test(void)
|
||||
|
||||
void version_tests(void)
|
||||
{
|
||||
if (OptExternal)
|
||||
return;
|
||||
|
||||
TEST(version_test);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ int NtfsTests = 0;
|
||||
int WinFspDiskTests = 1;
|
||||
int WinFspNetTests = 1;
|
||||
|
||||
BOOLEAN OptExternal = FALSE;
|
||||
BOOLEAN OptResilient = FALSE;
|
||||
BOOLEAN OptCaseInsensitiveCmp = FALSE;
|
||||
BOOLEAN OptCaseInsensitive = FALSE;
|
||||
@ -211,6 +212,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
if (0 == strcmp("--ntfs", a) || 0 == strcmp("--external", a))
|
||||
{
|
||||
OptExternal = TRUE;
|
||||
NtfsTests = 1;
|
||||
WinFspDiskTests = 0;
|
||||
WinFspNetTests = 0;
|
||||
|
@ -149,6 +149,7 @@ extern int NtfsTests;
|
||||
extern int WinFspDiskTests;
|
||||
extern int WinFspNetTests;
|
||||
|
||||
extern BOOLEAN OptExternal;
|
||||
extern BOOLEAN OptResilient;
|
||||
extern BOOLEAN OptCaseInsensitiveCmp;
|
||||
extern BOOLEAN OptCaseInsensitive;
|
||||
|
Reference in New Issue
Block a user