Compare commits

..

63 Commits

Author SHA1 Message Date
d2f42f4918 update Changelog 2019-07-11 03:17:33 -07:00
a73f1b9559 launcher: path transform language 2019-07-09 13:26:07 -07:00
fb6893968a dll: fuse: add --UserName and --GroupName 2019-07-08 15:12:26 -07:00
c97f2cb660 dotnet: add MountEx and fine-grained timeouts 2019-07-07 12:12:04 -07:00
3a12d928e5 dll: fuse: avoid calling fgetattr on directories 2019-07-01 00:00:37 -07:00
8fa337ae54 sys: fix issues found by static analyzer 2019-06-28 16:19:58 -07:00
7f084787e3 sys: fix issues found by static analyzer 2019-06-28 15:21:36 -07:00
369c0256f3 build: version.properties: update company name 2019-06-25 17:11:01 -07:00
f25983853b tools: build.bat: update cert subject 2019-06-25 17:09:34 -07:00
757e23ded6 ku: kernel-mode testing and fixes 2019-06-24 16:14:03 -07:00
ebb9b8b799 sys: FspVolumeTransact: remove erroneous ASSERT 2019-06-23 11:07:01 -07:00
804bcc3354 sys: FspVolumeTransactFsext:
- only allow ControlCodes with 0xC00 bits set in Function
2019-06-22 15:40:48 -07:00
f5fde4c0bb sys: FspVolumeTransactFsext 2019-06-22 15:18:16 -07:00
dcf7e4c5a6 sys: fsext: FsextProvider testing 2019-06-22 14:30:23 -07:00
adc759447e sys: FspVolumeCreate: fix missing return 2019-06-21 16:37:07 -07:00
f0d7e5b322 Merge pull request #237 from dworkin/feature/async-dotnet
Async I/O for dotnet
2019-06-21 14:48:30 -07:00
bfd8dca62d Delay unmounting until all Slowio tasks are done.
Preventing a crash when unmounting a filesystem with pending Slowio.
2019-06-20 15:49:02 +02:00
79b2f38d87 update README 2019-06-18 21:52:19 -07:00
4ae03629f7 sys: FspFsextProvider: load provider driver 2019-06-18 20:28:59 -07:00
f4496786e5 src: ku: posix.c
- src/ku directory contains shared kernel/user mode code
2019-06-18 16:49:20 -07:00
b637a72ec8 sys: FspFsextProvider 2019-06-18 16:11:38 -07:00
2cd1bddafb sys: FspFsextProvider 2019-06-14 21:22:01 -07:00
6b83748d89 sys: fsext: WIP 2019-06-14 20:53:09 -07:00
ed31a187ac opt/fsext: kernel mode winfsp extension 2019-06-14 18:34:19 -07:00
781deff06f sys: default TransactTimeout changes 2019-06-11 17:53:34 -07:00
3902874ac9 dll: FspFileSystemStartDispatcher
Change default number of threads when ThreadCount==0 is passed.
New min DEFAULT number of threads is 4 and new max DEFAULT number of threads is 16.
The absolute minimum number of threads that any file system dispatcher has remains 2.
2019-06-11 11:51:20 -07:00
8ad77fe62f shared: minimal.h: fix memmove issue in VS 2019 2019-06-06 15:10:25 -07:00
f78b3464ce sys: meta: fix rare memory leak 2019-06-05 20:43:12 -07:00
02fd6906c2 Revert making SeekableReadDirectory virtual.
This would be an API-breaking change that is actually pointless.
Override ReadDirectory instead, as intended.
2019-06-05 09:24:27 +02:00
ce436fc29a Attempt to add a slowio test for memfs-dotnet. 2019-06-04 17:10:33 +02:00
879fa2464f Add asynchronous I/O testing to memfs-dotnet.
Make SeekableReadDirectory virtual, so that it can be overridden.
2019-06-04 15:58:54 +02:00
af7e5432a7 Let the Status argument be a signed integer.
The constants are defined as negative numbers, which would have required
a cast to unsigned for each call.
2019-05-15 14:09:08 +02:00
1d619e0874 Use pointers instead of references.
To avoid copying structs needlessly.
2019-05-14 11:38:55 +02:00
290896b010 Add asyncronous support for dotnet. 2019-05-13 09:47:59 +02:00
c01402443d wslinux support: ATOMIC_CREATE_ECP_CONTEXT 2019-04-27 15:30:57 -07:00
195f3bf92d build: VS2015 - VS2019 round-tripping: LatestTargetPlatformVersion 2019-04-26 09:44:30 -07:00
ae86aeb633 README: WinFsp now builds with VS2015 - VS2019 2019-04-25 17:43:14 -07:00
369da895d3 build: VS2015 - VS2019 round-tripping 2019-04-25 16:43:53 -07:00
17adae481c sys: FspFileNodeOplockCheckAsyncEx: fix stupid mistake in DEBUGTEST code 2019-04-18 23:47:27 -07:00
db34b8c913 update changelog 2019-04-18 20:45:56 -07:00
f6212be687 README: minor fix 2019-04-18 20:38:35 -07:00
7af36d8f78 Merge branch 'master' of https://github.com/billziss-gh/winfsp 2019-04-18 17:46:51 -07:00
f6e49a11c8 .gitignore: add .vs rule 2019-04-18 17:45:11 -07:00
01ca9cef35 README: add info on VS2015 + latest WDK problem 2019-04-18 17:34:02 -07:00
7cb29a4db3 sys: remove unused variables 2019-04-18 17:22:58 -07:00
5523320348 build: fix stampinf cmdline for latest WDK 2019-04-18 17:21:06 -07:00
969651f5f6 sys: improve support for FileStatLxInformation 2019-04-18 15:57:22 -07:00
a08fdccb17 sys: FspSendQueryEaIrp: fix EA related BSOD 2019-04-17 16:04:44 -07:00
859d4250c3 tst: winfsp-tests: wsl: fix WOW64 failure 2019-04-17 15:04:53 -07:00
c6b7b7586e sys: ea: buffers from user mode fs can have zero length 2019-04-17 14:40:06 -07:00
6406246ce2 tools: deploy: fix driver path 2019-04-17 14:39:16 -07:00
9d8ff57be7 Merge branch 'master' into pvt-wsl 2019-04-17 11:28:06 -07:00
2b0d204ff1 sys: FileStatInformation is missing on old WDK's 2019-04-16 21:28:09 -07:00
851d0758d9 sys: define FSP_FILE_STAT*_INFORMATION that are missing on some WDK's 2019-04-16 15:55:13 -07:00
4f444b412e dll: fuse: create_file_mask, create_dir_mask options 2019-04-16 15:16:54 -07:00
e9578b48ce update Changelog 2019-04-16 12:15:32 -07:00
3c3163c41b dll; fuse: rename dot_hidden option to dothidden 2019-04-16 12:11:43 -07:00
8beb534340 dll: fuse: dot_hidden option adds hidden file attribute on dot files 2019-04-15 16:30:00 -07:00
9dcc04f882 tools: update deploy/debug scripts 2019-04-15 15:34:35 -07:00
ce83619728 sys: FileStatLxInformation and friends 2019-04-15 15:04:31 -07:00
04b3675f12 update .gitignore files 2019-04-03 22:39:25 -07:00
6a23f28249 build: bump version number 2019-04-03 22:39:03 -07:00
351b4f5294 sys: fileinfo: fix unnecessary STATUS_BUFFER_TOO_SMALL 2019-04-03 09:52:00 -07:00
78 changed files with 3051 additions and 309 deletions

View File

@ -1,6 +1,29 @@
= Changelog = Changelog
v1.5B2 (2019.3 B2)::
Changes since v1.4:
* [GEN] WinFsp file systems can now be used by WSLinux. Use the command `sudo mount -t drvfs x: /mnt/x` to mount.
* [GEN] Extended attribute support has been added for all WinFsp API's: native, .NET, FUSE2 and FUSE3.
* [FSD] Support for kernel-mode file systems on top of WinFsp has been added. See `FspFsextProvider`. This is in preparation for WinFuse - FUSE for Windows and WSLinux.
* [FSD] FastIO support has been added. FastIO operations are enabled on cache-enabled file systems with the notable exception of `FastIoQueryOpen`, which allows opening files in kernel mode; this operation requires the file system to specify the `FSP_FSCTL_VOLUME_PARAMS::AllowOpenInKernelMode` flag.
* [DLL] The `FspFileSystemStartDispatcher` default number of threads (`ThreadCount==0`) has been changed. See commit 3902874ac93fe40685d9761f46a96358ba24f24c for more.
* [FUSE] FUSE has new `-o UserName=DOMAIN\USERNAME` and `-o GroupName=DOMAIN\GROUPNAME` options. These function like the `-o uid=UID` and `-o gid=GID` options, but accept Windows user and groups names.
* [FUSE] FUSE has new `-o dothidden` option that is used to add the Windows hidden file attribute to files that start with a dot.
* [FUSE] FUSE has new `-o create_file_umask=nnn` and `-o create_dir_umask=nnn` options that allow for more control than the `-o create_umask=nnn` option.
* [.NET] The .NET API now supports asynchronous handling of `Read`, `Write` and `ReadDirectory`. (Thanks @dworkin.)
* [.NET] The .NET API now supports fine-grained timeouts (`VolumeInfoTimeout`, `DirInfoTimeout`, etc).
* [.NET] The .NET API has new method `FileSystemHost.MountEx` that adds a `ThreadCount` parameter.
* [LAUNCH] The Launcher can now rewrite path arguments passed to file systems during launching using "Path Transformation Language". See commit a73f1b95592617ac7484e16c2e642573a4d65644 for more.
* [FIX] Fixes for very large (> 4GiB) files. (Thanks @dworkin.)
* [FIX] A fix for how FUSE handles the return value from `opendir`. (GitHub issue billziss-gh/sshfs-win#54)
* [FIX] A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* [FIX] A fix on the C++ layer. (Thanks @colatkinson.)
* Other fixes and improvements.
v1.5B1 (2019.3 B1):: v1.5B1 (2019.3 B1)::
Changes since v1.4: Changes since v1.4:
@ -11,6 +34,7 @@ Changes since v1.4:
* A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.) * A fix for an invalid UID to SID mapping on domains with a lot of users. (Thanks @sganis.)
* A fix on the C++ layer. (Thanks @colatkinson.) * A fix on the C++ layer. (Thanks @colatkinson.)
v1.4.19049 (2019.2):: v1.4.19049 (2019.2)::
Changes since v1.3: Changes since v1.3:

View File

@ -96,6 +96,7 @@ The project source code is organized as follows:
* :file_folder: [src/dll/fuse3](src/dll/fuse3): Source code to the FUSE3 compatibility layer. * :file_folder: [src/dll/fuse3](src/dll/fuse3): Source code to the FUSE3 compatibility layer.
* :file_folder: [src/dotnet](src/dotnet): Source code to the .NET layer. * :file_folder: [src/dotnet](src/dotnet): Source code to the .NET layer.
* :file_folder: [src/fsptool](src/fsptool): Source code to fsptool command line utility. * :file_folder: [src/fsptool](src/fsptool): Source code to fsptool command line utility.
* :file_folder: [src/ku](src/ku): Source code that can be used from kernel or user mode.
* :file_folder: [src/launcher](src/launcher): Source code to the launcher service and the launchctl utility. * :file_folder: [src/launcher](src/launcher): Source code to the launcher service and the launchctl utility.
* :file_folder: [src/sys](src/sys): Source code to the WinFsp FSD. * :file_folder: [src/sys](src/sys): Source code to the WinFsp FSD.
* :file_folder: [opt/cygfuse](opt/cygfuse): Source code to the FUSE for Cygwin package. * :file_folder: [opt/cygfuse](opt/cygfuse): Source code to the FUSE for Cygwin package.
@ -107,8 +108,12 @@ The project source code is organized as follows:
In order to build WinFsp you will need the following: In order to build WinFsp you will need the following:
* Visual Studio 2015 * Visual Studio 2015 - 2019
* Windows Driver Kit (WDK) 10 * Windows Driver Kit (WDK) 10
- **NOTE**: When using the latest WDK (Windows 10.0.18362.1) with Visual Studio 2015 you may get an error about a missing task `ValidateNTTargetVersion`. The fix is to edit the file `\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets` and modify the `UsingTask` line for `ValidateNTTargetVersion` as follows:
```
<UsingTask TaskName="ValidateNTTargetVersion" AssemblyFile="$(WDKContentRoot)build\bin\Microsoft.DriverKit.Build.Tasks.16.0.dll"/>
```
* [Wix toolset](http://wixtoolset.org) * [Wix toolset](http://wixtoolset.org)
To fully build WinFsp (including the installer) you must use `tools\build.bat`. By default it builds a Release build, but you can choose either the Debug or Release configuration by using the syntax: To fully build WinFsp (including the installer) you must use `tools\build.bat`. By default it builds a Release build, but you can choose either the Debug or Release configuration by using the syntax:

View File

@ -4,3 +4,6 @@ build
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.csproj.user *.csproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -14,18 +15,18 @@
<ProjectGuid>{95C223E6-B5F1-4FD0-9376-41CDBC824445}</ProjectGuid> <ProjectGuid>{95C223E6-B5F1-4FD0-9376-41CDBC824445}</ProjectGuid>
<RootNamespace>CustomActions</RootNamespace> <RootNamespace>CustomActions</RootNamespace>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -68,7 +69,6 @@
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile> <ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
@ -92,7 +92,6 @@
<AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>msi.lib;dutil.lib;wcautil.lib;Version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(WIX)sdk\VS2015\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile> <ModuleDefinitionFile>CustomActions.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}</ProjectGuid> <ProjectGuid>{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fsbench</RootNamespace> <RootNamespace>fsbench</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -122,7 +122,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -142,7 +141,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -162,7 +160,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{10757011-749D-4954-873B-AE38D8145472}</ProjectGuid> <ProjectGuid>{10757011-749D-4954-873B-AE38D8145472}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fscrash</RootNamespace> <RootNamespace>fscrash</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -122,7 +122,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -142,7 +141,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -162,7 +160,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,33 +23,33 @@
<ProjectGuid>{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}</ProjectGuid> <ProjectGuid>{AA7190E8-877F-4827-8CDD-E0D85F83C8C1}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>memfs</RootNamespace> <RootNamespace>memfs</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<ProjectName>memfs</ProjectName> <ProjectName>memfs</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -107,7 +108,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -124,7 +124,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -143,7 +142,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -164,7 +162,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\version.properties" />
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -22,32 +23,32 @@
<ProjectGuid>{262DF8CC-E7A8-4460-A22C-683CBA322C32}</ProjectGuid> <ProjectGuid>{262DF8CC-E7A8-4460-A22C-683CBA322C32}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>winfsptests</RootNamespace> <RootNamespace>winfsptests</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -106,7 +107,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -123,7 +123,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -142,7 +141,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -163,7 +161,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>ntdll.lib;netapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -194,6 +191,7 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\hooks.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\info-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\launch-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\launcher-ptrans-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\lock-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\lock-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\memfs-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\memfs-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\mount-test.c" />
@ -208,6 +206,7 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c" /> <ClCompile Include="..\..\..\tst\winfsp-tests\winfsp-tests.c" />
<ClCompile Include="..\..\..\tst\winfsp-tests\wsl-test.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\ext\tlib\testsuite.h" /> <ClInclude Include="..\..\..\ext\tlib\testsuite.h" />

View File

@ -97,6 +97,12 @@
<ClCompile Include="..\..\..\tst\winfsp-tests\ea-test.c"> <ClCompile Include="..\..\..\tst\winfsp-tests\ea-test.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\wsl-test.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\..\tst\winfsp-tests\launcher-ptrans-test.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\ext\tlib\testsuite.h"> <ClInclude Include="..\..\..\ext\tlib\testsuite.h">

View File

@ -23,32 +23,32 @@
<ProjectGuid>{1E997BEC-1642-4A5C-B252-852DA094E11E}</ProjectGuid> <ProjectGuid>{1E997BEC-1642-4A5C-B252-852DA094E11E}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>fsptool</RootNamespace> <RootNamespace>fsptool</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -108,7 +108,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -127,7 +126,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -149,7 +147,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -171,7 +168,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>

View File

@ -23,32 +23,32 @@
<ProjectGuid>{264A5D09-126F-4760-A3F1-4B3B95C925AA}</ProjectGuid> <ProjectGuid>{264A5D09-126F-4760-A3F1-4B3B95C925AA}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>launchctl</RootNamespace> <RootNamespace>launchctl</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -110,7 +110,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -131,7 +130,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -155,7 +153,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>
@ -179,7 +176,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
</Link> </Link>

View File

@ -23,32 +23,32 @@
<ProjectGuid>{6CDF9411-B852-4EAC-822D-8F930675F17B}</ProjectGuid> <ProjectGuid>{6CDF9411-B852-4EAC-822D-8F930675F17B}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>launcher</RootNamespace> <RootNamespace>launcher</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -110,7 +110,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -132,7 +131,6 @@
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -157,7 +155,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -182,7 +179,6 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies> <AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols> <StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
@ -190,6 +186,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\src\launcher\launcher.c" /> <ClCompile Include="..\..\..\src\launcher\launcher.c" />
<ClCompile Include="..\..\..\src\launcher\ptrans.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\winfsp_dll.vcxproj"> <ProjectReference Include="..\winfsp_dll.vcxproj">

View File

@ -16,6 +16,9 @@
<ClCompile Include="..\..\..\src\launcher\launcher.c"> <ClCompile Include="..\..\..\src\launcher\launcher.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\..\src\launcher\ptrans.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\shared\minimal.h"> <ClInclude Include="..\..\..\src\shared\minimal.h">

View File

@ -13,12 +13,12 @@
<MyProductName>WinFsp</MyProductName> <MyProductName>WinFsp</MyProductName>
<MyDescription>Windows File System Proxy</MyDescription> <MyDescription>Windows File System Proxy</MyDescription>
<MyCompanyName>Navimatics Corporation</MyCompanyName> <MyCompanyName>Navimatics LLC</MyCompanyName>
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright> <MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
<MyCanonicalVersion>1.5</MyCanonicalVersion> <MyCanonicalVersion>1.5</MyCanonicalVersion>
<MyProductVersion>2019.3 B1</MyProductVersion> <MyProductVersion>2019.3 B2</MyProductVersion>
<MyProductStage>Beta</MyProductStage> <MyProductStage>Beta</MyProductStage>
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion> <MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
@ -37,4 +37,17 @@
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions> <PreprocessorDefinitions>MyProductName=$(MyProductName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion)</PreprocessorDefinitions>
</ResourceCompile> </ResourceCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(DefaultPlatformToolset)'=='v140'">
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(DefaultPlatformToolset)'!='v140'">
<Link>
<GenerateDebugInformation>DebugFull</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<PropertyGroup>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
</Project> </Project>

View File

@ -35,6 +35,7 @@
<ClInclude Include="..\..\src\dll\fuse3\library.h" /> <ClInclude Include="..\..\src\dll\fuse3\library.h" />
<ClInclude Include="..\..\src\dll\fuse\library.h" /> <ClInclude Include="..\..\src\dll\fuse\library.h" />
<ClInclude Include="..\..\src\dll\library.h" /> <ClInclude Include="..\..\src\dll\library.h" />
<ClInclude Include="..\..\src\ku\library.h" />
<ClInclude Include="..\..\src\shared\minimal.h" /> <ClInclude Include="..\..\src\shared\minimal.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -51,7 +52,6 @@
<ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" /> <ClCompile Include="..\..\src\dll\fuse\fuse_opt.c" />
<ClCompile Include="..\..\src\dll\launch.c" /> <ClCompile Include="..\..\src\dll\launch.c" />
<ClCompile Include="..\..\src\dll\np.c" /> <ClCompile Include="..\..\src\dll\np.c" />
<ClCompile Include="..\..\src\dll\posix.c" />
<ClCompile Include="..\..\src\dll\security.c" /> <ClCompile Include="..\..\src\dll\security.c" />
<ClCompile Include="..\..\src\dll\debug.c" /> <ClCompile Include="..\..\src\dll\debug.c" />
<ClCompile Include="..\..\src\dll\fsctl.c" /> <ClCompile Include="..\..\src\dll\fsctl.c" />
@ -63,6 +63,7 @@
<ClCompile Include="..\..\src\dll\service.c" /> <ClCompile Include="..\..\src\dll\service.c" />
<ClCompile Include="..\..\src\dll\util.c" /> <ClCompile Include="..\..\src\dll\util.c" />
<ClCompile Include="..\..\src\dll\wksid.c" /> <ClCompile Include="..\..\src\dll\wksid.c" />
<ClCompile Include="..\..\src\ku\posix.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in"> <CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
@ -126,33 +127,33 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
<ProjectGuid>{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}</ProjectGuid> <ProjectGuid>{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>winfspdll</RootNamespace> <RootNamespace>winfspdll</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
<ProjectName>winfsp.dll</ProjectName> <ProjectName>winfsp.dll</ProjectName>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -216,7 +217,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -244,7 +244,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName> <MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
@ -273,7 +272,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>
@ -304,7 +302,6 @@ copy /b $(OutDir)fuse3-$(PlatformTarget).pc + %(FullPath) $(OutDir)fuse3-$(Platf
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile> <ProgramDatabaseFile>$(OutDir)$(TargetFileName).pdb</ProgramDatabaseFile>

View File

@ -27,6 +27,9 @@
<Filter Include="Source\fuse3"> <Filter Include="Source\fuse3">
<UniqueIdentifier>{96091a7b-3923-4a74-9491-3ee230c688f9}</UniqueIdentifier> <UniqueIdentifier>{96091a7b-3923-4a74-9491-3ee230c688f9}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source\ku">
<UniqueIdentifier>{613cce77-2428-4f9a-9187-f37e009253c1}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">
@ -77,6 +80,9 @@
<ClInclude Include="..\..\src\dll\fuse3\library.h"> <ClInclude Include="..\..\src\dll\fuse3\library.h">
<Filter>Source\fuse3</Filter> <Filter>Source\fuse3</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ku\library.h">
<Filter>Source\ku</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\dll\library.c"> <ClCompile Include="..\..\src\dll\library.c">
@ -124,9 +130,6 @@
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c"> <ClCompile Include="..\..\src\dll\fuse\fuse_main.c">
<Filter>Source\fuse</Filter> <Filter>Source\fuse</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\dll\posix.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\dll\fuse\fuse_intf.c"> <ClCompile Include="..\..\src\dll\fuse\fuse_intf.c">
<Filter>Source\fuse</Filter> <Filter>Source\fuse</Filter>
</ClCompile> </ClCompile>
@ -154,6 +157,9 @@
<ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c"> <ClCompile Include="..\..\src\dll\fuse3\fuse3_compat.c">
<Filter>Source\fuse3</Filter> <Filter>Source\fuse3</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ku\posix.c">
<Filter>Source\ku</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\src\dll\library.def"> <None Include="..\..\src\dll\library.def">

View File

@ -101,7 +101,7 @@
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -114,7 +114,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -127,7 +127,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -140,7 +140,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\src;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\src;..\..\opt\fsext\inc;..\..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions> _WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -155,6 +155,7 @@
<FilesToPackage Include="$(TargetPath)" /> <FilesToPackage Include="$(TargetPath)" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\ku\posix.c" />
<ClCompile Include="..\..\src\sys\cleanup.c" /> <ClCompile Include="..\..\src\sys\cleanup.c" />
<ClCompile Include="..\..\src\sys\close.c" /> <ClCompile Include="..\..\src\sys\close.c" />
<ClCompile Include="..\..\src\sys\create.c" /> <ClCompile Include="..\..\src\sys\create.c" />
@ -169,6 +170,7 @@
<ClCompile Include="..\..\src\sys\fileinfo.c" /> <ClCompile Include="..\..\src\sys\fileinfo.c" />
<ClCompile Include="..\..\src\sys\flush.c" /> <ClCompile Include="..\..\src\sys\flush.c" />
<ClCompile Include="..\..\src\sys\fsctl.c" /> <ClCompile Include="..\..\src\sys\fsctl.c" />
<ClCompile Include="..\..\src\sys\fsext.c" />
<ClCompile Include="..\..\src\sys\iop.c" /> <ClCompile Include="..\..\src\sys\iop.c" />
<ClCompile Include="..\..\src\sys\ioq.c" /> <ClCompile Include="..\..\src\sys\ioq.c" />
<ClCompile Include="..\..\src\sys\lockctl.c" /> <ClCompile Include="..\..\src\sys\lockctl.c" />
@ -188,6 +190,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\winfsp\fsctl.h" /> <ClInclude Include="..\..\inc\winfsp\fsctl.h" />
<ClInclude Include="..\..\opt\fsext\inc\winfsp\fsext.h" />
<ClInclude Include="..\..\src\ku\library.h" />
<ClInclude Include="..\..\src\sys\driver.h" /> <ClInclude Include="..\..\src\sys\driver.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -212,7 +216,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -225,7 +229,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -238,7 +242,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkObjects>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName) <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName)
set Provider="$(MyCompanyName)" set Provider="$(MyCompanyName)"
@ -251,7 +255,7 @@ for /f "delims=" %%l in (%(FullPath)) do (
echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf echo !line! &gt;&gt;$(OutDir)driver-$(PlatformTarget).inf
) )
stampinf -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command> stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(PlatformTarget).inf</Command>
<LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects> <LinkObjects Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkObjects>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing driver-$(PlatformTarget).inf</Message> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Writing driver-$(PlatformTarget).inf</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(OutDir)driver-$(PlatformTarget).inf</Outputs>

View File

@ -12,6 +12,9 @@
<Filter Include="Include\winfsp"> <Filter Include="Include\winfsp">
<UniqueIdentifier>{904f0df1-2fb8-4f84-aa46-fa929488c39a}</UniqueIdentifier> <UniqueIdentifier>{904f0df1-2fb8-4f84-aa46-fa929488c39a}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Source\ku">
<UniqueIdentifier>{235076b8-290c-4dec-b005-71d9b8e8cba7}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\sys\driver.c"> <ClCompile Include="..\..\src\sys\driver.c">
@ -104,6 +107,12 @@
<ClCompile Include="..\..\src\sys\mup.c"> <ClCompile Include="..\..\src\sys\mup.c">
<Filter>Source</Filter> <Filter>Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\sys\fsext.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ku\posix.c">
<Filter>Source\ku</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h"> <ClInclude Include="..\..\src\sys\driver.h">
@ -112,6 +121,12 @@
<ClInclude Include="..\..\inc\winfsp\fsctl.h"> <ClInclude Include="..\..\inc\winfsp\fsctl.h">
<Filter>Include\winfsp</Filter> <Filter>Include\winfsp</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\opt\fsext\inc\winfsp\fsext.h">
<Filter>Include\winfsp</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ku\library.h">
<Filter>Source\ku</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\src\sys\version.rc"> <ResourceCompile Include="..\..\src\sys\version.rc">

View File

@ -65,6 +65,10 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
#define FSP_FSCTL_STOP \ #define FSP_FSCTL_STOP \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS) CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'S', METHOD_BUFFERED, FILE_ANY_ACCESS)
/* fsctl internal device codes (usable only in-kernel) */
#define FSP_FSCTL_TRANSACT_INTERNAL \
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'I', METHOD_NEITHER, FILE_ANY_ACCESS)
#define FSP_FSCTL_VOLUME_PARAMS_PREFIX "\\VolumeParams=" #define FSP_FSCTL_VOLUME_PARAMS_PREFIX "\\VolumeParams="
#define FSP_FSCTL_VOLUME_NAME_SIZE (64 * sizeof(WCHAR)) #define FSP_FSCTL_VOLUME_NAME_SIZE (64 * sizeof(WCHAR))
@ -83,7 +87,7 @@ FSP_FSCTL_STATIC_ASSERT(FSP_FSCTL_VOLUME_NAME_SIZEMAX <= 260 * sizeof(WCHAR),
#define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024) #define FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN (64 * 1024)
#define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX #define FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN FSP_FSCTL_TRANSACT_REQ_SIZEMAX
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((T) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(T) ((HANDLE)((UINT_PTR)((T) & 0xffffffff)))
#define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff)) #define FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff))
#define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */ #define FSP_FSCTL_DEVICECONTROL_SIZEMAX (4 * 1024) /* must be < FSP_FSCTL_TRANSACT_{REQ,RSP}_SIZEMAX */
@ -121,7 +125,7 @@ enum
{ {
FspFsctlTransactTimeoutMinimum = 1000, FspFsctlTransactTimeoutMinimum = 1000,
FspFsctlTransactTimeoutMaximum = 10000, FspFsctlTransactTimeoutMaximum = 10000,
FspFsctlTransactTimeoutDefault = 1000, FspFsctlTransactTimeoutDefault = 1000, /* DEPRECATED: default is unspecified */
FspFsctlIrpTimeoutMinimum = 60000, FspFsctlIrpTimeoutMinimum = 60000,
FspFsctlIrpTimeoutMaximum = 600000, FspFsctlIrpTimeoutMaximum = 600000,
FspFsctlIrpTimeoutDefault = 300000, FspFsctlIrpTimeoutDefault = 300000,
@ -139,7 +143,7 @@ enum
UINT64 VolumeCreationTime;\ UINT64 VolumeCreationTime;\
UINT32 VolumeSerialNumber;\ UINT32 VolumeSerialNumber;\
/* I/O timeouts, capacity, etc. */\ /* I/O timeouts, capacity, etc. */\
UINT32 TransactTimeout; /* FSP_FSCTL_TRANSACT timeout (millis; 1 sec - 10 sec) */\ UINT32 TransactTimeout; /* DEPRECATED: (millis; 1 sec - 10 sec) */\
UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\ UINT32 IrpTimeout; /* pending IRP timeout (millis; 1 min - 10 min) */\
UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\ UINT32 IrpCapacity; /* maximum number of pending IRP's (100 - 1000)*/\
UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\ UINT32 FileInfoTimeout; /* FileInfo/Security/VolumeInfo timeout (millis) */\
@ -168,7 +172,8 @@ enum
/* additional kernel-mode flags */\ /* additional kernel-mode flags */\
UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\ UINT32 AllowOpenInKernelMode:1; /* allow kernel mode to open files when possible */\
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\ UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
UINT32 KmReservedFlags:6;\ UINT32 WslFeatures:1; /* support features required for WSLinux */\
UINT32 KmReservedFlags:5;\
WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\ WCHAR Prefix[FSP_FSCTL_VOLUME_PREFIX_SIZE / sizeof(WCHAR)]; /* UNC prefix (\Server\Share) */\
WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)]; WCHAR FileSystemName[FSP_FSCTL_VOLUME_FSNAME_SIZE / sizeof(WCHAR)];
#define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\ #define FSP_FSCTL_VOLUME_PARAMS_V1_FIELD_DEFN\
@ -184,7 +189,8 @@ enum
UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\ UINT32 SecurityTimeout; /* security info timeout (millis); overrides FileInfoTimeout */\
UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\ UINT32 StreamInfoTimeout; /* stream info timeout (millis); overrides FileInfoTimeout */\
UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\ UINT32 EaTimeout; /* EA timeout (millis); overrides FileInfoTimeout */\
UINT32 Reserved32[2];\ UINT32 FsextControlCode;\
UINT32 Reserved32[1];\
UINT64 Reserved64[2]; UINT64 Reserved64[2];
typedef struct typedef struct
{ {
@ -277,7 +283,7 @@ typedef struct
UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 DesiredAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */ UINT32 GrantedAccess; /* FILE_{READ_DATA,WRITE_DATA,etc.} */
UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */ UINT32 ShareAccess; /* FILE_SHARE_{READ,WRITE,DELETE} */
FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes buffer */ FSP_FSCTL_TRANSACT_BUF Ea; /* extended attributes or reparse point buffer */
UINT32 UserMode:1; /* request originated in user mode */ UINT32 UserMode:1; /* request originated in user mode */
UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */ UINT32 HasTraversePrivilege:1; /* requestor has TOKEN_HAS_TRAVERSE_PRIVILEGE */
UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */ UINT32 HasBackupPrivilege:1; /* requestor has TOKEN_HAS_BACKUP_PRIVILEGE */
@ -286,6 +292,7 @@ typedef struct
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */ UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */ UINT32 HasTrailingBackslash:1; /* FileName had trailing backslash */
UINT32 AcceptsSecurityDescriptor:1; UINT32 AcceptsSecurityDescriptor:1;
UINT32 EaIsReparsePoint:1; /* Ea buffer is reparse point */
UINT32 ReservedFlags:24; UINT32 ReservedFlags:24;
UINT16 NamedStream; /* request targets named stream; colon offset in FileName */ UINT16 NamedStream; /* request targets named stream; colon offset in FileName */
} Create; } Create;
@ -586,7 +593,7 @@ static inline FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse(
return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse : 0; return NextResponse <= ResponseBufEnd ? (FSP_FSCTL_TRANSACT_RSP *)NextResponse : 0;
} }
#if !defined(WINFSP_SYS_INTERNAL) #if !defined(_KERNEL_MODE)
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,

View File

@ -912,7 +912,8 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
/** /**
* Create new file or directory. * Create new file or directory.
* *
* This function works like Create, except that it also accepts EA (extended attributes). * This function works like Create, except that it also accepts an extra buffer that
* may contain extended attributes or a reparse point.
* *
* NOTE: If both Create and CreateEx are defined, CreateEx takes precedence. * NOTE: If both Create and CreateEx are defined, CreateEx takes precedence.
* *
@ -941,10 +942,12 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
* Windows GetSecurityDescriptorLength API. Will be NULL for named streams. * Windows GetSecurityDescriptorLength API. Will be NULL for named streams.
* @param AllocationSize * @param AllocationSize
* Allocation size for the newly created file. * Allocation size for the newly created file.
* @param Ea * @param ExtraBuffer
* Extended attributes buffer. * Extended attributes or reparse point buffer.
* @param EaLength * @param ExtraLength
* Extended attributes buffer length. * Extended attributes or reparse point buffer length.
* @param ExtraBufferIsReparsePoint
* FALSE: extra buffer is extended attributes; TRUE: extra buffer is reparse point.
* @param PFileContext [out] * @param PFileContext [out]
* Pointer that will receive the file context on successful return from this call. * Pointer that will receive the file context on successful return from this call.
* @param FileInfo [out] * @param FileInfo [out]
@ -956,7 +959,7 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem, NTSTATUS (*CreateEx)(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo); PVOID *PFileContext, FSP_FSCTL_FILE_INFO *FileInfo);
/** /**
* Overwrite a file. * Overwrite a file.

View File

@ -0,0 +1,93 @@
/**
* @file winfsp/fsext.h
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef WINFSP_FSEXT_H_INCLUDED
#define WINFSP_FSEXT_H_INCLUDED
#if !defined(_KERNEL_MODE)
#error This file can only be included when compiling for kernel mode.
#endif
#include <winfsp/fsctl.h>
#if defined(WINFSP_SYS_INTERNAL)
#define FSP_DDI __declspec(dllexport)
#else
#define FSP_DDI __declspec(dllimport)
#endif
#if !defined(FSP_DDI_DEF)
#define FSP_DDI_DEF(RetType, Name, ...) FSP_DDI RetType NTAPI Name ( __VA_ARGS__ );
#endif
typedef struct
{
UINT32 Version;
/* in */
UINT32 DeviceTransactCode;
UINT32 DeviceExtensionSize;
NTSTATUS (*DeviceInit)(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_PARAMS *VolumeParams);
VOID (*DeviceFini)(PDEVICE_OBJECT DeviceObject);
VOID (*DeviceExpirationRoutine)(PDEVICE_OBJECT DeviceObject, UINT64 ExpirationTime);
NTSTATUS (*DeviceTransact)(PDEVICE_OBJECT DeviceObject, PIRP Irp);
/* out */
UINT32 DeviceExtensionOffset;
} FSP_FSEXT_PROVIDER;
FSP_DDI_DEF(NTSTATUS, FspFsextProviderRegister,
FSP_FSEXT_PROVIDER *Provider)
FSP_DDI_DEF(NTSTATUS, FspPosixMapUidToSid,
UINT32 Uid,
PSID *PSid)
FSP_DDI_DEF(NTSTATUS, FspPosixMapSidToUid,
PSID Sid,
PUINT32 PUid)
FSP_DDI_DEF(VOID, FspDeleteSid,
PSID Sid,
NTSTATUS (*CreateFunc)())
FSP_DDI_DEF(NTSTATUS, FspPosixMapPermissionsToSecurityDescriptor,
UINT32 Uid,
UINT32 Gid,
UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor)
FSP_DDI_DEF(NTSTATUS, FspPosixMapSecurityDescriptorToPermissions,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid,
PUINT32 PGid,
PUINT32 PMode)
FSP_DDI_DEF(NTSTATUS, FspPosixMapWindowsToPosixPathEx,
PWSTR WindowsPath,
char **PPosixPath,
BOOLEAN Translate)
FSP_DDI_DEF(NTSTATUS, FspPosixMapPosixToWindowsPathEx,
const char *PosixPath,
PWSTR *PWindowsPath,
BOOLEAN Translate)
FSP_DDI_DEF(VOID, FspPosixDeletePath,
void *Path)
FSP_DDI_DEF(VOID, FspPosixEncodeWindowsPath,
PWSTR WindowsPath,
ULONG Size)
FSP_DDI_DEF(VOID, FspPosixDecodeWindowsPath,
PWSTR WindowsPath,
ULONG Size)
#endif

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,6 @@
// tools\impdef.bat lib\winfsp.impdef lib\winfsp-x64.lib
// tools\impdef.bat lib\winfsp.impdef lib\winfsp-x86.lib
#define FSP_DDI_DEF(RetType, Name, ...) __declspec(dllexport) RetType NTAPI Name ( __VA_ARGS__ ) {}
#include <ntifs.h>
#include <winfsp/fsext.h>

View File

@ -24,6 +24,8 @@
enum enum
{ {
FspFileSystemDispatcherThreadCountMin = 2, FspFileSystemDispatcherThreadCountMin = 2,
FspFileSystemDispatcherDefaultThreadCountMin = 4,
FspFileSystemDispatcherDefaultThreadCountMax = 16,
}; };
static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface; static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface;
@ -636,6 +638,11 @@ FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG
for (ThreadCount = 0; 0 != ProcessMask; ProcessMask >>= 1) for (ThreadCount = 0; 0 != ProcessMask; ProcessMask >>= 1)
ThreadCount += ProcessMask & 1; ThreadCount += ProcessMask & 1;
if (ThreadCount < FspFileSystemDispatcherDefaultThreadCountMin)
ThreadCount = FspFileSystemDispatcherDefaultThreadCountMin;
else if (ThreadCount > FspFileSystemDispatcherDefaultThreadCountMax)
ThreadCount = FspFileSystemDispatcherDefaultThreadCountMax;
} }
if (ThreadCount < FspFileSystemDispatcherThreadCountMin) if (ThreadCount < FspFileSystemDispatcherThreadCountMin)

View File

@ -443,6 +443,7 @@ static NTSTATUS FspFileSystemOpCreate_FileCreate(FSP_FILE_SYSTEM *FileSystem,
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
@ -590,6 +591,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOpenIf(FSP_FILE_SYSTEM *FileSystem,
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,
@ -724,6 +726,7 @@ static NTSTATUS FspFileSystemOpCreate_FileOverwriteIf(FSP_FILE_SYSTEM *FileSyste
0 != Request->Req.Create.Ea.Size ? 0 != Request->Req.Create.Ea.Size ?
(PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0, (PVOID)(Request->Buffer + Request->Req.Create.Ea.Offset) : 0,
Request->Req.Create.Ea.Size, Request->Req.Create.Ea.Size,
Request->Req.Create.EaIsReparsePoint,
AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo); AddrOfFileContext(FullContext), &OpenFileInfo.FileInfo);
else else
Result = FileSystem->Interface->Create(FileSystem, Result = FileSystem->Interface->Create(FileSystem,

View File

@ -54,6 +54,10 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("umask=%o", umask, 0), FSP_FUSE_CORE_OPT("umask=%o", umask, 0),
FSP_FUSE_CORE_OPT("create_umask=", set_create_umask, 1), FSP_FUSE_CORE_OPT("create_umask=", set_create_umask, 1),
FSP_FUSE_CORE_OPT("create_umask=%o", create_umask, 0), FSP_FUSE_CORE_OPT("create_umask=%o", create_umask, 0),
FSP_FUSE_CORE_OPT("create_file_umask=", set_create_file_umask, 1),
FSP_FUSE_CORE_OPT("create_file_umask=%o", create_file_umask, 0),
FSP_FUSE_CORE_OPT("create_dir_umask=", set_create_dir_umask, 1),
FSP_FUSE_CORE_OPT("create_dir_umask=%o", create_dir_umask, 0),
FSP_FUSE_CORE_OPT("uid=", set_uid, 1), FSP_FUSE_CORE_OPT("uid=", set_uid, 1),
FSP_FUSE_CORE_OPT("uid=%d", uid, 0), FSP_FUSE_CORE_OPT("uid=%d", uid, 0),
FSP_FUSE_CORE_OPT("gid=", set_gid, 1), FSP_FUSE_CORE_OPT("gid=", set_gid, 1),
@ -71,6 +75,9 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FSP_FUSE_CORE_OPT("rellinks", rellinks, 1), FSP_FUSE_CORE_OPT("rellinks", rellinks, 1),
FSP_FUSE_CORE_OPT("norellinks", rellinks, 0), FSP_FUSE_CORE_OPT("norellinks", rellinks, 0),
FSP_FUSE_CORE_OPT("dothidden", dothidden, 1),
FSP_FUSE_CORE_OPT("nodothidden", dothidden, 0),
FUSE_OPT_KEY("fstypename=", 'F'), FUSE_OPT_KEY("fstypename=", 'F'),
FUSE_OPT_KEY("volname=", 'v'), FUSE_OPT_KEY("volname=", 'v'),
@ -96,6 +103,15 @@ static struct fuse_opt fsp_fuse_core_opts[] =
FUSE_OPT_KEY("FileSystemName=", 'F'), FUSE_OPT_KEY("FileSystemName=", 'F'),
FUSE_OPT_KEY("--FileSystemName=", 'F'), FUSE_OPT_KEY("--FileSystemName=", 'F'),
FSP_FUSE_CORE_OPT("UserName=", set_uid, 1),
FUSE_OPT_KEY("UserName=", 'u'),
FSP_FUSE_CORE_OPT("--UserName=", set_uid, 1),
FUSE_OPT_KEY("--UserName=", 'u'),
FSP_FUSE_CORE_OPT("GroupName=", set_gid, 1),
FUSE_OPT_KEY("GroupName=", 'g'),
FSP_FUSE_CORE_OPT("--GroupName=", set_gid, 1),
FUSE_OPT_KEY("--GroupName=", 'g'),
FUSE_OPT_END, FUSE_OPT_END,
}; };
@ -226,6 +242,43 @@ FSP_FUSE_API int fsp_fuse_is_lib_option(struct fsp_fuse_env *env,
return fsp_fuse_opt_match(env, fsp_fuse_core_opts, opt); return fsp_fuse_opt_match(env, fsp_fuse_core_opts, opt);
} }
static int fsp_fuse_username_to_uid(const char *username, int *puid)
{
union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} SidBuf;
char Name[256], Domn[256];
DWORD SidSize, NameSize, DomnSize;
SID_NAME_USE Use;
UINT32 Uid;
NTSTATUS Result;
*puid = 0;
NameSize = lstrlenA(username) + 1;
if (sizeof Name / sizeof Name[0] < NameSize)
return -1;
memcpy(Name, username, NameSize);
for (PSTR P = Name, EndP = P + NameSize; EndP > P; P++)
if ('+' == *P)
*P = '\\';
SidSize = sizeof SidBuf;
DomnSize = sizeof Domn / sizeof Domn[0];
if (!LookupAccountNameA(0, Name, &SidBuf, &SidSize, Domn, &DomnSize, &Use))
return -1;
Result = FspPosixMapSidToUid(&SidBuf, &Uid);
if (!NT_SUCCESS(Result))
return -1;
*puid = Uid;
return 0;
}
static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key, static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
struct fuse_args *outargs) struct fuse_args *outargs)
{ {
@ -241,9 +294,12 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
FSP_FUSE_LIBRARY_NAME " options:\n" FSP_FUSE_LIBRARY_NAME " options:\n"
" -o umask=MASK set file permissions (octal)\n" " -o umask=MASK set file permissions (octal)\n"
" -o create_umask=MASK set newly created file permissions (octal)\n" " -o create_umask=MASK set newly created file permissions (octal)\n"
" -o create_file_umask=MASK for files only\n"
" -o create_dir_umask=MASK for directories only\n"
" -o uid=N set file owner (-1 for mounting user id)\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 gid=N set file group (-1 for mounting user group)\n"
" -o rellinks interpret absolute symlinks as volume relative\n" " -o rellinks interpret absolute symlinks as volume relative\n"
" -o dothidden dot files have the Windows hidden file attrib\n"
" -o volname=NAME set volume label\n" " -o volname=NAME set volume label\n"
" -o VolumePrefix=UNC set UNC prefix (/Server/Share)\n" " -o VolumePrefix=UNC set UNC prefix (/Server/Share)\n"
" --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n" " --VolumePrefix=UNC set UNC prefix (\\Server\\Share)\n"
@ -311,6 +367,28 @@ static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
[sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0'; [sizeof opt_data->VolumeParams.FileSystemName / sizeof(WCHAR) - 1] = L'\0';
memcpy(opt_data->VolumeParams.FileSystemName, L"FUSE-", 5 * sizeof(WCHAR)); memcpy(opt_data->VolumeParams.FileSystemName, L"FUSE-", 5 * sizeof(WCHAR));
return 0; return 0;
case 'u':
if ('U' == arg[0])
arg += sizeof "UserName=" - 1;
else if ('U' == arg[2])
arg += sizeof "--UserName=" - 1;
if (-1 == fsp_fuse_username_to_uid(arg, &opt_data->uid))
{
opt_data->username_to_uid_result = -1;
return -1;
}
return 0;
case 'g':
if ('G' == arg[0])
arg += sizeof "GroupName=" - 1;
else if ('G' == arg[2])
arg += sizeof "--GroupName=" - 1;
if (-1 == fsp_fuse_username_to_uid(arg, &opt_data->gid))
{
opt_data->username_to_uid_result = -1;
return -1;
}
return 0;
case 'v': case 'v':
arg += sizeof "volname=" - 1; arg += sizeof "volname=" - 1;
opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) * opt_data->VolumeLabelLength = (UINT16)(sizeof(WCHAR) *
@ -355,7 +433,14 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE; opt_data.VolumeParams.FlushAndPurgeOnCleanup = TRUE;
if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1)) if (-1 == fsp_fuse_core_opt_parse(env, args, &opt_data, /*help=*/1))
{
if (-1 == opt_data.username_to_uid_result)
{
ErrorMessage = L": invalid user or group name.";
goto fail;
}
return 0; return 0;
}
if (opt_data.help) if (opt_data.help)
return 0; return 0;
@ -422,9 +507,12 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
f->env = env; f->env = env;
f->set_umask = opt_data.set_umask; f->umask = opt_data.umask; f->set_umask = opt_data.set_umask; f->umask = opt_data.umask;
f->set_create_umask = opt_data.set_create_umask; f->create_umask = opt_data.create_umask; f->set_create_umask = opt_data.set_create_umask; f->create_umask = opt_data.create_umask;
f->set_create_file_umask = opt_data.set_create_file_umask; f->create_file_umask = opt_data.create_file_umask;
f->set_create_dir_umask = opt_data.set_create_dir_umask; f->create_dir_umask = opt_data.create_dir_umask;
f->set_uid = opt_data.set_uid; f->uid = opt_data.uid; f->set_uid = opt_data.set_uid; f->uid = opt_data.uid;
f->set_gid = opt_data.set_gid; f->gid = opt_data.gid; f->set_gid = opt_data.set_gid; f->gid = opt_data.gid;
f->rellinks = opt_data.rellinks; f->rellinks = opt_data.rellinks;
f->dothidden = opt_data.dothidden;
f->ThreadCount = opt_data.ThreadCount; f->ThreadCount = opt_data.ThreadCount;
memcpy(&f->ops, ops, opsize); memcpy(&f->ops, ops, opsize);
f->data = data; f->data = data;

View File

@ -354,6 +354,7 @@ static inline UINT32 fsp_fuse_intf_MapFlagsToFileAttributes(uint32_t flags)
return FileAttributes; return FileAttributes;
} }
#define FUSE_FILE_INFO(IsDirectory, fi) ((IsDirectory) ? 0 : (fi))
#define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\ #define fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, fi, PUid, PGid, PMode, FileInfo)\
fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo) fsp_fuse_intf_GetFileInfoFunnel(FileSystem, PosixPath, fi, 0, PUid, PGid, PMode, 0, FileInfo)
static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
@ -429,6 +430,15 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
} }
if (StatEx) if (StatEx)
FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags); FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags);
if (f->dothidden)
{
const char *basename = PosixPath;
for (const char *p = PosixPath; '\0' != *p; p++)
if ('/' == *p)
basename = p + 1;
if ('.' == basename[0])
FileInfo->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
FileInfo->FileSize = stbuf.st_size; FileInfo->FileSize = stbuf.st_size;
FileInfo->AllocationSize = FileInfo->AllocationSize =
(FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; (FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
@ -743,7 +753,7 @@ exit:
static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileDesc, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
@ -757,12 +767,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
int err; int err;
NTSTATUS Result; NTSTATUS Result;
if (0 != Ea) if (0 != ExtraBuffer)
{ {
if (0 == f->ops.listxattr || 0 == f->ops.getxattr || if (!ExtraBufferIsReparsePoint)
0 == f->ops.setxattr || 0 == f->ops.removexattr)
{ {
Result = STATUS_EAS_NOT_SUPPORTED; if (0 == f->ops.listxattr || 0 == f->ops.getxattr ||
0 == f->ops.setxattr || 0 == f->ops.removexattr)
{
Result = STATUS_EAS_NOT_SUPPORTED;
goto exit;
}
}
else
{
/* !!!: revisit */
Result = STATUS_INVALID_PARAMETER;
goto exit; goto exit;
} }
} }
@ -785,8 +804,22 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
Mode &= ~context->umask; Mode &= ~context->umask;
if (f->set_create_umask) if (CreateOptions & FILE_DIRECTORY_FILE)
Mode = 0777 & ~f->create_umask; {
if (f->set_create_dir_umask)
Mode = 0777 & ~f->create_dir_umask;
else
if (f->set_create_umask)
Mode = 0777 & ~f->create_umask;
}
else
{
if (f->set_create_file_umask)
Mode = 0777 & ~f->create_file_umask;
else
if (f->set_create_umask)
Mode = 0777 & ~f->create_umask;
}
memset(&fi, 0, sizeof fi); memset(&fi, 0, sizeof fi);
if ('C' == f->env->environment) /* Cygwin */ if ('C' == f->env->environment) /* Cygwin */
@ -866,12 +899,21 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
if (0 != Ea) if (0 != ExtraBuffer)
{ {
Result = FspFileSystemEnumerateEa(FileSystem, if (!ExtraBufferIsReparsePoint)
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, Ea, EaLength); {
if (!NT_SUCCESS(Result)) Result = FspFileSystemEnumerateEa(FileSystem,
fsp_fuse_intf_SetEaEntry, contexthdr->PosixPath, ExtraBuffer, ExtraLength);
if (!NT_SUCCESS(Result))
goto exit;
}
else
{
/* !!!: revisit: WslFeatures, GetFileInfoFunnel, GetReparsePointEx, SetReparsePoint */
Result = STATUS_INVALID_PARAMETER;
goto exit; goto exit;
}
} }
/* /*
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache. * Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
@ -881,7 +923,8 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
* Ignore fuse_file_info::nonseekable. * Ignore fuse_file_info::nonseekable.
*/ */
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, contexthdr->PosixPath,
FUSE_FILE_INFO(CreateOptions & FILE_DIRECTORY_FILE, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1096,7 +1139,8 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1227,7 +1271,8 @@ static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1307,7 +1352,8 @@ static NTSTATUS fsp_fuse_intf_Flush(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1330,7 +1376,8 @@ static NTSTATUS fsp_fuse_intf_GetFileInfo(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1368,7 +1415,8 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
{ {
if (0 == LastAccessTime || 0 == LastWriteTime) if (0 == LastAccessTime || 0 == LastWriteTime)
{ {
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1415,7 +1463,8 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
return Result; return Result;
} }
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }
@ -1442,7 +1491,8 @@ static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfoBuf); &Uid, &Gid, &Mode, &FileInfoBuf);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -1589,7 +1639,8 @@ static NTSTATUS fsp_fuse_intf_GetSecurity(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetSecurityEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetSecurityEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&FileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize); &FileAttributes, SecurityDescriptorBuf, PSecurityDescriptorSize);
} }
@ -1613,8 +1664,9 @@ static NTSTATUS fsp_fuse_intf_SetSecurity(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, &Uid, &Gid, &Mode, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
&FileInfo); FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
@ -1712,7 +1764,7 @@ int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
NTSTATUS Result0; NTSTATUS Result0;
Result0 = fsp_fuse_intf_GetFileInfoFunnel(dh->FileSystem, 0, 0, stbuf, Result0 = fsp_fuse_intf_GetFileInfoFunnel(dh->FileSystem, name, 0, stbuf,
&Uid, &Gid, &Mode, 0, &DirInfo->FileInfo); &Uid, &Gid, &Mode, 0, &DirInfo->FileInfo);
if (NT_SUCCESS(Result0)) if (NT_SUCCESS(Result0))
DirInfo->Padding[0] = 1; /* HACK: remember that the FileInfo is valid */ DirInfo->Padding[0] = 1; /* HACK: remember that the FileInfo is valid */
@ -1972,7 +2024,9 @@ static NTSTATUS fsp_fuse_intf_GetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetReparsePointEx(FileSystem, filedesc->PosixPath, &fi, Buffer, PSize); return fsp_fuse_intf_GetReparsePointEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
Buffer, PSize);
} }
static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
@ -2043,7 +2097,8 @@ static NTSTATUS fsp_fuse_intf_SetReparsePoint(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, &FileInfo); &Uid, &Gid, &Mode, &FileInfo);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
@ -2316,7 +2371,8 @@ static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
fi.flags = filedesc->OpenFlags; fi.flags = filedesc->OpenFlags;
fi.fh = filedesc->FileHandle; fi.fh = filedesc->FileHandle;
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi, return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath,
FUSE_FILE_INFO(filedesc->IsDirectory, &fi),
&Uid, &Gid, &Mode, FileInfo); &Uid, &Gid, &Mode, FileInfo);
} }

View File

@ -216,11 +216,13 @@ static int fsp_fuse_opt_call_proc(struct fsp_fuse_env *env,
goto exit; goto exit;
} }
result = 0;
exit: exit:
if (0 != fullarg) if (0 != fullarg)
env->memfree(fullarg); env->memfree(fullarg);
return 0; return result;
} }
static int fsp_fuse_opt_process_arg(struct fsp_fuse_env *env, static int fsp_fuse_opt_process_arg(struct fsp_fuse_env *env,

View File

@ -50,9 +50,12 @@ struct fuse
struct fsp_fuse_env *env; struct fsp_fuse_env *env;
int set_umask, umask; int set_umask, umask;
int set_create_umask, create_umask; int set_create_umask, create_umask;
int set_create_file_umask, create_file_umask;
int set_create_dir_umask, create_dir_umask;
int set_uid, uid; int set_uid, uid;
int set_gid, gid; int set_gid, gid;
int rellinks; int rellinks;
int dothidden;
unsigned ThreadCount; unsigned ThreadCount;
struct fuse_operations ops; struct fuse_operations ops;
void *data; void *data;
@ -137,10 +140,13 @@ struct fsp_fuse_core_opt_data
HANDLE DebugLogHandle; HANDLE DebugLogHandle;
int set_umask, umask, int set_umask, umask,
set_create_umask, create_umask, set_create_umask, create_umask,
set_uid, uid, set_create_file_umask, create_file_umask,
set_create_dir_umask, create_dir_umask,
set_uid, uid, username_to_uid_result,
set_gid, gid, set_gid, gid,
set_attr_timeout, attr_timeout, set_attr_timeout, attr_timeout,
rellinks; rellinks,
dothidden;
int set_FileInfoTimeout, int set_FileInfoTimeout,
set_DirInfoTimeout, set_DirInfoTimeout,
set_EaTimeout, set_EaTimeout,

View File

@ -1085,8 +1085,9 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
Byte[] SecurityDescriptor, Byte[] SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
Boolean ExtraBufferIsReparsePoint,
out Object FileNode, out Object FileNode,
out Object FileDesc, out Object FileDesc,
out FileInfo FileInfo, out FileInfo FileInfo,
@ -1391,6 +1392,16 @@ namespace Fsp
} }
} }
/// <summary> /// <summary>
/// Makes a byte array that contains a reparse point.
/// </summary>
/// <returns>The reparse point byte array.</returns>
public static Byte[] MakeReparsePoint(
IntPtr Buffer,
UInt32 Size)
{
return Api.MakeReparsePoint(Buffer, (UIntPtr)Size);
}
/// <summary>
/// Gets the reparse tag from reparse data. /// Gets the reparse tag from reparse data.
/// </summary> /// </summary>
/// <param name="ReparseData"> /// <param name="ReparseData">

View File

@ -40,6 +40,7 @@ namespace Fsp
/// <param name="FileSystem">The file system to host.</param> /// <param name="FileSystem">The file system to host.</param>
public FileSystemHost(FileSystemBase FileSystem) public FileSystemHost(FileSystemBase FileSystem)
{ {
_VolumeParams.Version = (UInt16)Marshal.SizeOf(_VolumeParams);
_VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext; _VolumeParams.Flags = VolumeParams.UmFileContextIsFullContext;
_FileSystem = FileSystem; _FileSystem = FileSystem;
} }
@ -126,6 +127,86 @@ namespace Fsp
set { _VolumeParams.FileInfoTimeout = value; } set { _VolumeParams.FileInfoTimeout = value; }
} }
/// <summary> /// <summary>
/// Gets or sets the volume information timeout.
/// </summary>
public UInt32 VolumeInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.VolumeInfoTimeoutValid) ?
_VolumeParams.VolumeInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.VolumeInfoTimeoutValid;
_VolumeParams.VolumeInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the directory information timeout.
/// </summary>
public UInt32 DirInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.DirInfoTimeoutValid) ?
_VolumeParams.DirInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.DirInfoTimeoutValid;
_VolumeParams.DirInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the security information timeout.
/// </summary>
public UInt32 SecurityTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.SecurityTimeoutValid) ?
_VolumeParams.SecurityTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.SecurityTimeoutValid;
_VolumeParams.SecurityTimeout = value;
}
}
/// <summary>
/// Gets or sets the stream information timeout.
/// </summary>
public UInt32 StreamInfoTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.StreamInfoTimeoutValid) ?
_VolumeParams.StreamInfoTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.StreamInfoTimeoutValid;
_VolumeParams.StreamInfoTimeout = value;
}
}
/// <summary>
/// Gets or sets the EA information timeout.
/// </summary>
public UInt32 EaTimeout
{
get
{
return 0 != (_VolumeParams.AdditionalFlags & VolumeParams.EaTimeoutValid) ?
_VolumeParams.EaTimeout : _VolumeParams.FileInfoTimeout;
}
set
{
_VolumeParams.AdditionalFlags |= VolumeParams.EaTimeoutValid;
_VolumeParams.EaTimeout = value;
}
}
/// <summary>
/// Gets or sets a value that determines whether the file system is case sensitive. /// Gets or sets a value that determines whether the file system is case sensitive.
/// </summary> /// </summary>
public Boolean CaseSensitiveSearch public Boolean CaseSensitiveSearch
@ -221,6 +302,11 @@ namespace Fsp
get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); } get { return 0 != (_VolumeParams.Flags & VolumeParams.AllowOpenInKernelMode); }
set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); } set { _VolumeParams.Flags |= (value ? VolumeParams.AllowOpenInKernelMode : 0); }
} }
public Boolean WslFeatures
{
get { return 0 != (_VolumeParams.Flags & VolumeParams.WslFeatures); }
set { _VolumeParams.Flags |= (value ? VolumeParams.WslFeatures : 0); }
}
/// <summary> /// <summary>
/// Gets or sets the prefix for a network file system. /// Gets or sets the prefix for a network file system.
/// </summary> /// </summary>
@ -274,11 +360,44 @@ namespace Fsp
/// A value of 0 disables all debug logging. /// A value of 0 disables all debug logging.
/// A value of -1 enables all debug logging. /// A value of -1 enables all debug logging.
/// </param> /// </param>
/// <returns></returns> /// <returns>STATUS_SUCCESS or error code.</returns>
public Int32 Mount(String MountPoint, public Int32 Mount(String MountPoint,
Byte[] SecurityDescriptor = null, Byte[] SecurityDescriptor = null,
Boolean Synchronized = false, Boolean Synchronized = false,
UInt32 DebugLog = 0) UInt32 DebugLog = 0)
{
return MountEx(MountPoint, 0, SecurityDescriptor, Synchronized, DebugLog);
}
/// <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="ThreadCount">
/// Number of threads to use to service file system requests. A value
/// of 0 means that the default number of threads should be used.
/// </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>STATUS_SUCCESS or error code.</returns>
public Int32 MountEx(String MountPoint,
UInt32 ThreadCount,
Byte[] SecurityDescriptor = null,
Boolean Synchronized = false,
UInt32 DebugLog = 0)
{ {
Int32 Result; Int32 Result;
try try
@ -315,7 +434,7 @@ namespace Fsp
} }
if (0 <= Result) if (0 <= Result)
{ {
Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, 0); Result = Api.FspFileSystemStartDispatcher(_FileSystemPtr, ThreadCount);
if (0 > Result) if (0 > Result)
try try
{ {
@ -381,6 +500,83 @@ namespace Fsp
{ {
return Api.GetVersion(); return Api.GetVersion();
} }
/// <summary>
/// Returns a RequestHint to reference the current operation asynchronously.
/// </summary>
public UInt64 GetOperationRequestHint()
{
return Api.FspFileSystemGetOperationRequestHint();
}
/// <summary>
/// Asynchronously complete a Read operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// Number of bytes read.
/// </param>
public void SendReadResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.ReadKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/// <summary>
/// Asynchronously complete a Write operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// The number of bytes written.
/// </param>
/// <param name="FileInfo">
/// Updated file information.
/// </param>
public void SendWriteResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred, ref FileInfo FileInfo)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.WriteKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Response.WriteFileInfo = FileInfo;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/// <summary>
/// Asynchronously complete a ReadDirectory operation.
/// </summary>
/// <param name="RequestHint">
/// A reference to the operation to complete.
/// </param>
/// <param name="Status">
/// STATUS_SUCCESS or error code.
/// </param>
/// <param name="BytesTransferred">
/// Number of bytes read.
/// </param>
public void SendReadDirectoryResponse(UInt64 RequestHint, Int32 Status, UInt32 BytesTransferred)
{
FspFsctlTransactRsp Response = default(FspFsctlTransactRsp);
Response.Size = 128;
Response.Kind = (UInt32)FspFsctlTransact.QueryDirectoryKind;
Response.Hint = RequestHint;
Response.IoStatus.Information = BytesTransferred;
Response.IoStatus.Status = (UInt32)Status;
Api.FspFileSystemSendResponse(_FileSystemPtr, ref Response);
}
/* FSP_FILE_SYSTEM_INTERFACE */ /* FSP_FILE_SYSTEM_INTERFACE */
private static Byte[] ByteBufferNotNull = new Byte[0]; private static Byte[] ByteBufferNotNull = new Byte[0];
@ -472,8 +668,9 @@ namespace Fsp
UInt32 FileAttributes, UInt32 FileAttributes,
IntPtr SecurityDescriptor, IntPtr SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
Boolean ExtraBufferIsReparsePoint,
ref FullContext FullContext, ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo) ref OpenFileInfo OpenFileInfo)
{ {
@ -490,8 +687,9 @@ namespace Fsp
FileAttributes, FileAttributes,
Api.MakeSecurityDescriptor(SecurityDescriptor), Api.MakeSecurityDescriptor(SecurityDescriptor),
AllocationSize, AllocationSize,
Ea, ExtraBuffer,
EaLength, ExtraLength,
ExtraBufferIsReparsePoint,
out FileNode, out FileNode,
out FileDesc, out FileDesc,
out OpenFileInfo.FileInfo, out OpenFileInfo.FileInfo,

View File

@ -53,9 +53,16 @@ namespace Fsp.Interop
internal const UInt32 UmFileContextIsFullContext = 0x00020000; internal const UInt32 UmFileContextIsFullContext = 0x00020000;
internal const UInt32 AllowOpenInKernelMode = 0x01000000; internal const UInt32 AllowOpenInKernelMode = 0x01000000;
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000; internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
internal const UInt32 WslFeatures = 0x04000000;
internal const int PrefixSize = 192; internal const int PrefixSize = 192;
internal const int FileSystemNameSize = 16; internal const int FileSystemNameSize = 16;
internal const UInt32 VolumeInfoTimeoutValid = 0x00000001;
internal const UInt32 DirInfoTimeoutValid = 0x00000002;
internal const UInt32 SecurityTimeoutValid = 0x00000004;
internal const UInt32 StreamInfoTimeoutValid = 0x00000008;
internal const UInt32 EaTimeoutValid = 0x00000010;
internal UInt16 Version; internal UInt16 Version;
internal UInt16 SectorSize; internal UInt16 SectorSize;
internal UInt16 SectorsPerAllocationUnit; internal UInt16 SectorsPerAllocationUnit;
@ -69,6 +76,15 @@ namespace Fsp.Interop
internal UInt32 Flags; internal UInt32 Flags;
internal unsafe fixed UInt16 Prefix[PrefixSize]; internal unsafe fixed UInt16 Prefix[PrefixSize];
internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize]; internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize];
internal UInt32 AdditionalFlags;
internal UInt32 VolumeInfoTimeout;
internal UInt32 DirInfoTimeout;
internal UInt32 SecurityTimeout;
internal UInt32 StreamInfoTimeout;
internal UInt32 EaTimeout;
internal UInt32 FsextControlCode;
internal unsafe fixed UInt32 Reserved32[1];
internal unsafe fixed UInt64 Reserved64[2];
internal unsafe String GetPrefix() internal unsafe String GetPrefix()
{ {
@ -354,6 +370,65 @@ namespace Fsp.Interop
public IntPtr Information; public IntPtr Information;
} }
[StructLayout(LayoutKind.Sequential)]
internal struct IoStatus
{
internal UInt32 Information;
internal UInt32 Status;
}
internal enum FspFsctlTransact
{
ReadKind = 5,
WriteKind = 6,
QueryDirectoryKind = 14
}
[StructLayout(LayoutKind.Explicit)]
internal struct FspFsctlTransactReq
{
[FieldOffset(0)]
internal UInt16 Version;
[FieldOffset(2)]
internal UInt16 Size;
[FieldOffset(4)]
internal UInt32 Kind;
[FieldOffset(8)]
internal UInt64 Hint;
[FieldOffset(0)]
internal unsafe fixed Byte Padding[88];
}
[StructLayout(LayoutKind.Explicit)]
internal struct FspFsctlTransactRsp
{
[FieldOffset(0)]
internal UInt16 Version;
[FieldOffset(2)]
internal UInt16 Size;
[FieldOffset(4)]
internal UInt32 Kind;
[FieldOffset(8)]
internal UInt64 Hint;
[FieldOffset(16)]
internal IoStatus IoStatus;
[FieldOffset(24)]
internal FileInfo WriteFileInfo;
[FieldOffset(0)]
internal unsafe fixed Byte Padding[128];
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct FspFileSystemOperationContext
{
internal FspFsctlTransactReq *Request;
internal FspFsctlTransactRsp *Response;
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct FileSystemInterface internal struct FileSystemInterface
{ {
@ -557,8 +632,9 @@ namespace Fsp.Interop
UInt32 FileAttributes, UInt32 FileAttributes,
IntPtr SecurityDescriptor, IntPtr SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
[MarshalAs(UnmanagedType.U1)] Boolean ExtraBufferIsReparsePoint,
ref FullContext FullContext, ref FullContext FullContext,
ref OpenFileInfo OpenFileInfo); ref OpenFileInfo OpenFileInfo);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -662,6 +738,12 @@ namespace Fsp.Interop
internal delegate Int32 FspFileSystemStopDispatcher( internal delegate Int32 FspFileSystemStopDispatcher(
IntPtr FileSystem); IntPtr FileSystem);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void FspFileSystemSendResponse(
IntPtr FileSystem,
ref FspFsctlTransactRsp Response);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal unsafe delegate FspFileSystemOperationContext *FspFileSystemGetOperationContext();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr FspFileSystemMountPointF( internal delegate IntPtr FspFileSystemMountPointF(
IntPtr FileSystem); IntPtr FileSystem);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -846,6 +928,8 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint; internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint;
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher; internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher; internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse;
internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext;
internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint; internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint;
internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy; internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy;
internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog; internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog;
@ -892,6 +976,10 @@ namespace Fsp.Interop
else else
return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero); return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero);
} }
internal static unsafe UInt64 FspFileSystemGetOperationRequestHint()
{
return FspFileSystemGetOperationContext()->Request->Hint;
}
internal static unsafe Boolean FspFileSystemAddDirInfo( internal static unsafe Boolean FspFileSystemAddDirInfo(
ref DirInfo DirInfo, ref DirInfo DirInfo,
IntPtr Buffer, IntPtr Buffer,
@ -1240,6 +1328,8 @@ namespace Fsp.Interop
FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module); FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module);
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module); FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module); FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
FspFileSystemSendResponse = GetEntryPoint<Proto.FspFileSystemSendResponse>(Module);
FspFileSystemGetOperationContext = GetEntryPoint<Proto.FspFileSystemGetOperationContext>(Module);
FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module); FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module);
FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module); FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module);
FspFileSystemSetDebugLog = GetEntryPoint<Proto.FspFileSystemSetDebugLogF>(Module); FspFileSystemSetDebugLog = GetEntryPoint<Proto.FspFileSystemSetDebugLogF>(Module);

222
src/ku/library.h Normal file
View File

@ -0,0 +1,222 @@
/**
* @file ku/library.h
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#ifndef WINFSP_KU_LIBRARY_H_INCLUDED
#define WINFSP_KU_LIBRARY_H_INCLUDED
#if !defined(_KERNEL_MODE)
#include <dll/library.h>
#include <aclapi.h>
#define _NTDEF_
#include <ntsecapi.h>
#define FSP_KU_CODE ((void)0)
#else
#include <sys/driver.h>
#define FSP_KU_CODE PAGED_CODE(); NTSTATUS fsp_ku_status = STATUS_SUCCESS; (VOID)fsp_ku_status
#define FSP_API FSP_DDI
#define BYTE UINT8
#define BOOL BOOLEAN
#define LPBOOL PBOOLEAN
#define UINT ULONG
#define GetLastError() ((DWORD)fsp_ku_status)
#define FspNtStatusFromWin32(Err) ((NTSTATUS)(Err))
#define ERROR_INSUFFICIENT_BUFFER STATUS_BUFFER_TOO_SMALL
#define InitOnceExecuteOnce(I, F, P, C) RtlRunOnceExecuteOnce(I, F, P, C)
#define INIT_ONCE RTL_RUN_ONCE
#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
#define AddAccessAllowedAce(Acl, Rev, Acc, Sid)\
(fsp_ku_status = RtlAddAccessAllowedAce(Acl, Rev, Acc, Sid),\
NT_SUCCESS(fsp_ku_status))
#define AddAccessDeniedAce(Acl, Rev, Acc, Sid)\
(fsp_ku_status = FspKuAddAccessDeniedAce(Acl, Rev, Acc, Sid),\
NT_SUCCESS(fsp_ku_status))
#define EqualSid(Sid1, Sid2) (fsp_ku_status = 0, RtlEqualSid(Sid1, Sid2))
#define GetAce(Acl, Idx, Ace) (fsp_ku_status = RtlGetAce(Acl, Idx, Ace), NT_SUCCESS(fsp_ku_status))
#define GetAclInformation(Acl, Inf, Len, Cls)\
(fsp_ku_status = FspKuQueryInformationAcl(Acl, Inf, Len, Cls),\
NT_SUCCESS(fsp_ku_status))
#define GetLengthSid(Sid) (fsp_ku_status = 0, RtlLengthSid(Sid))
#define GetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
(fsp_ku_status = RtlGetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSecurityDescriptorGroup(Sec, Grp, Def)\
(fsp_ku_status = RtlGetGroupSecurityDescriptor(Sec, Grp, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSecurityDescriptorOwner(Sec, Own, Def)\
(fsp_ku_status = RtlGetOwnerSecurityDescriptor(Sec, Own, Def),\
NT_SUCCESS(fsp_ku_status))
#define GetSidIdentifierAuthority(Sid) (fsp_ku_status = 0, &((PISID)(Sid))->IdentifierAuthority)
#define GetSidSubAuthority(Sid, Sub) (fsp_ku_status = 0, RtlSubAuthoritySid(Sid, Sub))
#define GetSidSubAuthorityCount(Sid) (fsp_ku_status = 0, RtlSubAuthorityCountSid(Sid))
#define InitializeAcl(Acl, Len, Rev) (fsp_ku_status = RtlCreateAcl(Acl, Len, Rev), NT_SUCCESS(fsp_ku_status))
#define InitializeSecurityDescriptor(Sec, Rev)\
(fsp_ku_status = RtlCreateSecurityDescriptor(Sec, Rev),\
NT_SUCCESS(fsp_ku_status))
#define InitializeSid(Sid, Aut, Cnt) (fsp_ku_status = RtlInitializeSid(Sid, Aut, Cnt), NT_SUCCESS(fsp_ku_status))
#define IsValidSid(Sid) (RtlValidSid(Sid) || (fsp_ku_status = STATUS_INVALID_SID, FALSE))
#define MakeSelfRelativeSD(Abs, Rel, Len)\
(fsp_ku_status = RtlAbsoluteToSelfRelativeSD(Abs, Rel, Len),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorControl(Sec, Msk, Bit)\
(fsp_ku_status = FspKuSetControlSecurityDescriptor(Sec, Msk, Bit),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorDacl(Sec, Prs, Dac, Def)\
(fsp_ku_status = RtlSetDaclSecurityDescriptor(Sec, Prs, Dac, Def),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorGroup(Sec, Grp, Def)\
(fsp_ku_status = RtlSetGroupSecurityDescriptor(Sec, Grp, Def),\
NT_SUCCESS(fsp_ku_status))
#define SetSecurityDescriptorOwner(Sec, Own, Def)\
(fsp_ku_status = RtlSetOwnerSecurityDescriptor(Sec, Own, Def),\
NT_SUCCESS(fsp_ku_status))
static inline NTSTATUS FspKuAddAccessDeniedAce(
PACL Acl,
ULONG AceRevision,
ACCESS_MASK AccessMask,
PSID Sid)
{
/* We are missing RtlAddAccessDeniedAce. So we need this malarkey! */
NTSTATUS Result;
PACE_HEADER Ace;
Result = RtlAddAccessAllowedAce(Acl, AceRevision, AccessMask, Sid);
if (!NT_SUCCESS(Result))
return Result;
Result = RtlGetAce(Acl, Acl->AceCount - 1, &Ace);
if (!NT_SUCCESS(Result))
return Result;
Ace->AceType = ACCESS_DENIED_ACE_TYPE;
return STATUS_SUCCESS;
}
typedef enum
{
AclRevisionInformation__DO_NOT_USE = 1,
AclSizeInformation,
} ACL_INFORMATION_CLASS;
typedef struct
{
DWORD AceCount;
DWORD AclBytesInUse__DO_NOT_USE;
DWORD AclBytesFree__DO_NOT_USE;
} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
static inline NTSTATUS FspKuQueryInformationAcl(
PACL Acl,
PVOID AclInformation,
ULONG AclInformationLength,
ACL_INFORMATION_CLASS AclInformationClass)
{
ASSERT(AclSizeInformation == AclInformationClass);
ASSERT(sizeof(ACL_SIZE_INFORMATION) <= AclInformationLength);
((PACL_SIZE_INFORMATION)AclInformation)->AceCount = Acl->AceCount;
return STATUS_SUCCESS;
}
static inline NTSTATUS FspKuSetControlSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor,
SECURITY_DESCRIPTOR_CONTROL ControlMask,
SECURITY_DESCRIPTOR_CONTROL ControlBits)
{
((PUSHORT)(SecurityDescriptor))[1] &= ~ControlMask;
((PUSHORT)(SecurityDescriptor))[1] |= ControlBits;
return STATUS_SUCCESS;
}
#define WideCharToMultiByte(C, F, W, w, B, b, D, d)\
(FspKuWideCharToMultiByte(C, F, W, w, B, b, D, d, &fsp_ku_status))
#define MultiByteToWideChar(C, F, B, b, W, w)\
(FspKuMultiByteToWideChar(C, F, B, b, W, w, &fsp_ku_status))
#define CP_UTF8 65001
static inline int FspKuWideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWCH lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCCH lpDefaultChar,
LPBOOL lpUsedDefaultChar,
PNTSTATUS PResult)
{
ASSERT(CP_UTF8 == CodePage);
ASSERT(0 == dwFlags);
ASSERT(0 == lpDefaultChar);
ASSERT(0 == lpUsedDefaultChar);
NTSTATUS Result;
ULONG ByteCount;
if (-1 == cchWideChar)
cchWideChar = (int)wcslen(lpWideCharStr) + 1;
Result = RtlUnicodeToUTF8N(
lpMultiByteStr, cbMultiByte, &ByteCount,
lpWideCharStr, cchWideChar * sizeof(WCHAR));
if (STATUS_SOME_NOT_MAPPED == Result)
Result = STATUS_SUCCESS;
else if (!NT_SUCCESS(Result))
return 0;
*PResult = Result;
return ByteCount;
}
static inline int FspKuMultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCCH lpMultiByteStr,
int cbMultiByte,
LPWSTR lpWideCharStr,
int cchWideChar,
PNTSTATUS PResult)
{
ASSERT(CP_UTF8 == CodePage);
ASSERT(0 == dwFlags);
NTSTATUS Result;
ULONG ByteCount;
if (-1 == cbMultiByte)
cbMultiByte = (int)strlen(lpMultiByteStr) + 1;
Result = RtlUTF8ToUnicodeN(
lpWideCharStr, cchWideChar * sizeof(WCHAR), &ByteCount,
lpMultiByteStr, cbMultiByte);
if (STATUS_SOME_NOT_MAPPED == Result)
Result = STATUS_SUCCESS;
else if (!NT_SUCCESS(Result))
return 0;
*PResult = Result;
return ByteCount / sizeof(WCHAR);
}
static inline void *MemAlloc(size_t Size)
{
return FspAlloc(Size);
}
static inline void MemFree(void *Pointer)
{
if (0 != Pointer)
FspFree(Pointer);
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/** /**
* @file dll/posix.c * @file ku/posix.c
* POSIX Interop. * POSIX Interop.
* *
* This file provides routines for Windows/POSIX interoperability. It is based * This file provides routines for Windows/POSIX interoperability. It is based
@ -32,15 +32,67 @@
* associated repository. * associated repository.
*/ */
#include <dll/library.h> #include <ku/library.h>
#include <aclapi.h>
#define _NTDEF_
#include <ntsecapi.h>
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid);
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid);
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...); static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...);
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)());
FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor);
FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode);
FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
BOOLEAN Translate);
FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
BOOLEAN Translate);
FSP_API VOID FspPosixDeletePath(void *Path);
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT; #if defined(_KERNEL_MODE)
union #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspPosixMapUidToSid)
#pragma alloc_text(PAGE, FspPosixMapSidToUid)
#pragma alloc_text(PAGE, FspPosixCreateSid)
#pragma alloc_text(PAGE, FspDeleteSid)
#pragma alloc_text(PAGE, FspPosixMapPermissionsToSecurityDescriptor)
#pragma alloc_text(PAGE, FspPosixMapSecurityDescriptorToPermissions)
#pragma alloc_text(PAGE, FspPosixMapWindowsToPosixPathEx)
#pragma alloc_text(PAGE, FspPosixMapPosixToWindowsPathEx)
#pragma alloc_text(PAGE, FspPosixDeletePath)
#pragma alloc_text(PAGE, FspPosixEncodeWindowsPath)
#pragma alloc_text(PAGE, FspPosixDecodeWindowsPath)
#endif
#endif
static union
{
SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
} FspWorldSidBuf =
{
/* S-1-1-0 */
.V.Revision = SID_REVISION,
.V.SubAuthorityCount = 1,
.V.IdentifierAuthority.Value[5] = 1,
.V.SubAuthority[0] = 0,
};
static union
{
SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
} FspAuthUsersSidBuf =
{
/* S-1-5-11 */
.V.Revision = SID_REVISION,
.V.SubAuthorityCount = 1,
.V.IdentifierAuthority.Value[5] = 5,
.V.SubAuthority[0] = 11,
};
static union
{ {
SID V; SID V;
UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))]; UINT8 B[sizeof(SID) - sizeof(DWORD) + (1 * sizeof(DWORD))];
@ -52,11 +104,15 @@ union
.V.IdentifierAuthority.Value[5] = 0, .V.IdentifierAuthority.Value[5] = 0,
.V.SubAuthority[0] = 65534, .V.SubAuthority[0] = 65534,
}; };
static PISID FspAccountDomainSid, FspPrimaryDomainSid;
#define FspWorldSid (&FspWorldSidBuf.V)
#define FspAuthUsersSid (&FspAuthUsersSidBuf.V)
#define FspUnmappedSid (&FspUnmappedSidBuf.V) #define FspUnmappedSid (&FspUnmappedSidBuf.V)
#define FspUnmappedUid (65534) #define FspUnmappedUid (65534)
static PISID FspAccountDomainSid, FspPrimaryDomainSid;
static INIT_ONCE FspPosixInitOnce = INIT_ONCE_STATIC_INIT;
#if !defined(_KERNEL_MODE)
static BOOL WINAPI FspPosixInitialize( static BOOL WINAPI FspPosixInitialize(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
{ {
@ -120,9 +176,79 @@ VOID FspPosixFinalize(BOOLEAN Dynamic)
MemFree(FspPrimaryDomainSid); MemFree(FspPrimaryDomainSid);
} }
} }
#else
ULONG NTAPI FspPosixInitialize(
PRTL_RUN_ONCE RunOnce, PVOID Parameter, PVOID *Context)
{
static union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} FspAccountDomainSidBuf;
static union
{
SID V;
UINT8 B[SECURITY_MAX_SID_SIZE];
} FspPrimaryDomainSidBuf;
UNICODE_STRING Path;
UNICODE_STRING Name;
union
{
KEY_VALUE_PARTIAL_INFORMATION V;
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + SECURITY_MAX_SID_SIZE];
} Value;
ULONG Length;
NTSTATUS Result;
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\SECURITY\\Policy\\PolAcDmS");
RtlZeroMemory(&Name, sizeof Name);
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (NT_SUCCESS(Result) && REG_NONE == Value.V.Type &&
sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
{
RtlCopyMemory(&FspAccountDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
FspAccountDomainSid = &FspAccountDomainSidBuf.V;
}
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\SECURITY\\Policy\\PolPrDmS");
RtlZeroMemory(&Name, sizeof Name);
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (NT_SUCCESS(Result) && REG_NONE == Value.V.Type &&
sizeof(SID) <= Value.V.DataLength && RtlValidSid((PSID)&Value.V.Data))
{
RtlCopyMemory(&FspPrimaryDomainSidBuf.V, &Value.V.Data, Value.V.DataLength);
FspPrimaryDomainSid = &FspPrimaryDomainSidBuf.V;
}
return TRUE;
}
#endif
static inline BOOLEAN FspPosixIsRelativeSid(PISID Sid1, PISID Sid2)
{
if (Sid1->Revision != Sid2->Revision)
return FALSE;
if (Sid1->IdentifierAuthority.Value[0] != Sid2->IdentifierAuthority.Value[0] ||
Sid1->IdentifierAuthority.Value[1] != Sid2->IdentifierAuthority.Value[1] ||
Sid1->IdentifierAuthority.Value[2] != Sid2->IdentifierAuthority.Value[2] ||
Sid1->IdentifierAuthority.Value[3] != Sid2->IdentifierAuthority.Value[3] ||
Sid1->IdentifierAuthority.Value[4] != Sid2->IdentifierAuthority.Value[4] ||
Sid1->IdentifierAuthority.Value[5] != Sid2->IdentifierAuthority.Value[5])
return FALSE;
if (Sid1->SubAuthorityCount + 1 != Sid2->SubAuthorityCount)
return FALSE;
for (ULONG I = 0; Sid1->SubAuthorityCount > I; I++)
if (Sid1->SubAuthority[I] != Sid2->SubAuthority[I])
return FALSE;
return TRUE;
}
FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid) FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
{ {
FSP_KU_CODE;
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
*PSid = 0; *PSid = 0;
@ -221,7 +347,7 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
* S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y * S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y
*/ */
else if (0x10000 <= Uid && Uid < 0x11000) else if (0x10000 <= Uid && Uid < 0x11000)
*PSid = FspPosixCreateSid((Uid - 0x10000) >> 8, 1, (Uid - 0x10000) & 0xff); *PSid = FspPosixCreateSid((BYTE)((Uid - 0x10000) >> 8), 1, (Uid - 0x10000) & 0xff);
/* [IDMAP] /* [IDMAP]
* Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID): * Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID):
@ -238,13 +364,15 @@ FSP_API NTSTATUS FspPosixMapUidToSid(UINT32 Uid, PSID *PSid)
FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid) FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
{ {
FSP_KU_CODE;
InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0); InitOnceExecuteOnce(&FspPosixInitOnce, FspPosixInitialize, 0, 0);
BYTE Authority; BYTE Authority;
BYTE Count; BYTE Count;
UINT32 SubAuthority0, Rid; UINT32 SubAuthority0, Rid;
*PUid = -1; *PUid = (UINT32)-1;
if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid))) if (!IsValidSid(Sid) || 0 == (Count = *GetSidSubAuthorityCount(Sid)))
return STATUS_INVALID_SID; return STATUS_INVALID_SID;
@ -298,12 +426,11 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
* has PrimaryDomainSid == AccountDomainSid. * has PrimaryDomainSid == AccountDomainSid.
*/ */
BOOL EqualDomains = FALSE;
if (0 != FspPrimaryDomainSid && if (0 != FspPrimaryDomainSid &&
EqualDomainSid(FspPrimaryDomainSid, Sid, &EqualDomains) && EqualDomains) FspPosixIsRelativeSid(FspPrimaryDomainSid, Sid))
*PUid = 0x100000 + Rid; *PUid = 0x100000 + Rid;
else if (0 != FspAccountDomainSid && else if (0 != FspAccountDomainSid &&
EqualDomainSid(FspAccountDomainSid, Sid, &EqualDomains) && EqualDomains) FspPosixIsRelativeSid(FspAccountDomainSid, Sid))
*PUid = 0x30000 + Rid; *PUid = 0x30000 + Rid;
/* /*
@ -348,6 +475,8 @@ FSP_API NTSTATUS FspPosixMapSidToUid(PSID Sid, PUINT32 PUid)
static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...) static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
{ {
FSP_KU_CODE;
PISID Sid; PISID Sid;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority; SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
va_list ap; va_list ap;
@ -370,6 +499,8 @@ static PISID FspPosixCreateSid(BYTE Authority, ULONG Count, ...)
FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)()) FSP_API VOID FspDeleteSid(PSID Sid, NTSTATUS (*CreateFunc)())
{ {
FSP_KU_CODE;
if (FspUnmappedSid == Sid) if (FspUnmappedSid == Sid)
; ;
else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc) else if ((NTSTATUS (*)())FspPosixMapUidToSid == CreateFunc)
@ -439,7 +570,9 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
UINT32 Uid, UINT32 Gid, UINT32 Mode, UINT32 Uid, UINT32 Gid, UINT32 Mode,
PSECURITY_DESCRIPTOR *PSecurityDescriptor) PSECURITY_DESCRIPTOR *PSecurityDescriptor)
{ {
PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0; FSP_KU_CODE;
PSID OwnerSid = 0, GroupSid = 0;
UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm; UINT32 OwnerPerm, OwnerDeny, GroupPerm, GroupDeny, WorldPerm;
PACL Acl = 0; PACL Acl = 0;
SECURITY_DESCRIPTOR SecurityDescriptor; SECURITY_DESCRIPTOR SecurityDescriptor;
@ -457,13 +590,6 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
WorldSid = FspWksidGet(WinWorldSid);
if (0 == WorldSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
OwnerPerm = (Mode & 0700) >> 6; OwnerPerm = (Mode & 0700) >> 6;
GroupPerm = (Mode & 0070) >> 3; GroupPerm = (Mode & 0070) >> 3;
WorldPerm = (Mode & 0007); WorldPerm = (Mode & 0007);
@ -502,7 +628,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny); sizeof(ACCESS_DENIED_ACE) * (!!OwnerDeny + !!GroupDeny);
Size += GetLengthSid(OwnerSid) - sizeof(DWORD); Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
Size += GetLengthSid(GroupSid) - sizeof(DWORD); Size += GetLengthSid(GroupSid) - sizeof(DWORD);
Size += GetLengthSid(WorldSid) - sizeof(DWORD); Size += GetLengthSid(FspWorldSid) - sizeof(DWORD);
if (OwnerDeny) if (OwnerDeny)
Size += GetLengthSid(OwnerSid) - sizeof(DWORD); Size += GetLengthSid(OwnerSid) - sizeof(DWORD);
if (GroupDeny) if (GroupDeny)
@ -546,7 +672,7 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
if (!AddAccessAllowedAce(Acl, ACL_REVISION, if (!AddAccessAllowedAce(Acl, ACL_REVISION,
FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm), FspPosixDefaultPerm | FspPosixMapPermissionToAccessMask(Mode, WorldPerm),
WorldSid)) FspWorldSid))
goto lasterror; goto lasterror;
if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) if (!InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
@ -621,7 +747,9 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode) PUINT32 PUid, PUINT32 PGid, PUINT32 PMode)
{ {
PSID OwnerSid = 0, GroupSid = 0, WorldSid = 0, AuthUsersSid = 0; FSP_KU_CODE;
PSID OwnerSid = 0, GroupSid = 0;
BOOL Defaulted, DaclPresent; BOOL Defaulted, DaclPresent;
PACL Acl = 0; PACL Acl = 0;
ACL_SIZE_INFORMATION AclSizeInfo; ACL_SIZE_INFORMATION AclSizeInfo;
@ -653,20 +781,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
if (0 != Acl) if (0 != Acl)
{ {
WorldSid = FspWksidGet(WinWorldSid);
if (0 == WorldSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
if (0 == AuthUsersSid)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0; OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation)) if (!GetAclInformation(Acl, &AclSizeInfo, sizeof AclSizeInfo, AclSizeInformation))
@ -701,7 +815,7 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
* add the allowed or denied access right bits into the "owner", "group" * add the allowed or denied access right bits into the "owner", "group"
* and "other" collections. * and "other" collections.
*/ */
if (EqualSid(WorldSid, AceSid) || EqualSid(AuthUsersSid, AceSid)) if (EqualSid(FspWorldSid, AceSid) || EqualSid(FspAuthUsersSid, AceSid))
{ {
/* [PERMS] /* [PERMS]
* If this is an access-denied ACE, then add each access right to the set * If this is an access-denied ACE, then add each access right to the set
@ -812,6 +926,8 @@ static UINT32 FspPosixInvalidPathChars[4] =
FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath, FSP_API NTSTATUS FspPosixMapWindowsToPosixPathEx(PWSTR WindowsPath, char **PPosixPath,
BOOLEAN Translate) BOOLEAN Translate)
{ {
FSP_KU_CODE;
NTSTATUS Result; NTSTATUS Result;
ULONG Size; ULONG Size;
char *PosixPath = 0, *p, *q; char *PosixPath = 0, *p, *q;
@ -874,6 +990,8 @@ lasterror:
FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath, FSP_API NTSTATUS FspPosixMapPosixToWindowsPathEx(const char *PosixPath, PWSTR *PWindowsPath,
BOOLEAN Translate) BOOLEAN Translate)
{ {
FSP_KU_CODE;
NTSTATUS Result; NTSTATUS Result;
ULONG Size; ULONG Size;
PWSTR WindowsPath = 0, p; PWSTR WindowsPath = 0, p;
@ -925,11 +1043,15 @@ lasterror:
FSP_API VOID FspPosixDeletePath(void *Path) FSP_API VOID FspPosixDeletePath(void *Path)
{ {
FSP_KU_CODE;
MemFree(Path); MemFree(Path);
} }
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size) FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{ {
FSP_KU_CODE;
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{ {
WCHAR c = *p; WCHAR c = *p;
@ -944,6 +1066,8 @@ FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size)
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size) FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size)
{ {
FSP_KU_CODE;
for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++) for (PWSTR p = WindowsPath, endp = p + Size; endp > p; p++)
{ {
WCHAR c = *p; WCHAR c = *p;

View File

@ -503,24 +503,19 @@ static SVC_INSTANCE *SvcInstanceLookup(PWSTR ClassName, PWSTR InstanceName)
return 0; return 0;
} }
static ULONG SvcInstanceArgumentLength(PWSTR Arg) static inline ULONG SvcInstanceArgumentLength(PWSTR Arg, PWSTR Pattern)
{ {
ULONG Length; PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern);
Length = 2; /* for beginning and ending quotes */ return 2 + (ULONG)(UINT_PTR)PathTransform(0, Arg, Pattern);
for (PWSTR P = Arg; *P; P++)
if (L'"' != *P)
Length++;
return Length;
} }
static PWSTR SvcInstanceArgumentCopy(PWSTR Dest, PWSTR Arg) static inline PWSTR SvcInstanceArgumentCopy(PWSTR Dest, PWSTR Arg, PWSTR Pattern)
{ {
PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern);
*Dest++ = L'"'; *Dest++ = L'"';
for (PWSTR P = Arg; *P; P++) Dest = PathTransform(Dest, Arg, Pattern);
if (L'"' != *P)
*Dest++ = *P;
*Dest++ = L'"'; *Dest++ = L'"';
return Dest; return Dest;
@ -532,6 +527,7 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
PWSTR NewString = 0, P, Q; PWSTR NewString = 0, P, Q;
PWSTR EmptyArg = L""; PWSTR EmptyArg = L"";
ULONG Length; ULONG Length;
PWSTR Pattern;
*PNewString = 0; *PNewString = 0;
@ -541,24 +537,36 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
switch (*P) switch (*P)
{ {
case L'%': case L'%':
Pattern = 0;
P++; P++;
if (L'\\' == *P)
{
Pattern = ++P;
while (!(L'\0' == *P ||
(L'0' <= *P && *P <= '9') ||
(L'A' <= *P && *P <= 'Z')))
P++;
}
if (L'0' <= *P && *P <= '9') if (L'0' <= *P && *P <= '9')
{ {
if (Argc > (ULONG)(*P - L'0')) if (Argc > (ULONG)(*P - L'0'))
Length += SvcInstanceArgumentLength(Argv[*P - L'0']); Length += SvcInstanceArgumentLength(Argv[*P - L'0'], Pattern);
else else
Length += SvcInstanceArgumentLength(EmptyArg); Length += SvcInstanceArgumentLength(EmptyArg, 0);
} }
else else
if (L'U' == *P) if (L'U' == *P)
{ {
if (0 != SvcInstanceUserName()) if (0 != SvcInstanceUserName())
Length += SvcInstanceArgumentLength(SvcInstanceUserName()); Length += SvcInstanceArgumentLength(SvcInstanceUserName(), Pattern);
else else
Length += SvcInstanceArgumentLength(EmptyArg); Length += SvcInstanceArgumentLength(EmptyArg, 0);
} }
else else
if (*P)
Length++; Length++;
else
P--;
break; break;
default: default:
Length++; Length++;
@ -575,24 +583,36 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
switch (*P) switch (*P)
{ {
case L'%': case L'%':
Pattern = 0;
P++; P++;
if (L'\\' == *P)
{
Pattern = ++P;
while (!(L'\0' == *P ||
(L'0' <= *P && *P <= '9') ||
(L'A' <= *P && *P <= 'Z')))
P++;
}
if (L'0' <= *P && *P <= '9') if (L'0' <= *P && *P <= '9')
{ {
if (Argc > (ULONG)(*P - L'0')) if (Argc > (ULONG)(*P - L'0'))
Q = SvcInstanceArgumentCopy(Q, Argv[*P - L'0']); Q = SvcInstanceArgumentCopy(Q, Argv[*P - L'0'], Pattern);
else else
Q = SvcInstanceArgumentCopy(Q, EmptyArg); Q = SvcInstanceArgumentCopy(Q, EmptyArg, 0);
} }
else else
if (L'U' == *P) if (L'U' == *P)
{ {
if (0 != SvcInstanceUserName()) if (0 != SvcInstanceUserName())
Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName()); Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName(), Pattern);
else else
Q = SvcInstanceArgumentCopy(Q, EmptyArg); Q = SvcInstanceArgumentCopy(Q, EmptyArg, 0);
} }
else else
if (*P)
*Q++ = *P; *Q++ = *P;
else
P--;
break; break;
default: default:
*Q++ = *P; *Q++ = *P;

182
src/launcher/ptrans.c Normal file
View File

@ -0,0 +1,182 @@
/**
* @file launcher/ptrans.c
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
/**
* Path Transformation Language
*
* Syntax:
* PERCENT BACKLASH replace-sep *(*sep component) [*sep UNDERSCORE] arg
*
* Arg:
* The command line argument that a rule is applied on. These are denoted
* by digits [0-9] or a capital letter (A-Z).
*
* Component:
* A path component denoted by a small letter (a-z). The letter a denotes
* the first path component, the letter b the second path component, etc.
*
* UNDERSCORE:
* The UNDERSCORE (_) denotes the "rest of the path". This is any path
* left after any path components explicitly mentioned by using small
* letters (a-z).
*
* Sep:
* A separator symbol that is used to separated components.
* E.g. slash (/), colon (:), etc.
*
* Replace-sep:
* A separator symbol that replaces the backslash (\) separator in the
* "rest of the path" (UNDERSCORE). E.g. slash (/), colon (:), etc.
*
*
* Examples:
* - %\/b:_1
* - Transforms \rclone\REMOTE\PATH\TO\FILES to REMOTE:PATH/TO/FILES
* - %\/b:/_1
* - Transforms \rclone\REMOTE\PATH\TO\FILES to REMOTE:/PATH/TO/FILES
* - %\/_1
* - Transforms \P1\P2\P3 to /P1/P2/P3
* - %\+_1
* - Transforms \P1\P2\P3 to +P1+P2+P3
* - %\\_1
* - Transforms \P1\P2\P3 to \\P1\\P2\\P3
* (Backslash is doubled up when used as a replacement separator!)
*/
#include <winfsp/launch.h>
#include <shared/minimal.h>
static PWSTR PathCopy(PWSTR Dest, PWSTR Arg, PWSTR ArgEnd, BOOLEAN WriteDest, WCHAR Replacement)
{
if (0 != Replacement)
{
for (PWSTR P = Arg, EndP = (0 != ArgEnd ? ArgEnd : (PWSTR)(UINT_PTR)~0); EndP > P && *P; P++)
if (L'\\' == *P)
{
if (L'\\' == Replacement)
{
if (WriteDest)
*Dest = Replacement;
Dest++;
}
if (WriteDest)
*Dest = Replacement;
Dest++;
}
else if (L'"' != *P)
{
if (WriteDest)
*Dest = *P;
Dest++;
}
}
else
{
for (PWSTR P = Arg, EndP = (0 != ArgEnd ? ArgEnd : (PWSTR)(UINT_PTR)~0); EndP > P && *P; P++)
if (L'"' != *P)
{
if (WriteDest)
*Dest = *P;
Dest++;
}
}
return Dest;
}
static inline BOOLEAN PatternEnd(WCHAR C)
{
return L'\0' == C ||
(L'0' <= C && C <= '9') ||
(L'A' <= C && C <= 'Z');
}
PWSTR PathTransform(PWSTR Dest, PWSTR Arg, PWSTR Pattern)
{
BOOLEAN WriteDest = 0 != Dest;
WCHAR Replacement;
PWSTR Components[26][2];
PWSTR Remainder = Arg;
ULONG RemainderIndex = 0;
PWSTR P;
if (0 == Pattern)
return PathCopy(Dest, Arg, 0, WriteDest, 0);
for (ULONG I = 0; 26 > I; I++)
Components[I][0] = 0;
Replacement = *Pattern++;
if (PatternEnd(Replacement))
return Dest;
while (!PatternEnd(*Pattern))
{
if (L'a' <= *Pattern && *Pattern <= 'z')
{
ULONG I = *Pattern - 'a', J;
if (0 == Components[I][0])
{
P = Remainder;
J = RemainderIndex;
while (L'\\' == *P)
P++;
for (;;)
{
Components[J][0] = P;
while (*P && L'\\' != *P)
P++;
Components[J][1] = P;
while (L'\\' == *P)
P++;
if (I == J)
{
Remainder = P;
RemainderIndex = I + 1;
break;
}
J++;
}
}
Dest = PathCopy(Dest, Components[I][0], Components[I][1], WriteDest, Replacement);
}
else
if (L'_' == *Pattern)
Dest = PathCopy(Dest, Remainder, 0, WriteDest, Replacement);
else
{
if (WriteDest)
*Dest = *Pattern;
Dest++;
}
Pattern++;
}
return Dest;
}

View File

@ -72,6 +72,7 @@ NTSYSAPI VOID NTAPI RtlMoveMemory(VOID *Destination, CONST VOID *Source, DWORD L
#pragma function(memset) #pragma function(memset)
#pragma function(memcpy) #pragma function(memcpy)
#pragma function(memmove)
static inline static inline
void *memset(void *dst, int val, size_t siz) void *memset(void *dst, int val, size_t siz)
{ {

View File

@ -29,7 +29,7 @@ static NTSTATUS FspFsvolCreate(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolCreateNoLock( static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen); BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp);
FSP_IOPREP_DISPATCH FspFsvolCreatePrepare; FSP_IOPREP_DISPATCH FspFsvolCreatePrepare;
FSP_IOCMPL_DISPATCH FspFsvolCreateComplete; FSP_IOCMPL_DISPATCH FspFsvolCreateComplete;
static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response, static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response,
@ -144,6 +144,7 @@ static NTSTATUS FspFsvolCreate(
PECP_LIST ExtraCreateParameters; PECP_LIST ExtraCreateParameters;
PVOID ExtraCreateParameter; PVOID ExtraCreateParameter;
BOOLEAN MainFileOpen = FALSE; BOOLEAN MainFileOpen = FALSE;
PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp = 0;
/* /*
* Check if the IRP has ECP's. * Check if the IRP has ECP's.
@ -219,6 +220,21 @@ static NTSTATUS FspFsvolCreate(
} }
} }
#endif #endif
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures)
{
// {4720bd83-52ac-4104-a130-d1ec6a8cc8e5}
static const GUID FspAtomicCreateEcpGuid =
{ 0x4720bd83, 0x52ac, 0x4104, { 0xa1, 0x30, 0xd1, 0xec, 0x6a, 0x8c, 0xc8, 0xe5 } };
ExtraCreateParameter = 0;
AtomicCreateEcp =
NT_SUCCESS(FsRtlFindExtraCreateParameter(ExtraCreateParameters,
&FspAtomicCreateEcpGuid, &ExtraCreateParameter, 0)) &&
0 != ExtraCreateParameter &&
!FsRtlIsEcpFromUserMode(ExtraCreateParameter) ?
ExtraCreateParameter : 0;
}
} }
if (!MainFileOpen) if (!MainFileOpen)
@ -226,7 +242,8 @@ static NTSTATUS FspFsvolCreate(
FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject); FspFsvolDeviceFileRenameAcquireShared(FsvolDeviceObject);
try try
{ {
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, FALSE); Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp,
MainFileOpen, AtomicCreateEcp);
} }
finally finally
{ {
@ -235,14 +252,15 @@ static NTSTATUS FspFsvolCreate(
} }
} }
else else
Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp, TRUE); Result = FspFsvolCreateNoLock(FsvolDeviceObject, Irp, IrpSp,
MainFileOpen, AtomicCreateEcp);
return Result; return Result;
} }
static NTSTATUS FspFsvolCreateNoLock( static NTSTATUS FspFsvolCreateNoLock(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
BOOLEAN MainFileOpen) BOOLEAN MainFileOpen, PFSP_ATOMIC_CREATE_ECP_CONTEXT AtomicCreateEcp)
{ {
PAGED_CODE(); PAGED_CODE();
@ -279,6 +297,8 @@ static NTSTATUS FspFsvolCreateNoLock(
USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess;
PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG EaLength = IrpSp->Parameters.Create.EaLength; ULONG EaLength = IrpSp->Parameters.Create.EaLength;
PVOID ExtraBuffer = 0;
ULONG ExtraLength = 0;
ULONG Flags = IrpSp->Flags; ULONG Flags = IrpSp->Flags;
KPROCESSOR_MODE RequestorMode = KPROCESSOR_MODE RequestorMode =
FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode; FlagOn(Flags, SL_FORCE_ACCESS_CHECK) ? UserMode : Irp->RequestorMode;
@ -292,6 +312,7 @@ static NTSTATUS FspFsvolCreateNoLock(
BOOLEAN HasRestorePrivilege = BOOLEAN HasRestorePrivilege =
BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE); BooleanFlagOn(AccessState->Flags, TOKEN_HAS_RESTORE_PRIVILEGE);
BOOLEAN HasTrailingBackslash = FALSE; BOOLEAN HasTrailingBackslash = FALSE;
BOOLEAN EaIsReparsePoint = FALSE;
FSP_FILE_NODE *FileNode, *RelatedFileNode; FSP_FILE_NODE *FileNode, *RelatedFileNode;
FSP_FILE_DESC *FileDesc; FSP_FILE_DESC *FileDesc;
UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 }; UNICODE_STRING MainFileName = { 0 }, StreamPart = { 0 };
@ -302,6 +323,36 @@ static NTSTATUS FspFsvolCreateNoLock(
if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID)) if (FlagOn(CreateOptions, FILE_OPEN_BY_FILE_ID))
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
/* is there an AtomicCreateEcp attached? */
if (0 != AtomicCreateEcp)
{
if ((FILE_CREATE != CreateDisposition && FILE_OPEN_IF != CreateDisposition) ||
0 != EaBuffer ||
RTL_SIZEOF_THROUGH_FIELD(FSP_ATOMIC_CREATE_ECP_CONTEXT, ReparseBuffer) >
AtomicCreateEcp->Size ||
/* !!!: revisit: FlagOn*/
!FlagOn(AtomicCreateEcp->InFlags,
ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT |
ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED))
return STATUS_INVALID_PARAMETER; /* docs do not say what to return on failure! */
if (FlagOn(AtomicCreateEcp->InFlags,
ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED))
{
Result = FsRtlValidateReparsePointBuffer(AtomicCreateEcp->ReparseBufferLength,
AtomicCreateEcp->ReparseBuffer);
if (!NT_SUCCESS(Result))
return Result;
/* mark that we satisfied the reparse point request, although we may fail it later! */
AtomicCreateEcp->OutFlags = ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET;
ExtraBuffer = AtomicCreateEcp->ReparseBuffer;
ExtraLength = AtomicCreateEcp->ReparseBufferLength;
EaIsReparsePoint = TRUE;
}
}
/* was an EA buffer specified? */ /* was an EA buffer specified? */
if (0 != EaBuffer) if (0 != EaBuffer)
{ {
@ -318,6 +369,9 @@ static NTSTATUS FspFsvolCreateNoLock(
EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information); EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
return Result; return Result;
ExtraBuffer = EaBuffer;
ExtraLength = EaLength;
} }
/* cannot open a paging file */ /* cannot open a paging file */
@ -555,9 +609,9 @@ static NTSTATUS FspFsvolCreateNoLock(
SecurityDescriptorSize = 0; SecurityDescriptorSize = 0;
FileAttributes = 0; FileAttributes = 0;
/* cannot set EA on named stream */ /* cannot set extra buffer on named stream */
EaBuffer = 0; ExtraBuffer = 0;
EaLength = 0; ExtraLength = 0;
/* remember the main file node */ /* remember the main file node */
ASSERT(0 == FileNode->MainFileNode); ASSERT(0 == FileNode->MainFileNode);
@ -577,8 +631,8 @@ static NTSTATUS FspFsvolCreateNoLock(
/* create the user-mode file system request */ /* create the user-mode file system request */
Result = FspIopCreateRequestEx(Irp, &FileNode->FileName, Result = FspIopCreateRequestEx(Irp, &FileNode->FileName,
0 != EaBuffer ? 0 != ExtraBuffer ?
FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + EaLength : SecurityDescriptorSize, FSP_FSCTL_DEFAULT_ALIGN_UP(SecurityDescriptorSize) + ExtraLength : SecurityDescriptorSize,
FspFsvolCreateRequestFini, &Request); FspFsvolCreateRequestFini, &Request);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
@ -616,10 +670,10 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.DesiredAccess = DesiredAccess; Request->Req.Create.DesiredAccess = DesiredAccess;
Request->Req.Create.GrantedAccess = GrantedAccess; Request->Req.Create.GrantedAccess = GrantedAccess;
Request->Req.Create.ShareAccess = ShareAccess; Request->Req.Create.ShareAccess = ShareAccess;
Request->Req.Create.Ea.Offset = 0 != EaBuffer ? Request->Req.Create.Ea.Offset = 0 != ExtraBuffer ?
(0 != Request->Req.Create.SecurityDescriptor.Offset ? (0 != Request->Req.Create.SecurityDescriptor.Offset ?
NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0; NEXTOFS(Request->Req.Create.SecurityDescriptor) : NEXTOFS(Request->FileName)) : 0;
Request->Req.Create.Ea.Size = 0 != EaBuffer ? (UINT16)EaLength : 0; Request->Req.Create.Ea.Size = 0 != ExtraBuffer ? (UINT16)ExtraLength : 0;
Request->Req.Create.UserMode = UserMode == RequestorMode; Request->Req.Create.UserMode = UserMode == RequestorMode;
Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege; Request->Req.Create.HasTraversePrivilege = HasTraversePrivilege;
Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege; Request->Req.Create.HasBackupPrivilege = HasBackupPrivilege;
@ -628,10 +682,10 @@ static NTSTATUS FspFsvolCreateNoLock(
Request->Req.Create.CaseSensitive = CaseSensitive; Request->Req.Create.CaseSensitive = CaseSensitive;
Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash; Request->Req.Create.HasTrailingBackslash = HasTrailingBackslash;
Request->Req.Create.NamedStream = MainFileName.Length; Request->Req.Create.NamedStream = MainFileName.Length;
#undef NEXTOFS
Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream && Request->Req.Create.AcceptsSecurityDescriptor = 0 == Request->Req.Create.NamedStream &&
!!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode; !!FsvolDeviceExtension->VolumeParams.AllowOpenInKernelMode;
Request->Req.Create.EaIsReparsePoint = EaIsReparsePoint;
#undef NEXTOFS
ASSERT( ASSERT(
0 == StreamPart.Length && 0 == MainFileName.Length || 0 == StreamPart.Length && 0 == MainFileName.Length ||
@ -642,10 +696,10 @@ static NTSTATUS FspFsvolCreateNoLock(
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
SecurityDescriptor, SecurityDescriptorSize); SecurityDescriptor, SecurityDescriptorSize);
/* copy the EA buffer (if any) into the request */ /* copy the extra buffer (if any) into the request */
if (0 != EaBuffer) if (0 != ExtraBuffer)
RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset, RtlCopyMemory(Request->Buffer + Request->Req.Create.Ea.Offset,
EaBuffer, EaLength); ExtraBuffer, ExtraLength);
/* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */ /* fix FileNode->FileName if we are doing SL_OPEN_TARGET_DIRECTORY */
if (Request->Req.Create.OpenTargetDirectory) if (Request->Req.Create.OpenTargetDirectory)

View File

@ -252,6 +252,8 @@ const char *FileInformationClassSym(FILE_INFORMATION_CLASS FileInformationClass)
SYM(FileReplaceCompletionInformation) SYM(FileReplaceCompletionInformation)
SYM(FileHardLinkFullIdInformation) SYM(FileHardLinkFullIdInformation)
SYM(FileIdExtdBothDirectoryInformation) SYM(FileIdExtdBothDirectoryInformation)
case 68: return "FileStatInformation";
case 70: return "FileStatLxInformation";
default: default:
return "FILE_INFORMATION_CLASS:Unknown"; return "FILE_INFORMATION_CLASS:Unknown";
} }

View File

@ -325,6 +325,22 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
* to track what has been initialized! * to track what has been initialized!
*/ */
/* initialize any fsext provider */
if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode)
{
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider)
{
Result = Provider->DeviceInit(DeviceObject, &FsvolDeviceExtension->VolumeParams);
if (!NT_SUCCESS(Result))
return Result;
FsvolDeviceExtension->InitDoneFsext = 1;
}
else
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* is there a virtual disk? */ /* is there a virtual disk? */
if (0 != FsvolDeviceExtension->FsvrtDeviceObject) if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
{ {
@ -500,6 +516,15 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
if (0 != FsvolDeviceExtension->SwapVpb) if (0 != FsvolDeviceExtension->SwapVpb)
FspFreeExternal(FsvolDeviceExtension->SwapVpb); FspFreeExternal(FsvolDeviceExtension->SwapVpb);
} }
/* finalize any fsext provider */
if (FsvolDeviceExtension->InitDoneFsext)
{
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider)
Provider->DeviceFini(DeviceObject);
}
} }
static VOID FspFsvolDeviceTimerRoutine(PDEVICE_OBJECT DeviceObject, PVOID Context) static VOID FspFsvolDeviceTimerRoutine(PDEVICE_OBJECT DeviceObject, PVOID Context)
@ -546,6 +571,14 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
FspMetaCacheInvalidateExpired(FsvolDeviceExtension->SecurityCache, InterruptTime); FspMetaCacheInvalidateExpired(FsvolDeviceExtension->SecurityCache, InterruptTime);
FspMetaCacheInvalidateExpired(FsvolDeviceExtension->DirInfoCache, InterruptTime); FspMetaCacheInvalidateExpired(FsvolDeviceExtension->DirInfoCache, InterruptTime);
FspMetaCacheInvalidateExpired(FsvolDeviceExtension->StreamInfoCache, InterruptTime); FspMetaCacheInvalidateExpired(FsvolDeviceExtension->StreamInfoCache, InterruptTime);
/* run any fsext provider expiration routine */
if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode)
{
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider)
Provider->DeviceExpirationRoutine(DeviceObject, InterruptTime);
}
FspIoqRemoveExpired(FsvolDeviceExtension->Ioq, InterruptTime); FspIoqRemoveExpired(FsvolDeviceExtension->Ioq, InterruptTime);
KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql); KeAcquireSpinLock(&FsvolDeviceExtension->ExpirationLock, &Irql);

View File

@ -29,6 +29,7 @@
#include <ntstrsafe.h> #include <ntstrsafe.h>
#include <wdmsec.h> #include <wdmsec.h>
#include <winfsp/fsctl.h> #include <winfsp/fsctl.h>
#include <winfsp/fsext.h>
/* disable warnings */ /* disable warnings */
#pragma warning(disable:4100) /* unreferenced formal parameter */ #pragma warning(disable:4100) /* unreferenced formal parameter */
@ -36,6 +37,12 @@
#define DRIVER_NAME FSP_FSCTL_DRIVER_NAME #define DRIVER_NAME FSP_FSCTL_DRIVER_NAME
#if _WIN64
#define FSP_REGKEY "\\Registry\\Machine\\Software\\WOW6432Node\\WinFsp"
#else
#define FSP_REGKEY "\\Registry\\Machine\\Software\\WinFsp"
#endif
/* IoCreateDeviceSecure default SDDL's */ /* IoCreateDeviceSecure default SDDL's */
#define FSP_FSCTL_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)" #define FSP_FSCTL_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)"
/* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */ /* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */
@ -492,8 +499,17 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize);
NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength);
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress, ULONG ExtraPriorityFlags);
@ -1048,7 +1064,8 @@ typedef struct
{ {
FSP_DEVICE_EXTENSION Base; FSP_DEVICE_EXTENSION Base;
UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1, InitDoneEa:1, UINT32 InitDoneFsvrt:1, InitDoneIoq:1, InitDoneSec:1, InitDoneDir:1, InitDoneStrm:1, InitDoneEa:1,
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1; InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1,
InitDoneFsext;
PDEVICE_OBJECT FsctlDeviceObject; PDEVICE_OBJECT FsctlDeviceObject;
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject;
@ -1078,6 +1095,7 @@ typedef struct
PNOTIFY_SYNC NotifySync; PNOTIFY_SYNC NotifySync;
LIST_ENTRY NotifyList; LIST_ENTRY NotifyList;
FSP_STATISTICS *Statistics; FSP_STATISTICS *Statistics;
FSP_FSCTL_DECLSPEC_ALIGN UINT8 FsextData[];
} FSP_FSVOL_DEVICE_EXTENSION; } FSP_FSVOL_DEVICE_EXTENSION;
typedef struct typedef struct
{ {
@ -1169,6 +1187,9 @@ VOID FspDeviceGlobalUnlock(VOID)
//(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\ //(FILE_DEVICE_DISK_FILE_SYSTEM == (DeviceObject)->DeviceType ?\
// STATUS_VOLUME_DISMOUNTED : STATUS_DEVICE_NOT_CONNECTED) // STATUS_VOLUME_DISMOUNTED : STATUS_DEVICE_NOT_CONNECTED)
/* fsext */
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadResult);
/* process buffers conditional usage */ /* process buffers conditional usage */
static inline static inline
BOOLEAN FspReadIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize) BOOLEAN FspReadIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
@ -1209,7 +1230,6 @@ NTSTATUS FspMupHandleIrp(
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp); PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp);
/* volume management */ /* volume management */
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
NTSTATUS FspVolumeCreate( NTSTATUS FspVolumeCreate(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
VOID FspVolumeDelete( VOID FspVolumeDelete(
@ -1222,6 +1242,8 @@ NTSTATUS FspVolumeGetNameList(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeTransact( NTSTATUS FspVolumeTransact(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeTransactFsext(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeStop( NTSTATUS FspVolumeStop(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeWork( NTSTATUS FspVolumeWork(
@ -1571,7 +1593,7 @@ NTSTATUS FspFileNodeOplockCheckAsyncEx(
CompletionRoutine, CompletionRoutine,
PostIrpRoutine); PostIrpRoutine);
#if DBG #if DBG
if (STATUS_SUCCESS == Result && DEBUGTEST(10)) if (DEBUGTEST_EX(STATUS_SUCCESS == Result, 10, FALSE))
{ {
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -1636,4 +1658,74 @@ LOGICAL RtlEqualMemory(const VOID *Source1, const VOID *Source2, SIZE_T Length)
return Length == RtlCompareMemory(Source1, Source2, Length); return Length == RtlCompareMemory(Source1, Source2, Length);
} }
/* FILE_STAT_INFORMATION and FILE_STAT_LX_INFORMATION are missings on some WDK's. */
typedef struct
{
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ACCESS_MASK EffectiveAccess;
} FSP_FILE_STAT_INFORMATION, *PFSP_FILE_STAT_INFORMATION;
typedef struct
{
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ACCESS_MASK EffectiveAccess;
ULONG LxFlags;
ULONG LxUid;
ULONG LxGid;
ULONG LxMode;
ULONG LxDeviceIdMajor;
ULONG LxDeviceIdMinor;
} FSP_FILE_STAT_LX_INFORMATION, *PFSP_FILE_STAT_LX_INFORMATION;
/* ATOMIC_CREATE_ECP_CONTEXT is missing on some WDK's */
#define ATOMIC_CREATE_ECP_IN_FLAG_REPARSE_POINT_SPECIFIED 0x0002
#define ATOMIC_CREATE_ECP_OUT_FLAG_REPARSE_POINT_SET 0x0002
#define ATOMIC_CREATE_ECP_IN_FLAG_BEST_EFFORT 0x0100
typedef struct
{
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
} FSP_FILE_TIMESTAMPS, *PFSP_FILE_TIMESTAMPS;
typedef struct
{
USHORT Size;
USHORT InFlags;
USHORT OutFlags;
USHORT ReparseBufferLength;
PREPARSE_DATA_BUFFER ReparseBuffer;
LONGLONG FileSize;
LONGLONG ValidDataLength;
PFSP_FILE_TIMESTAMPS FileTimestamps;
ULONG FileAttributes;
ULONG UsnSourceInfo;
USN Usn;
ULONG SuppressFileAttributeInheritanceMask;
ULONG InOpFlags;
ULONG OutOpFlags;
ULONG InGenFlags;
ULONG OutGenFlags;
ULONG CaseSensitiveFlagsMask;
ULONG InCaseSensitiveFlags;
ULONG OutCaseSensitiveFlags;
} FSP_ATOMIC_CREATE_ECP_CONTEXT, *PFSP_ATOMIC_CREATE_ECP_CONTEXT;
#endif #endif

View File

@ -55,6 +55,7 @@ FSP_DRIVER_DISPATCH FspSetEa;
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFsvolQueryEaGetCopy) #pragma alloc_text(PAGE, FspFsvolQueryEaGetCopy)
#pragma alloc_text(PAGE, FspFsvolQueryEaIndexCopy) #pragma alloc_text(PAGE, FspFsvolQueryEaIndexCopy)
#pragma alloc_text(PAGE, FspFsvolQueryEaCopy)
#pragma alloc_text(PAGE, FspFsvolQueryEa) #pragma alloc_text(PAGE, FspFsvolQueryEa)
#pragma alloc_text(PAGE, FspFsvolQueryEaComplete) #pragma alloc_text(PAGE, FspFsvolQueryEaComplete)
#pragma alloc_text(PAGE, FspFsvolQueryEaRequestFini) #pragma alloc_text(PAGE, FspFsvolQueryEaRequestFini)

View File

@ -45,6 +45,15 @@ static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject,
static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd, PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo); const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatLxBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo);
static NTSTATUS FspFsvolQueryStatLxEaInformation(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd);
static NTSTATUS FspFsvolQueryStreamInformationCopy( static NTSTATUS FspFsvolQueryStreamInformationCopy(
FSP_FSCTL_STREAM_INFO *StreamInfoBuffer, ULONG StreamInfoBufferSize, FSP_FSCTL_STREAM_INFO *StreamInfoBuffer, ULONG StreamInfoBufferSize,
PVOID DestBuf, PULONG PDestLen); PVOID DestBuf, PULONG PDestLen);
@ -52,6 +61,9 @@ static NTSTATUS FspFsvolQueryStreamInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
static NTSTATUS FspFsvolQueryStreamInformationSuccess( static NTSTATUS FspFsvolQueryStreamInformationSuccess(
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response);
static NTSTATUS FspFsvolQueryInformationEffectiveAccess(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PACCESS_MASK PEffectiveAccess);
static NTSTATUS FspFsvolQueryInformation( static NTSTATUS FspFsvolQueryInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete; FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete;
@ -97,9 +109,13 @@ FAST_IO_QUERY_OPEN FspFastIoQueryOpen;
#pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation) #pragma alloc_text(PAGE, FspFsvolQueryNetworkOpenInformation)
#pragma alloc_text(PAGE, FspFsvolQueryPositionInformation) #pragma alloc_text(PAGE, FspFsvolQueryPositionInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStandardInformation) #pragma alloc_text(PAGE, FspFsvolQueryStandardInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatBaseInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatLxBaseInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStatLxEaInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationCopy) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformationCopy)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformation) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformation)
#pragma alloc_text(PAGE, FspFsvolQueryStreamInformationSuccess) #pragma alloc_text(PAGE, FspFsvolQueryStreamInformationSuccess)
#pragma alloc_text(PAGE, FspFsvolQueryInformationEffectiveAccess)
#pragma alloc_text(PAGE, FspFsvolQueryInformation) #pragma alloc_text(PAGE, FspFsvolQueryInformation)
#pragma alloc_text(PAGE, FspFsvolQueryInformationComplete) #pragma alloc_text(PAGE, FspFsvolQueryInformationComplete)
#pragma alloc_text(PAGE, FspFsvolQueryInformationRequestFini) #pragma alloc_text(PAGE, FspFsvolQueryInformationRequestFini)
@ -301,7 +317,7 @@ static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject,
PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FileNode->FsvolDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
if ((PVOID)(Info + 1) > BufferEnd) if ((PVOID)((PUINT8)Info + FIELD_OFFSET(FILE_NAME_INFORMATION, FileName)) > BufferEnd)
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
FspFileNodeAcquireShared(FileNode, Main); FspFileNodeAcquireShared(FileNode, Main);
@ -417,6 +433,187 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static NTSTATUS FspFsvolQueryStatBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo)
{
PAGED_CODE();
PFSP_FILE_STAT_INFORMATION Info = (PFSP_FILE_STAT_INFORMATION)*PBuffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
if (0 == FileInfo)
{
if ((PVOID)(Info + 1) > BufferEnd)
return STATUS_BUFFER_TOO_SMALL;
return STATUS_SUCCESS;
}
Info->FileId.QuadPart = FileNode->IndexNumber;
Info->CreationTime.QuadPart = FileInfo->CreationTime;
Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime;
Info->LastWriteTime.QuadPart = FileInfo->LastWriteTime;
Info->ChangeTime.QuadPart = FileInfo->ChangeTime;
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
Info->EndOfFile.QuadPart = FileInfo->FileSize;
Info->FileAttributes = 0 != FileInfo->FileAttributes ?
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
Info->ReparseTag = FileInfo->ReparseTag;
Info->NumberOfLinks = 1;
*PBuffer = (PVOID)(Info + 1);
return STATUS_SUCCESS;
}
static NTSTATUS FspFsvolQueryStatLxBaseInformation(PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd,
const FSP_FSCTL_FILE_INFO *FileInfo)
{
PAGED_CODE();
PFSP_FILE_STAT_LX_INFORMATION Info = (PFSP_FILE_STAT_LX_INFORMATION)*PBuffer;
FSP_FILE_NODE *FileNode = FileObject->FsContext;
if (0 == FileInfo)
{
if ((PVOID)(Info + 1) > BufferEnd)
return STATUS_BUFFER_TOO_SMALL;
return STATUS_SUCCESS;
}
Info->FileId.QuadPart = FileNode->IndexNumber;
Info->CreationTime.QuadPart = FileInfo->CreationTime;
Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime;
Info->LastWriteTime.QuadPart = FileInfo->LastWriteTime;
Info->ChangeTime.QuadPart = FileInfo->ChangeTime;
Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
Info->EndOfFile.QuadPart = FileInfo->FileSize;
Info->FileAttributes = 0 != FileInfo->FileAttributes ?
FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL;
Info->ReparseTag = FileInfo->ReparseTag;
Info->NumberOfLinks = 1;
*PBuffer = (PVOID)(Info + 1);
return STATUS_SUCCESS;
}
static NTSTATUS FspFsvolQueryStatLxEaInformation(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PVOID *PBuffer, PVOID BufferEnd)
{
#define ADD_GET_EA(Name, End) \
GetEa->NextEntryOffset = (ULONG)(End ? 0 :\
FSP_FSCTL_ALIGN_UP( \
FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + sizeof("" Name),\
sizeof(ULONG))); \
GetEa->EaNameLength = (UCHAR)(sizeof("" Name) - 1);\
RtlCopyMemory(GetEa->EaName, "" Name, sizeof("" Name));\
GetEaLength = (ULONG)((PUINT8)GetEa - (PUINT8)&GetEaBuf.V +\
FIELD_OFFSET(FILE_GET_EA_INFORMATION, EaName) + sizeof("" Name));\
GetEa = (PVOID)((PUINT8)GetEa + GetEa->NextEntryOffset);
#define EQUAL_EA_NAME(Name) \
CmpName.Length = \
CmpName.MaximumLength = sizeof("" Name) - 1,\
CmpName.Buffer = "" Name, \
RtlEqualString(&CmpName, &EaName, TRUE/* always case-insensitive */)
PAGED_CODE();
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
PFSP_FILE_STAT_LX_INFORMATION Info = (PFSP_FILE_STAT_LX_INFORMATION)*PBuffer;
union
{
FILE_GET_EA_INFORMATION V;
UINT8 B[64];
} GetEaBuf;
PFILE_GET_EA_INFORMATION GetEa = &GetEaBuf.V;
ULONG GetEaLength = 0;
union
{
FILE_FULL_EA_INFORMATION V;
UINT8 B[128];
} EaBuf;
ULONG EaLength = sizeof EaBuf;
STRING EaName, CmpName;
NTSTATUS Result;
Info->LxFlags = 0;
Info->LxUid = 0;
Info->LxGid = 0;
Info->LxMode = 0;
Info->LxDeviceIdMajor = 0;
Info->LxDeviceIdMinor = 0;
if (!FsvolDeviceExtension->VolumeParams.ExtendedAttributes)
return STATUS_SUCCESS;
ADD_GET_EA("$LXUID", 0);
ADD_GET_EA("$LXGID", 0);
ADD_GET_EA("$LXMOD", 0);
ADD_GET_EA("$LXDEV", 1);
Result = FspSendQueryEaIrp(FsvolDeviceObject/* bypass filters */, FileObject,
&GetEaBuf.V, GetEaLength,
&EaBuf.V, &EaLength);
if (!NT_SUCCESS(Result))
return Result;
for (PFILE_FULL_EA_INFORMATION Ea = &EaBuf.V, EaEnd = (PVOID)((PUINT8)Ea + EaLength);
EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd))
{
EaName.Length =
EaName.MaximumLength = Ea->EaNameLength,
EaName.Buffer = Ea->EaName;
if (EQUAL_EA_NAME("$LXUID"))
{
if (sizeof(ULONG) == Ea->EaValueLength)
{
Info->LxFlags |= 0x1/*LX_FILE_METADATA_HAS_UID*/;
Info->LxUid = *(PULONG)(Ea->EaName + sizeof "$LXUID");
}
}
else
if (EQUAL_EA_NAME("$LXGID"))
{
if (sizeof(ULONG) == Ea->EaValueLength)
{
Info->LxFlags |= 0x2/*LX_FILE_METADATA_HAS_GID*/;
Info->LxGid = *(PULONG)(Ea->EaName + sizeof "$LXGID");
}
}
else
if (EQUAL_EA_NAME("$LXMOD"))
{
if (sizeof(ULONG) == Ea->EaValueLength)
{
Info->LxFlags |= 0x4/*LX_FILE_METADATA_HAS_MODE*/;
Info->LxMode = *(PULONG)(Ea->EaName + sizeof "$LXMOD");
}
}
else
if (EQUAL_EA_NAME("$LXDEV"))
{
if (sizeof(UINT64) == Ea->EaValueLength)
{
Info->LxFlags |= 0x8/*LX_FILE_METADATA_HAS_DEVICE_ID*/;
UINT64 Dev = *(PUINT64)(Ea->EaName + sizeof "$LXDEV");
Info->LxDeviceIdMajor = (Dev >> 32) & 0xffffffff;
Info->LxDeviceIdMinor = Dev & 0xffffffff;
}
}
}
return STATUS_SUCCESS;
#undef EQUAL_EA_NAME
#undef ADD_GET_EA
}
static NTSTATUS FspFsvolQueryStreamInformationCopy( static NTSTATUS FspFsvolQueryStreamInformationCopy(
FSP_FSCTL_STREAM_INFO *StreamInfo, ULONG StreamInfoSize, FSP_FSCTL_STREAM_INFO *StreamInfo, ULONG StreamInfoSize,
PVOID DestBuf, PULONG PDestLen) PVOID DestBuf, PULONG PDestLen)
@ -646,6 +843,71 @@ static NTSTATUS FspFsvolQueryStreamInformationSuccess(
return Result; return Result;
} }
static NTSTATUS FspFsvolQueryInformationEffectiveAccess(
PDEVICE_OBJECT FsvolDeviceObject, PFILE_OBJECT FileObject,
PACCESS_MASK PEffectiveAccess)
{
PAGED_CODE();
union
{
SECURITY_DESCRIPTOR V;
UINT8 B[256];
} SecurityDescriptorBuf;
PSECURITY_DESCRIPTOR SecurityDescriptor = &SecurityDescriptorBuf.V;
ULONG Length;
SECURITY_SUBJECT_CONTEXT SecuritySubjectContext;
ACCESS_MASK EffectiveAccess;
NTSTATUS Result;
BOOLEAN AccessResult;
*PEffectiveAccess = 0;
Length = sizeof SecurityDescriptorBuf;
Result = FspSendQuerySecurityIrp(FsvolDeviceObject/* bypass filters */, FileObject,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
SecurityDescriptor, &Length);
if (STATUS_BUFFER_OVERFLOW == Result)
{
SecurityDescriptor = FspAlloc(Length);
if (0 == SecurityDescriptor)
{
Result = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
Result = FspSendQuerySecurityIrp(FsvolDeviceObject/* bypass filters */, FileObject,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
SecurityDescriptor, &Length);
}
if (!NT_SUCCESS(Result))
goto exit;
SeCaptureSubjectContext(&SecuritySubjectContext);
AccessResult = SeAccessCheck(
SecurityDescriptor,
&SecuritySubjectContext,
FALSE,
MAXIMUM_ALLOWED,
0,
0,
IoGetFileObjectGenericMapping(),
UserMode,
&EffectiveAccess,
&Result);
if (!AccessResult)
goto exit;
*PEffectiveAccess = EffectiveAccess;
exit:
if (&SecurityDescriptorBuf.V != SecurityDescriptor && 0 != SecurityDescriptor)
FspFree(SecurityDescriptor);
return Result;
}
static NTSTATUS FspFsvolQueryInformation( static NTSTATUS FspFsvolQueryInformation(
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {
@ -720,6 +982,18 @@ static NTSTATUS FspFsvolQueryInformation(
case FileStandardInformation: case FileStandardInformation:
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0);
break; break;
case 68/*FileStatInformation*/:
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures)
Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, 0);
else
Result = STATUS_INVALID_PARAMETER;
break;
case 70/*FileStatLxInformation*/:
if (FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.WslFeatures)
Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, 0);
else
Result = STATUS_INVALID_PARAMETER;
break;
default: default:
Result = STATUS_INVALID_PARAMETER; Result = STATUS_INVALID_PARAMETER;
return Result; return Result;
@ -729,6 +1003,26 @@ static NTSTATUS FspFsvolQueryInformation(
return Result; return Result;
FspFileNodeAcquireShared(FileNode, Main); FspFileNodeAcquireShared(FileNode, Main);
switch (FileInformationClass)
{
case 68/*FileStatInformation*/:
FspFsvolQueryInformationEffectiveAccess(
FsvolDeviceObject, FileObject, &((FSP_FILE_STAT_INFORMATION *)Buffer)->EffectiveAccess);
break;
case 70/*FileStatLxInformation*/:
FspFsvolQueryInformationEffectiveAccess(
FsvolDeviceObject, FileObject, &((FSP_FILE_STAT_LX_INFORMATION *)Buffer)->EffectiveAccess);
Result = FspFsvolQueryStatLxEaInformation(
FsvolDeviceObject, FileObject, &Buffer, BufferEnd);
if (!NT_SUCCESS(Result))
{
FspFileNodeRelease(FileNode, Main);
return Result;
}
break;
}
if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf))
{ {
FspFileNodeRelease(FileNode, Main); FspFileNodeRelease(FileNode, Main);
@ -755,6 +1049,12 @@ static NTSTATUS FspFsvolQueryInformation(
case FileStandardInformation: case FileStandardInformation:
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break; break;
case 68/*FileStatInformation*/:
Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break;
case 70/*FileStatLxInformation*/:
Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
break;
default: default:
ASSERT(0); ASSERT(0);
Result = STATUS_INVALID_PARAMETER; Result = STATUS_INVALID_PARAMETER;
@ -865,6 +1165,12 @@ NTSTATUS FspFsvolQueryInformationComplete(
case FileStandardInformation: case FileStandardInformation:
Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo); Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break; break;
case 68/*FileStatInformation*/:
Result = FspFsvolQueryStatBaseInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break;
case 70/*FileStatLxInformation*/:
Result = FspFsvolQueryStatLxBaseInformation(FileObject, &Buffer, BufferEnd, FileInfo);
break;
default: default:
ASSERT(0); ASSERT(0);
Result = STATUS_INVALID_PARAMETER; Result = STATUS_INVALID_PARAMETER;
@ -1813,7 +2119,7 @@ BOOLEAN FspFastIoQueryBasicInfo(
if (Result) if (Result)
{ {
PVOID Buffer = Info; PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info; PVOID BufferEnd = (PUINT8)Info + sizeof *Info;
NTSTATUS Result0 = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); NTSTATUS Result0 = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0)) if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE); FSP_RETURN(Result = FALSE);
@ -1851,7 +2157,7 @@ BOOLEAN FspFastIoQueryStandardInfo(
if (Result) if (Result)
{ {
PVOID Buffer = Info; PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info; PVOID BufferEnd = (PUINT8)Info + sizeof *Info;
NTSTATUS Result0 = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); NTSTATUS Result0 = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0)) if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE); FSP_RETURN(Result = FALSE);
@ -1889,7 +2195,7 @@ BOOLEAN FspFastIoQueryNetworkOpenInfo(
if (Result) if (Result)
{ {
PVOID Buffer = Info; PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info; PVOID BufferEnd = (PUINT8)Info + sizeof *Info;
NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0)) if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE); FSP_RETURN(Result = FALSE);
@ -1933,7 +2239,7 @@ BOOLEAN FspFastIoQueryOpen(
if (Result) if (Result)
{ {
PVOID Buffer = Info; PVOID Buffer = Info;
PVOID BufferEnd = (PUINT8)Info + sizeof Info; PVOID BufferEnd = (PUINT8)Info + sizeof *Info;
NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); NTSTATUS Result0 = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf);
if (!NT_SUCCESS(Result0)) if (!NT_SUCCESS(Result0))
FSP_RETURN(Result = FALSE); FSP_RETURN(Result = FALSE);

View File

@ -86,6 +86,7 @@ static NTSTATUS FspFsctlFileSystemControl(
break; break;
case FSP_FSCTL_TRANSACT: case FSP_FSCTL_TRANSACT:
case FSP_FSCTL_TRANSACT_BATCH: case FSP_FSCTL_TRANSACT_BATCH:
case FSP_FSCTL_TRANSACT_INTERNAL:
if (0 != IrpSp->FileObject->FsContext2) if (0 != IrpSp->FileObject->FsContext2)
Result = FspVolumeTransact(FsctlDeviceObject, Irp, IrpSp); Result = FspVolumeTransact(FsctlDeviceObject, Irp, IrpSp);
break; break;
@ -93,6 +94,14 @@ static NTSTATUS FspFsctlFileSystemControl(
if (0 != IrpSp->FileObject->FsContext2) if (0 != IrpSp->FileObject->FsContext2)
Result = FspVolumeStop(FsctlDeviceObject, Irp, IrpSp); Result = FspVolumeStop(FsctlDeviceObject, Irp, IrpSp);
break; break;
default:
if (CTL_CODE(0, 0xC00, 0, 0) ==
(IrpSp->Parameters.FileSystemControl.FsControlCode & CTL_CODE(0, 0xC00, 0, 0)))
{
if (0 != IrpSp->FileObject->FsContext2)
Result = FspVolumeTransactFsext(FsctlDeviceObject, Irp, IrpSp);
}
break;
} }
break; break;
case IRP_MN_MOUNT_VOLUME: case IRP_MN_MOUNT_VOLUME:

118
src/sys/fsext.c Normal file
View File

@ -0,0 +1,118 @@
/**
* @file sys/fsext.c
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <sys/driver.h>
#include <winfsp/fsext.h>
static KSPIN_LOCK FsextSpinLock = 0;
FSP_FSEXT_PROVIDER *FsextProvider;
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 FsextControlCode, PNTSTATUS PLoadResult)
{
FSP_FSEXT_PROVIDER *Provider;
KIRQL Irql;
KeAcquireSpinLock(&FsextSpinLock, &Irql);
Provider = FsextProvider;
KeReleaseSpinLock(&FsextSpinLock, Irql);
if (0 != Provider && FsextControlCode != Provider->DeviceTransactCode)
Provider = 0;
if (0 != PLoadResult)
{
if (0 == Provider)
{
WCHAR Buf[64 + 256];
UNICODE_STRING Path;
UNICODE_STRING Name;
union
{
KEY_VALUE_PARTIAL_INFORMATION V;
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 256];
} Value;
ULONG Length;
NTSTATUS Result;
RtlInitUnicodeString(&Path, L"" FSP_REGKEY "\\Fsext");
RtlInitEmptyUnicodeString(&Name, Buf, sizeof Buf);
Result = RtlUnicodeStringPrintf(&Name, L"%08x", FsextControlCode);
ASSERT(NT_SUCCESS(Result));
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (!NT_SUCCESS(Result))
{
*PLoadResult = Result;
return 0;
}
if (REG_SZ != Value.V.Type)
{
*PLoadResult = STATUS_OBJECT_NAME_NOT_FOUND;
return 0;
}
RtlInitEmptyUnicodeString(&Path, Buf, sizeof Buf);
Result = RtlUnicodeStringPrintf(&Path,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s", (PWSTR)Value.V.Data);
ASSERT(NT_SUCCESS(Result));
Result = ZwLoadDriver(&Path);
if (!NT_SUCCESS(Result) && STATUS_IMAGE_ALREADY_LOADED != Result)
{
*PLoadResult = Result;
return 0;
}
KeAcquireSpinLock(&FsextSpinLock, &Irql);
Provider = FsextProvider;
KeReleaseSpinLock(&FsextSpinLock, Irql);
if (0 != Provider && FsextControlCode != Provider->DeviceTransactCode)
Provider = 0;
}
*PLoadResult = 0 != Provider ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND;
}
return Provider;
}
NTSTATUS FspFsextProviderRegister(FSP_FSEXT_PROVIDER *Provider)
{
NTSTATUS Result;
KIRQL Irql;
KeAcquireSpinLock(&FsextSpinLock, &Irql);
if (0 != FsextProvider)
{
Result = STATUS_TOO_LATE;
goto exit;
}
Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData);
FsextProvider = Provider;
Result = STATUS_SUCCESS;
exit:
KeReleaseSpinLock(&FsextSpinLock, Irql);
return Result;
}

View File

@ -688,6 +688,12 @@ BOOLEAN FspIoqRetryCompleteIrp(FSP_IOQ *Ioq, PIRP Irp, NTSTATUS *PResult)
Result = FspCsqInsertIrpEx(&Ioq->RetriedIoCsq, Irp, 0, 0); Result = FspCsqInsertIrpEx(&Ioq->RetriedIoCsq, Irp, 0, 0);
if (NT_SUCCESS(Result)) if (NT_SUCCESS(Result))
{ {
/* wake up a waiter */
KIRQL Irql;
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
FspIoqEventSet(&Ioq->PendingIrpEvent);
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
if (0 != PResult) if (0 != PResult)
*PResult = STATUS_PENDING; *PResult = STATUS_PENDING;
return TRUE; return TRUE;

View File

@ -103,7 +103,7 @@ static inline FSP_META_CACHE_ITEM *FspMetaCacheRemoveExpiredItemAtDpcLevel(FSP_M
if (Head == Entry) if (Head == Entry)
return 0; return 0;
FSP_META_CACHE_ITEM *Item = CONTAINING_RECORD(Entry, FSP_META_CACHE_ITEM, ListEntry); FSP_META_CACHE_ITEM *Item = CONTAINING_RECORD(Entry, FSP_META_CACHE_ITEM, ListEntry);
if (!FspExpirationTimeValid2(Item->ExpirationTime, ExpirationTime)) if (FspExpirationTimeValid2(Item->ExpirationTime, ExpirationTime))
return 0; return 0;
ULONG HashIndex = Item->ItemIndex % MetaCache->ItemBucketCount; ULONG HashIndex = Item->ItemIndex % MetaCache->ItemBucketCount;
for (FSP_META_CACHE_ITEM **P = (PVOID)&MetaCache->ItemBuckets[HashIndex]; *P; P = &(*P)->DictNext) for (FSP_META_CACHE_ITEM **P = (PVOID)&MetaCache->ItemBuckets[HashIndex]; *P; P = &(*P)->DictNext)
@ -202,7 +202,7 @@ UINT64 FspMetaCacheAddItem(FSP_META_CACHE *MetaCache, PCVOID Buffer, ULONG Size)
{ {
if (0 == MetaCache) if (0 == MetaCache)
return 0; return 0;
FSP_META_CACHE_ITEM *Item; FSP_META_CACHE_ITEM *Item, *ExpiredItem = 0;
FSP_META_CACHE_ITEM_BUFFER *ItemBuffer; FSP_META_CACHE_ITEM_BUFFER *ItemBuffer;
UINT64 ItemIndex = 0; UINT64 ItemIndex = 0;
KIRQL Irql; KIRQL Irql;
@ -236,12 +236,14 @@ UINT64 FspMetaCacheAddItem(FSP_META_CACHE *MetaCache, PCVOID Buffer, ULONG Size)
} }
KeAcquireSpinLock(&MetaCache->SpinLock, &Irql); KeAcquireSpinLock(&MetaCache->SpinLock, &Irql);
if (MetaCache->ItemCount >= MetaCache->MetaCapacity) if (MetaCache->ItemCount >= MetaCache->MetaCapacity)
FspMetaCacheRemoveExpiredItemAtDpcLevel(MetaCache, (UINT64)-1LL); ExpiredItem = FspMetaCacheRemoveExpiredItemAtDpcLevel(MetaCache, (UINT64)-1LL);
ItemIndex = MetaCache->ItemIndex; ItemIndex = MetaCache->ItemIndex;
ItemIndex = (UINT64)-1LL == ItemIndex ? 1 : ItemIndex + 1; ItemIndex = (UINT64)-1LL == ItemIndex ? 1 : ItemIndex + 1;
MetaCache->ItemIndex = Item->ItemIndex = ItemIndex; MetaCache->ItemIndex = Item->ItemIndex = ItemIndex;
FspMetaCacheAddItemAtDpcLevel(MetaCache, Item); FspMetaCacheAddItemAtDpcLevel(MetaCache, Item);
KeReleaseSpinLock(&MetaCache->SpinLock, Irql); KeReleaseSpinLock(&MetaCache->SpinLock, Irql);
if (0 != ExpiredItem)
FspMetaCacheDereferenceItem(ExpiredItem);
return ItemIndex; return ItemIndex;
} }

View File

@ -275,6 +275,7 @@ NTSTATUS FspMupHandleIrp(
if (FspFileNodeIsValid(FileObject->FsContext)) if (FspFileNodeIsValid(FileObject->FsContext))
FsvolDeviceObject = ((FSP_FILE_NODE *)FileObject->FsContext)->FsvolDeviceObject; FsvolDeviceObject = ((FSP_FILE_NODE *)FileObject->FsContext)->FsvolDeviceObject;
else if (0 != FileObject->FsContext2 && else if (0 != FileObject->FsContext2 &&
#pragma prefast(disable:28175, "We are a filesystem: ok to access DeviceObject->Type")
3 == ((PDEVICE_OBJECT)FileObject->FsContext2)->Type && 3 == ((PDEVICE_OBJECT)FileObject->FsContext2)->Type &&
0 != ((PDEVICE_OBJECT)FileObject->FsContext2)->DeviceExtension && 0 != ((PDEVICE_OBJECT)FileObject->FsContext2)->DeviceExtension &&
FspFsvolDeviceExtensionKind == FspDeviceExtension((PDEVICE_OBJECT)FileObject->FsContext2)->Kind) FspFsvolDeviceExtensionKind == FspDeviceExtension((PDEVICE_OBJECT)FileObject->FsContext2)->Kind)

View File

@ -24,9 +24,18 @@
NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspCreateGuid(GUID *Guid);
NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess,
PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject);
NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength);
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length);
static NTSTATUS FspSendSetInformationIrpCompletion( NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength);
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength);
static NTSTATUS FspSendIrpCompletion(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0); PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0);
NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation);
@ -123,7 +132,10 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspCreateGuid)
#pragma alloc_text(PAGE, FspGetDeviceObjectPointer) #pragma alloc_text(PAGE, FspGetDeviceObjectPointer)
#pragma alloc_text(PAGE, FspRegistryGetValue)
#pragma alloc_text(PAGE, FspSendSetInformationIrp) #pragma alloc_text(PAGE, FspSendSetInformationIrp)
#pragma alloc_text(PAGE, FspSendQuerySecurityIrp)
#pragma alloc_text(PAGE, FspSendQueryEaIrp)
#pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspBufferUserBuffer)
#pragma alloc_text(PAGE, FspLockUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer)
#pragma alloc_text(PAGE, FspMapLockedPagesInUserMode) #pragma alloc_text(PAGE, FspMapLockedPagesInUserMode)
@ -271,11 +283,43 @@ NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK Desir
return Result; return Result;
} }
NTSTATUS FspRegistryGetValue(PUNICODE_STRING Path, PUNICODE_STRING ValueName,
PKEY_VALUE_PARTIAL_INFORMATION ValueInformation, PULONG PValueInformationLength)
{
PAGED_CODE();
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle = 0;
NTSTATUS Result;
InitializeObjectAttributes(&ObjectAttributes,
Path, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
Result = ZwOpenKey(&Handle, KEY_QUERY_VALUE, &ObjectAttributes);
if (!NT_SUCCESS(Result))
goto exit;
Result = ZwQueryValueKey(Handle, ValueName,
KeyValuePartialInformation, ValueInformation,
*PValueInformationLength, PValueInformationLength);
if (!NT_SUCCESS(Result))
goto exit;
Result = STATUS_SUCCESS;
/* NOTE: also converts STATUS_BUFFER_OVERFLOW to STATUS_SUCCESS */
exit:
if (0 != Handle)
ZwClose(Handle);
return Result;
}
typedef struct typedef struct
{ {
IO_STATUS_BLOCK IoStatus; IO_STATUS_BLOCK IoStatus;
KEVENT Event; KEVENT Event;
} FSP_SEND_SET_INFORMATION_IRP_CONTEXT; } FSP_SEND_IRP_CONTEXT;
NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length) FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length)
@ -289,7 +333,7 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
NTSTATUS Result; NTSTATUS Result;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION IrpSp;
FSP_SEND_SET_INFORMATION_IRP_CONTEXT Context; FSP_SEND_IRP_CONTEXT Context;
if (0 == DeviceObject) if (0 == DeviceObject)
DeviceObject = IoGetRelatedDeviceObject(FileObject); DeviceObject = IoGetRelatedDeviceObject(FileObject);
@ -304,24 +348,108 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File
IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION; IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpSp->FileObject = FileObject; IrpSp->FileObject = FileObject;
IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass; IrpSp->Parameters.SetFile.FileInformationClass = FileInformationClass;
IrpSp->Parameters.SetFile.Length = FileInformationClass; IrpSp->Parameters.SetFile.Length = Length;
IoSetCompletionRoutine(Irp, FspSendSetInformationIrpCompletion, &Context, TRUE, TRUE, TRUE);
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE); KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
Result = IoCallDriver(DeviceObject, Irp); Result = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Result) if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0); KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
return NT_SUCCESS(Result) ? Context.IoStatus.Status : Result; return Context.IoStatus.Status;
} }
static NTSTATUS FspSendSetInformationIrpCompletion( NTSTATUS FspSendQuerySecurityIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG PLength)
{
PAGED_CODE();
NTSTATUS Result;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
FSP_SEND_IRP_CONTEXT Context;
ULONG Length = *PLength;
*PLength = 0;
if (0 == DeviceObject)
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (0 == Irp)
return STATUS_INSUFFICIENT_RESOURCES;
IrpSp = IoGetNextIrpStackLocation(Irp);
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = SecurityDescriptor;
Irp->UserBuffer = SecurityDescriptor;
IrpSp->MajorFunction = IRP_MJ_QUERY_SECURITY;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
IrpSp->Parameters.QuerySecurity.Length = Length;
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
Result = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
*PLength = (ULONG)Context.IoStatus.Information;
return Context.IoStatus.Status;
}
NTSTATUS FspSendQueryEaIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject,
PFILE_GET_EA_INFORMATION GetEa, ULONG GetEaLength,
PFILE_FULL_EA_INFORMATION Ea, PULONG PEaLength)
{
PAGED_CODE();
NTSTATUS Result;
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
FSP_SEND_IRP_CONTEXT Context;
ULONG EaLength = *PEaLength;
*PEaLength = 0;
if (0 == DeviceObject)
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (0 == Irp)
return STATUS_INSUFFICIENT_RESOURCES;
IrpSp = IoGetNextIrpStackLocation(Irp);
Irp->RequestorMode = KernelMode;
Irp->AssociatedIrp.SystemBuffer = Ea;
Irp->UserBuffer = Ea;
IrpSp->MajorFunction = IRP_MJ_QUERY_EA;
IrpSp->FileObject = FileObject;
IrpSp->Parameters.QueryEa.Length = EaLength;
IrpSp->Parameters.QueryEa.EaList = GetEa;
IrpSp->Parameters.QueryEa.EaListLength = GetEaLength;
KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp, FspSendIrpCompletion, &Context, TRUE, TRUE, TRUE);
Result = IoCallDriver(DeviceObject, Irp);
if (STATUS_PENDING == Result)
KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, 0);
*PEaLength = (ULONG)Context.IoStatus.Information;
return Context.IoStatus.Status;
}
static NTSTATUS FspSendIrpCompletion(
PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0) PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0)
{ {
// !PAGED_CODE(); // !PAGED_CODE();
FSP_SEND_SET_INFORMATION_IRP_CONTEXT *Context = Context0; FSP_SEND_IRP_CONTEXT *Context = Context0;
Context->IoStatus = Irp->IoStatus; Context->IoStatus = Irp->IoStatus;
KeSetEvent(&Context->Event, 1, FALSE); KeSetEvent(&Context->Event, 1, FALSE);
@ -633,6 +761,10 @@ NTSTATUS FspEaBufferFromFileSystemValidate(
*PErrorOffset = 0; *PErrorOffset = 0;
/* EA buffers from the user mode file system are allowed to have zero length */
if (0 == Length)
return STATUS_SUCCESS;
/* EA buffers from the user mode file system are allowed to end with NextEntryOffset != 0 */ /* EA buffers from the user mode file system are allowed to end with NextEntryOffset != 0 */
for (PFILE_FULL_EA_INFORMATION Ea = Buffer, EaEnd = (PVOID)((PUINT8)Ea + Length); for (PFILE_FULL_EA_INFORMATION Ea = Buffer, EaEnd = (PVOID)((PUINT8)Ea + Length);
EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd)) EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd))

View File

@ -42,6 +42,8 @@ static NTSTATUS FspVolumeGetNameListNoLock(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeTransact( NTSTATUS FspVolumeTransact(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeTransactFsext(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeStop( NTSTATUS FspVolumeStop(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
NTSTATUS FspVolumeWork( NTSTATUS FspVolumeWork(
@ -59,6 +61,7 @@ NTSTATUS FspVolumeWork(
#pragma alloc_text(PAGE, FspVolumeGetNameList) #pragma alloc_text(PAGE, FspVolumeGetNameList)
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock) #pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
#pragma alloc_text(PAGE, FspVolumeTransact) #pragma alloc_text(PAGE, FspVolumeTransact)
#pragma alloc_text(PAGE, FspVolumeTransactFsext)
#pragma alloc_text(PAGE, FspVolumeStop) #pragma alloc_text(PAGE, FspVolumeStop)
#pragma alloc_text(PAGE, FspVolumeWork) #pragma alloc_text(PAGE, FspVolumeWork)
#endif #endif
@ -100,6 +103,7 @@ static NTSTATUS FspVolumeCreateNoLock(
UNICODE_STRING VolumeName; UNICODE_STRING VolumeName;
UNICODE_STRING FsmupDeviceName; UNICODE_STRING FsmupDeviceName;
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)]; WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
FSP_FSEXT_PROVIDER *Provider = 0;
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject;
PDEVICE_OBJECT FsvrtDeviceObject; PDEVICE_OBJECT FsvrtDeviceObject;
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension; FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
@ -132,7 +136,9 @@ static NTSTATUS FspVolumeCreateNoLock(
VolumeParams.SectorsPerAllocationUnit = 1; VolumeParams.SectorsPerAllocationUnit = 1;
if (0 == VolumeParams.MaxComponentLength) if (0 == VolumeParams.MaxComponentLength)
VolumeParams.MaxComponentLength = 255; VolumeParams.MaxComponentLength = 255;
if (FspFsctlTransactTimeoutMinimum > VolumeParams.TransactTimeout || if (0 == VolumeParams.TransactTimeout)
VolumeParams.TransactTimeout = 24 * 60 * 60 * 1000; /* 1 day */
else if (FspFsctlTransactTimeoutMinimum > VolumeParams.TransactTimeout ||
VolumeParams.TransactTimeout > FspFsctlTransactTimeoutMaximum) VolumeParams.TransactTimeout > FspFsctlTransactTimeoutMaximum)
VolumeParams.TransactTimeout = FspFsctlTransactTimeoutDefault; VolumeParams.TransactTimeout = FspFsctlTransactTimeoutDefault;
if (FspFsctlIrpTimeoutMinimum > VolumeParams.IrpTimeout || if (FspFsctlIrpTimeoutMinimum > VolumeParams.IrpTimeout ||
@ -207,6 +213,14 @@ static NTSTATUS FspVolumeCreateNoLock(
VolumeParams.AlwaysUseDoubleBuffering = 1; VolumeParams.AlwaysUseDoubleBuffering = 1;
#endif #endif
/* load any fsext provider */
if (0 != VolumeParams.FsextControlCode)
{
Provider = FspFsextProvider(VolumeParams.FsextControlCode, &Result);
if (0 == Provider)
return Result;
}
/* create volume guid */ /* create volume guid */
Result = FspCreateGuid(&Guid); Result = FspCreateGuid(&Guid);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
@ -224,7 +238,8 @@ static NTSTATUS FspVolumeCreateNoLock(
VolumeName.MaximumLength = VolumeName.Length; VolumeName.MaximumLength = VolumeName.Length;
/* create the volume (and virtual disk) device(s) */ /* create the volume (and virtual disk) device(s) */
Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0, Result = FspDeviceCreate(FspFsvolDeviceExtensionKind,
0 == Provider ? 0 : Provider->DeviceExtensionSize,
FsctlDeviceObject->DeviceType, FsctlDeviceObject->DeviceType,
FILE_DEVICE_DISK_FILE_SYSTEM == FsctlDeviceObject->DeviceType ? 0 : FILE_REMOTE_DEVICE, FILE_DEVICE_DISK_FILE_SYSTEM == FsctlDeviceObject->DeviceType ? 0 : FILE_REMOTE_DEVICE,
&FsvolDeviceObject); &FsvolDeviceObject);
@ -270,6 +285,7 @@ static NTSTATUS FspVolumeCreateNoLock(
if (0 != FsvrtDeviceObject) if (0 != FsvrtDeviceObject)
FspDeviceDereference(FsvrtDeviceObject); FspDeviceDereference(FsvrtDeviceObject);
FspDeviceDereference(FsvolDeviceObject); FspDeviceDereference(FsvolDeviceObject);
return Result;
} }
/* do we need to register with fsmup? */ /* do we need to register with fsmup? */
@ -650,10 +666,8 @@ NTSTATUS FspVolumeTransact(
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction); ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
ASSERT( ASSERT(
FSP_FSCTL_TRANSACT == IrpSp->Parameters.FileSystemControl.FsControlCode || FSP_FSCTL_TRANSACT == IrpSp->Parameters.FileSystemControl.FsControlCode ||
FSP_FSCTL_TRANSACT_BATCH == IrpSp->Parameters.FileSystemControl.FsControlCode); FSP_FSCTL_TRANSACT_BATCH == IrpSp->Parameters.FileSystemControl.FsControlCode ||
ASSERT( FSP_FSCTL_TRANSACT_INTERNAL == IrpSp->Parameters.FileSystemControl.FsControlCode);
METHOD_BUFFERED == (IrpSp->Parameters.FileSystemControl.FsControlCode & 3) ||
METHOD_OUT_DIRECT == (IrpSp->Parameters.FileSystemControl.FsControlCode & 3));
ASSERT(0 != IrpSp->FileObject->FsContext2); ASSERT(0 != IrpSp->FileObject->FsContext2);
/* check parameters */ /* check parameters */
@ -661,17 +675,31 @@ NTSTATUS FspVolumeTransact(
ULONG ControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode; ULONG ControlCode = IrpSp->Parameters.FileSystemControl.FsControlCode;
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
PVOID InputBuffer = Irp->AssociatedIrp.SystemBuffer; PVOID InputBuffer = 0;
PVOID OutputBuffer = 0; PVOID OutputBuffer = 0;
if (0 != InputBufferLength && if (FSP_FSCTL_TRANSACT_INTERNAL == ControlCode)
FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_TRANSACT_RSP)) > InputBufferLength) {
return STATUS_INVALID_PARAMETER; InputBuffer = IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
if (0 != OutputBufferLength && if (KernelMode != Irp->RequestorMode)
((FSP_FSCTL_TRANSACT == ControlCode && return STATUS_INVALID_DEVICE_REQUEST;
FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN > OutputBufferLength) || ASSERT(0 == InputBufferLength ||
(FSP_FSCTL_TRANSACT_BATCH == ControlCode && FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_TRANSACT_RSP)) <= InputBufferLength);
FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN > OutputBufferLength))) ASSERT(0 == OutputBufferLength ||
return STATUS_BUFFER_TOO_SMALL; sizeof(PVOID) <= OutputBufferLength);
}
else
{
InputBuffer = Irp->AssociatedIrp.SystemBuffer;
if (0 != InputBufferLength &&
FSP_FSCTL_DEFAULT_ALIGN_UP(sizeof(FSP_FSCTL_TRANSACT_RSP)) > InputBufferLength)
return STATUS_INVALID_PARAMETER;
if (0 != OutputBufferLength &&
((FSP_FSCTL_TRANSACT == ControlCode &&
FSP_FSCTL_TRANSACT_BUFFER_SIZEMIN > OutputBufferLength) ||
(FSP_FSCTL_TRANSACT_BATCH == ControlCode &&
FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN > OutputBufferLength)))
return STATUS_BUFFER_TOO_SMALL;
}
if (!FspDeviceReference(FsvolDeviceObject)) if (!FspDeviceReference(FsvolDeviceObject))
return STATUS_CANCELLED; return STATUS_CANCELLED;
@ -681,6 +709,7 @@ NTSTATUS FspVolumeTransact(
PUINT8 BufferEnd; PUINT8 BufferEnd;
FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse; FSP_FSCTL_TRANSACT_RSP *Response, *NextResponse;
FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest; FSP_FSCTL_TRANSACT_REQ *Request, *PendingIrpRequest;
PVOID InternalBuffer = 0;
PIRP ProcessIrp, PendingIrp, RetriedIrp, RepostedIrp; PIRP ProcessIrp, PendingIrp, RetriedIrp, RepostedIrp;
ULONG LoopCount; ULONG LoopCount;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
@ -749,6 +778,9 @@ NTSTATUS FspVolumeTransact(
/* were we sent an output buffer? */ /* were we sent an output buffer? */
switch (ControlCode & 3) switch (ControlCode & 3)
{ {
case METHOD_NEITHER:
OutputBuffer = Irp->UserBuffer;
break;
case METHOD_OUT_DIRECT: case METHOD_OUT_DIRECT:
if (0 != Irp->MdlAddress) if (0 != Irp->MdlAddress)
OutputBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress); OutputBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
@ -770,17 +802,17 @@ NTSTATUS FspVolumeTransact(
/* wait for an IRP to arrive */ /* wait for an IRP to arrive */
KeQuerySystemTime(&Timeout); KeQuerySystemTime(&Timeout);
Timeout.QuadPart += 0 == RepostedIrp ? Timeout.QuadPart += FsvolDeviceExtension->VolumeParams.TransactTimeout * 10000ULL;
FsvolDeviceExtension->VolumeParams.TransactTimeout * 10000ULL :
FspVolumeTransactEarlyTimeout;
/* convert millis to nanos and add to absolute time */ /* convert millis to nanos and add to absolute time */
while (0 == (PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, 0, &Timeout, Irp))) if (0 == (PendingIrp = FspIoqNextPendingIrp(FsvolDeviceExtension->Ioq, 0, &Timeout, Irp)))
{ {
if (FspIoqStopped(FsvolDeviceExtension->Ioq)) if (FspIoqStopped(FsvolDeviceExtension->Ioq))
{ {
Result = STATUS_CANCELLED; Result = STATUS_CANCELLED;
goto exit; goto exit;
} }
PendingIrp = FspIoqTimeout;
} }
if (FspIoqTimeout == PendingIrp || FspIoqCancelled == PendingIrp) if (FspIoqTimeout == PendingIrp || FspIoqCancelled == PendingIrp)
{ {
@ -793,7 +825,9 @@ NTSTATUS FspVolumeTransact(
RepostedIrp = 0; RepostedIrp = 0;
Request = OutputBuffer; Request = OutputBuffer;
BufferEnd = (PUINT8)OutputBuffer + OutputBufferLength; BufferEnd = (PUINT8)OutputBuffer + OutputBufferLength;
ASSERT(FspFsctlTransactCanProduceRequest(Request, BufferEnd)); ASSERT(FSP_FSCTL_TRANSACT_INTERNAL == ControlCode ?
TRUE :
FspFsctlTransactCanProduceRequest(Request, BufferEnd));
LoopCount = FspIoqPendingIrpCount(FsvolDeviceExtension->Ioq); LoopCount = FspIoqPendingIrpCount(FsvolDeviceExtension->Ioq);
for (;;) for (;;)
{ {
@ -814,8 +848,18 @@ NTSTATUS FspVolumeTransact(
FspIopCompleteIrp(PendingIrp, Result); FspIopCompleteIrp(PendingIrp, Result);
else else
{ {
RtlCopyMemory(Request, PendingIrpRequest, PendingIrpRequest->Size); if (FSP_FSCTL_TRANSACT_INTERNAL == ControlCode)
Request = FspFsctlTransactProduceRequest(Request, PendingIrpRequest->Size); {
InternalBuffer = FspAllocatePoolMustSucceed(
PagedPool, PendingIrpRequest->Size, FSP_ALLOC_EXTERNAL_TAG);
RtlCopyMemory(InternalBuffer, PendingIrpRequest, PendingIrpRequest->Size);
*(PVOID *)OutputBuffer = InternalBuffer;
}
else
{
RtlCopyMemory(Request, PendingIrpRequest, PendingIrpRequest->Size);
Request = FspFsctlTransactProduceRequest(Request, PendingIrpRequest->Size);
}
if (!FspIoqStartProcessingIrp(FsvolDeviceExtension->Ioq, PendingIrp)) if (!FspIoqStartProcessingIrp(FsvolDeviceExtension->Ioq, PendingIrp))
{ {
@ -826,12 +870,24 @@ NTSTATUS FspVolumeTransact(
* also cancel the PendingIrp we have in our hands. * also cancel the PendingIrp we have in our hands.
*/ */
ASSERT(FspIoqStopped(FsvolDeviceExtension->Ioq)); ASSERT(FspIoqStopped(FsvolDeviceExtension->Ioq));
if (0 != InternalBuffer)
{
ASSERT(FSP_FSCTL_TRANSACT_INTERNAL == ControlCode);
FspFree(InternalBuffer);
}
FspIopCompleteCanceledIrp(PendingIrp); FspIopCompleteCanceledIrp(PendingIrp);
Result = STATUS_CANCELLED; Result = STATUS_CANCELLED;
goto exit; goto exit;
} }
/* are we doing single request or batch mode? */ /* are we doing single request or batch mode? */
if (FSP_FSCTL_TRANSACT_INTERNAL == ControlCode)
{
Irp->IoStatus.Information = sizeof(PVOID);
Result = STATUS_SUCCESS;
goto exit;
}
else
if (FSP_FSCTL_TRANSACT == ControlCode) if (FSP_FSCTL_TRANSACT == ControlCode)
break; break;
@ -858,6 +914,36 @@ exit:
return Result; return Result;
} }
NTSTATUS FspVolumeTransactFsext(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
ASSERT(CTL_CODE(0, 0xC00, 0, 0) ==
(IrpSp->Parameters.FileSystemControl.FsControlCode & CTL_CODE(0, 0xC00, 0, 0)));
ASSERT(0 != IrpSp->FileObject->FsContext2);
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
if (!FspDeviceReference(FsvolDeviceObject))
return STATUS_CANCELLED;
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
if (IrpSp->Parameters.FileSystemControl.FsControlCode ==
FspFsvolDeviceExtension(FsvolDeviceObject)->VolumeParams.FsextControlCode)
{
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
IrpSp->Parameters.FileSystemControl.FsControlCode, 0);
if (0 != Provider)
Result = Provider->DeviceTransact(FsvolDeviceObject, Irp);
}
FspDeviceDereference(FsvolDeviceObject);
return Result;
}
NTSTATUS FspVolumeStop( NTSTATUS FspVolumeStop(
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
{ {

View File

@ -6,7 +6,7 @@ setlocal EnableDelayedExpansion
set MsiName="WinFsp - Windows File System Proxy" set MsiName="WinFsp - Windows File System Proxy"
set CrossCert="%~dp0DigiCert High Assurance EV Root CA.crt" set CrossCert="%~dp0DigiCert High Assurance EV Root CA.crt"
set Issuer="DigiCert" set Issuer="DigiCert"
set Subject="Navimatics Corporation" set Subject="Navimatics LLC"
set Configuration=Release set Configuration=Release
set SignedPackage= set SignedPackage=

View File

@ -4,7 +4,7 @@ setlocal
set DebugWorkspace=winfsp set DebugWorkspace=winfsp
set DebugPort=50000 set DebugPort=50000
set DebugKey=win8.debug.net.key set DebugKey=1.1.1.1
set RegKey="HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots" set RegKey="HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots"
set RegVal="KitsRoot10" set RegVal="KitsRoot10"

View File

@ -5,6 +5,7 @@ setlocal
set CONFIG=Debug set CONFIG=Debug
set SUFFIX=x64 set SUFFIX=x64
set TARGET_MACHINE=WIN8DBG set TARGET_MACHINE=WIN8DBG
if not X%1==X set TARGET_MACHINE=%1
set TARGET_ACCOUNT=\Users\%USERNAME%\Downloads\winfsp\ set TARGET_ACCOUNT=\Users\%USERNAME%\Downloads\winfsp\
set TARGET=\\%TARGET_MACHINE%%TARGET_ACCOUNT% set TARGET=\\%TARGET_MACHINE%%TARGET_ACCOUNT%
@ -14,7 +15,7 @@ for %%f in (winfsp-%SUFFIX%.sys winfsp-%SUFFIX%.dll winfsp-tests-%SUFFIX%.exe fs
copy build\VStudio\build\%CONFIG%\%%f %TARGET% >nul copy build\VStudio\build\%CONFIG%\%%f %TARGET% >nul
) )
copy tools\ifstest.bat %TARGET% >nul copy tools\ifstest.bat %TARGET% >nul
echo sc create WinFsp type=filesys binPath=%%~dp0%DRIVER% >%TARGET%sc-create.bat echo sc create WinFsp type=filesys binPath=%%~dp0winfsp-%SUFFIX%.sys >%TARGET%sc-create.bat
echo sc start WinFsp >%TARGET%sc-start.bat echo sc start WinFsp >%TARGET%sc-start.bat
echo sc stop WinFsp >%TARGET%sc-stop.bat echo sc stop WinFsp >%TARGET%sc-stop.bat
echo sc delete WinFsp >%TARGET%sc-delete.bat echo sc delete WinFsp >%TARGET%sc-delete.bat

44
tools/impdef.bat Normal file
View File

@ -0,0 +1,44 @@
@echo off
setlocal
setlocal EnableDelayedExpansion
if X%1==X goto usage
if X%2==X goto usage
set infile=%1
set infile=%infile:/=\%
set outfile=%2
set outfile=%outfile:/=\%
set workdir=!infile!.work
set workbase=!workdir!\%~n2
set outarch=%~n2
set outarch=%outarch:~-3%
set arch=x64
set cdef=/D_AMD64_
if /i X%outarch%==Xx86 set arch=x86
if /i X%outarch%==Xx86 set cdef=/D_X86_
call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" !arch!
set INCLUDE=%~dp0..\opt\fsext\inc;%~dp0..\inc;!WindowsSdkDir!Include\!WindowsSDKVersion!km\crt;!WindowsSdkDir!Include\!WindowsSDKVersion!km;!WindowsSdkDir!Include\!WindowsSDKVersion!km\shared;!INCLUDE!
if exist !workdir! rmdir /s/q !workdir!
mkdir !workdir!
type !infile! >>!workbase!.c
cl /LD /Fe!workbase!.sys /Fo!workbase!.obj !cdef! /D_KERNEL_MODE /wd4716 !workbase!.c
if errorlevel 1 goto fail
copy !workbase!.lib !outfile!
if errorlevel 1 goto fail
rmdir /s/q !workdir!
exit /b 0
:fail
exit /b 1
:usage
echo usage: impdef.bat infile.impdef outfile.lib 1>&2
exit /b 2

View File

@ -71,6 +71,7 @@ set dfl_tests=^
winfsp-tests-dotnet-external-share ^ winfsp-tests-dotnet-external-share ^
fsx-memfs-dotnet-disk ^ fsx-memfs-dotnet-disk ^
fsx-memfs-dotnet-net ^ fsx-memfs-dotnet-net ^
fsx-memfs-dotnet-slowio ^
winfstest-memfs-dotnet-disk ^ winfstest-memfs-dotnet-disk ^
winfstest-memfs-dotnet-net winfstest-memfs-dotnet-net
set opt_tests=^ set opt_tests=^
@ -498,6 +499,11 @@ call :__run_fsx_memfs_slowio_test memfs32-slowio memfs-x86
if !ERRORLEVEL! neq 0 goto fail if !ERRORLEVEL! neq 0 goto fail
exit /b 0 exit /b 0
:fsx-memfs-dotnet-slowio
call :__run_fsx_memfs_slowio_test memfs.net-slowio memfs-dotnet-msil
if !ERRORLEVEL! neq 0 goto fail
exit /b 0
:__run_fsx_memfs_slowio_test :__run_fsx_memfs_slowio_test
set RunSampleTestExit=0 set RunSampleTestExit=0
call "%ProjRoot%\tools\fsreg" %1 "%ProjRoot%\build\VStudio\build\%Configuration%\%2.exe" "-u %%%%1 -m %%%%2 -M 50 -P 10 -R 5" "D:P(A;;RPWPLC;;;WD)" call "%ProjRoot%\tools\fsreg" %1 "%ProjRoot%\build\VStudio\build\%Configuration%\%2.exe" "-u %%%%1 -m %%%%2 -M 50 -P 10 -R 5" "D:P(A;;RPWPLC;;;WD)"

View File

@ -3,3 +3,6 @@ build
*.suo *.suo
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -22,32 +22,32 @@
<ProjectGuid>{CA441CE7-C4DE-4B5E-AA72-D4D483413EF0}</ProjectGuid> <ProjectGuid>{CA441CE7-C4DE-4B5E-AA72-D4D483413EF0}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>airfs</RootNamespace> <RootNamespace>airfs</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

35
tst/launcher-tests/echo.c Normal file
View File

@ -0,0 +1,35 @@
/*
* Compile:
* - cl -I"%ProgramFiles(x86)%\WinFsp\inc" "%ProgramFiles(x86)%\WinFsp\lib\winfsp-x64.lib" echo.c
*
* Register:
* - echo.reg (fix Executable path first)
*
* Run:
* - launchctl-x64 start echo 1 \foo\bar\baz
*
* Expect:
* - "\foo\bar\baz" "bar:baz" "DOMAIN\\USERNAME"
*/
#include <winfsp/winfsp.h>
int wmain(int argc, wchar_t *argv[])
{
WCHAR buf[512], *bufp;
int len;
bufp = buf;
for (int i = 0; argc > i; i++)
{
len = lstrlenW(argv[i]);
memcpy(bufp, argv[i], len * sizeof(WCHAR));
bufp += len;
*bufp++ = '\n';
}
*bufp = '\0';
FspServiceLog(EVENTLOG_INFORMATION_TYPE, L"%s", buf);
return 0;
}

BIN
tst/launcher-tests/echo.reg Normal file

Binary file not shown.

Binary file not shown.

View File

@ -19,12 +19,17 @@
* associated repository. * associated repository.
*/ */
#define MEMFS_SLOWIO
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.Threading; using System.Threading;
#if MEMFS_SLOWIO
using System.Threading.Tasks;
#endif
using Fsp; using Fsp;
using VolumeInfo = Fsp.Interop.VolumeInfo; using VolumeInfo = Fsp.Interop.VolumeInfo;
@ -232,15 +237,20 @@ namespace memfs
class Memfs : FileSystemBase class Memfs : FileSystemBase
{ {
private FileSystemHost Host;
public const UInt16 MEMFS_SECTOR_SIZE = 512; public const UInt16 MEMFS_SECTOR_SIZE = 512;
public const UInt16 MEMFS_SECTORS_PER_ALLOCATION_UNIT = 1; public const UInt16 MEMFS_SECTORS_PER_ALLOCATION_UNIT = 1;
public Memfs( public Memfs(
Boolean CaseInsensitive, UInt32 MaxFileNodes, UInt32 MaxFileSize, String RootSddl) Boolean CaseInsensitive, UInt32 MaxFileNodes, UInt32 MaxFileSize, String RootSddl,
UInt64 SlowioMaxDelay, UInt64 SlowioPercentDelay, UInt64 SlowioRarefyDelay)
{ {
this.FileNodeMap = new FileNodeMap(CaseInsensitive); this.FileNodeMap = new FileNodeMap(CaseInsensitive);
this.MaxFileNodes = MaxFileNodes; this.MaxFileNodes = MaxFileNodes;
this.MaxFileSize = MaxFileSize; this.MaxFileSize = MaxFileSize;
this.SlowioMaxDelay = SlowioMaxDelay;
this.SlowioPercentDelay = SlowioPercentDelay;
this.SlowioRarefyDelay = SlowioRarefyDelay;
/* /*
* Create root directory. * Create root directory.
@ -259,7 +269,7 @@ namespace memfs
public override Int32 Init(Object Host0) public override Int32 Init(Object Host0)
{ {
FileSystemHost Host = (FileSystemHost)Host0; Host = (FileSystemHost)Host0;
Host.SectorSize = Memfs.MEMFS_SECTOR_SIZE; Host.SectorSize = Memfs.MEMFS_SECTOR_SIZE;
Host.SectorsPerAllocationUnit = Memfs.MEMFS_SECTORS_PER_ALLOCATION_UNIT; Host.SectorsPerAllocationUnit = Memfs.MEMFS_SECTORS_PER_ALLOCATION_UNIT;
Host.VolumeCreationTime = (UInt64)DateTime.Now.ToFileTimeUtc(); Host.VolumeCreationTime = (UInt64)DateTime.Now.ToFileTimeUtc();
@ -274,9 +284,24 @@ namespace memfs
Host.PostCleanupWhenModifiedOnly = true; Host.PostCleanupWhenModifiedOnly = true;
Host.PassQueryDirectoryFileName = true; Host.PassQueryDirectoryFileName = true;
Host.ExtendedAttributes = true; Host.ExtendedAttributes = true;
Host.WslFeatures = true;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
#if MEMFS_SLOWIO
public override int Mounted(object Host)
{
SlowioTasksRunning = 0;
return STATUS_SUCCESS;
}
public override void Unmounted(object Host)
{
while (SlowioTasksRunning != 0)
Thread.Sleep(1000);
}
#endif
public override Int32 GetVolumeInfo( public override Int32 GetVolumeInfo(
out VolumeInfo VolumeInfo) out VolumeInfo VolumeInfo)
{ {
@ -331,8 +356,9 @@ namespace memfs
UInt32 FileAttributes, UInt32 FileAttributes,
Byte[] SecurityDescriptor, Byte[] SecurityDescriptor,
UInt64 AllocationSize, UInt64 AllocationSize,
IntPtr Ea, IntPtr ExtraBuffer,
UInt32 EaLength, UInt32 ExtraLength,
Boolean ExtraBufferIsReparsePoint,
out Object FileNode0, out Object FileNode0,
out Object FileDesc, out Object FileDesc,
out FileInfo FileInfo, out FileInfo FileInfo,
@ -369,11 +395,21 @@ namespace memfs
FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ? FileNode.FileInfo.FileAttributes = 0 != (FileAttributes & (UInt32)System.IO.FileAttributes.Directory) ?
FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive; FileAttributes : FileAttributes | (UInt32)System.IO.FileAttributes.Archive;
FileNode.FileSecurity = SecurityDescriptor; FileNode.FileSecurity = SecurityDescriptor;
if (IntPtr.Zero != Ea) if (IntPtr.Zero != ExtraBuffer)
{ {
Result = SetEaEntries(FileNode, null, Ea, EaLength); if (!ExtraBufferIsReparsePoint)
if (0 > Result) {
return Result; Result = SetEaEntries(FileNode, null, ExtraBuffer, ExtraLength);
if (0 > Result)
return Result;
}
else
{
Byte[] ReparseData = MakeReparsePoint(ExtraBuffer, ExtraLength);
FileNode.FileInfo.FileAttributes |= (UInt32)System.IO.FileAttributes.ReparsePoint;
FileNode.FileInfo.ReparseTag = GetReparseTag(ReparseData);
FileNode.ReparseData = ReparseData;
}
} }
if (0 != AllocationSize) if (0 != AllocationSize)
{ {
@ -549,6 +585,93 @@ namespace memfs
Interlocked.Decrement(ref FileNode.OpenCount); Interlocked.Decrement(ref FileNode.OpenCount);
} }
#if MEMFS_SLOWIO
private UInt64 Hash(UInt64 X)
{
X = (X ^ (X >> 30)) * 0xbf58476d1ce4e5b9ul;
X = (X ^ (X >> 27)) * 0x94d049bb133111ebul;
X = X ^ (X >> 31);
return X;
}
private static int Spin = 0;
private UInt64 PseudoRandom(UInt64 To)
{
/* John Oberschelp's PRNG */
Interlocked.Increment(ref Spin);
return Hash((UInt64)Spin) % To;
}
private bool SlowioReturnPending()
{
if (0 == SlowioMaxDelay)
{
return false;
}
return PseudoRandom(100) < SlowioPercentDelay;
}
private void SlowioSnooze()
{
double Millis = PseudoRandom(SlowioMaxDelay + 1) >> (int) PseudoRandom(SlowioRarefyDelay + 1);
Thread.Sleep(TimeSpan.FromMilliseconds(Millis));
}
private void SlowioReadTask(
Object FileNode0,
IntPtr Buffer,
UInt64 Offset,
UInt64 EndOffset,
UInt64 RequestHint)
{
SlowioSnooze();
UInt32 BytesTransferred = (UInt32)(EndOffset - Offset);
FileNode FileNode = (FileNode)FileNode0;
Marshal.Copy(FileNode.FileData, (int)Offset, Buffer, (int)BytesTransferred);
Host.SendReadResponse(RequestHint, STATUS_SUCCESS, BytesTransferred);
Interlocked.Decrement(ref SlowioTasksRunning);
}
private void SlowioWriteTask(
Object FileNode0,
IntPtr Buffer,
UInt64 Offset,
UInt64 EndOffset,
UInt64 RequestHint)
{
SlowioSnooze();
UInt32 BytesTransferred = (UInt32)(EndOffset - Offset);
FileNode FileNode = (FileNode)FileNode0;
FileInfo FileInfo = FileNode.GetFileInfo();
Marshal.Copy(Buffer, FileNode.FileData, (int)Offset, (int)BytesTransferred);
Host.SendWriteResponse(RequestHint, STATUS_SUCCESS, BytesTransferred, ref FileInfo);
Interlocked.Decrement(ref SlowioTasksRunning);
}
private void SlowioReadDirectoryTask(
Object FileNode0,
Object FileDesc,
String Pattern,
String Marker,
IntPtr Buffer,
UInt32 Length,
UInt64 RequestHint)
{
SlowioSnooze();
UInt32 BytesTransferred;
var Status = SeekableReadDirectory(FileNode0, FileDesc, Pattern, Marker, Buffer, Length, out BytesTransferred);
Host.SendReadDirectoryResponse(RequestHint, Status, BytesTransferred);
Interlocked.Decrement(ref SlowioTasksRunning);
}
#endif
public override Int32 Read( public override Int32 Read(
Object FileNode0, Object FileNode0,
Object FileDesc, Object FileDesc,
@ -570,6 +693,25 @@ namespace memfs
if (EndOffset > FileNode.FileInfo.FileSize) if (EndOffset > FileNode.FileInfo.FileSize)
EndOffset = FileNode.FileInfo.FileSize; EndOffset = FileNode.FileInfo.FileSize;
#if MEMFS_SLOWIO
if (SlowioReturnPending())
{
var Hint = Host.GetOperationRequestHint();
try
{
Interlocked.Increment(ref SlowioTasksRunning);
Task.Run(() => SlowioReadTask(FileNode0, Buffer, Offset, EndOffset, Hint)).ConfigureAwait(false);
BytesTransferred = 0;
return STATUS_PENDING;
}
catch (Exception)
{
Interlocked.Decrement(ref SlowioTasksRunning);
}
}
#endif
BytesTransferred = (UInt32)(EndOffset - Offset); BytesTransferred = (UInt32)(EndOffset - Offset);
Marshal.Copy(FileNode.FileData, (int)Offset, Buffer, (int)BytesTransferred); Marshal.Copy(FileNode.FileData, (int)Offset, Buffer, (int)BytesTransferred);
@ -619,6 +761,26 @@ namespace memfs
} }
} }
#if MEMFS_SLOWIO
if (SlowioReturnPending())
{
var hint = Host.GetOperationRequestHint();
try
{
Interlocked.Increment(ref SlowioTasksRunning);
Task.Run(() => SlowioWriteTask(FileNode0, Buffer, Offset, EndOffset, hint)).ConfigureAwait(false);
BytesTransferred = 0;
FileInfo = default(FileInfo);
return STATUS_PENDING;
}
catch (Exception)
{
Interlocked.Decrement(ref SlowioTasksRunning);
}
}
#endif
BytesTransferred = (UInt32)(EndOffset - Offset); BytesTransferred = (UInt32)(EndOffset - Offset);
Marshal.Copy(Buffer, FileNode.FileData, (int)Offset, (int)BytesTransferred); Marshal.Copy(Buffer, FileNode.FileData, (int)Offset, (int)BytesTransferred);
@ -902,6 +1064,37 @@ namespace memfs
return false; return false;
} }
#if MEMFS_SLOWIO
public override int ReadDirectory(
Object FileNode0,
Object FileDesc,
String Pattern,
String Marker,
IntPtr Buffer,
UInt32 Length,
out UInt32 BytesTransferred)
{
if (SlowioReturnPending())
{
var Hint = Host.GetOperationRequestHint();
try
{
Interlocked.Increment(ref SlowioTasksRunning);
Task.Run(() => SlowioReadDirectoryTask(FileNode0, FileDesc, Pattern, Marker, Buffer, Length, Hint));
BytesTransferred = 0;
return STATUS_PENDING;
}
catch (Exception)
{
Interlocked.Decrement(ref SlowioTasksRunning);
}
}
return SeekableReadDirectory(FileNode0, FileDesc, Pattern, Marker, Buffer, Length, out BytesTransferred);
}
#endif
public override int GetDirInfoByName( public override int GetDirInfoByName(
Object ParentNode0, Object ParentNode0,
Object FileDesc, Object FileDesc,
@ -1140,6 +1333,10 @@ namespace memfs
private FileNodeMap FileNodeMap; private FileNodeMap FileNodeMap;
private UInt32 MaxFileNodes; private UInt32 MaxFileNodes;
private UInt32 MaxFileSize; private UInt32 MaxFileSize;
private UInt64 SlowioMaxDelay;
private UInt64 SlowioPercentDelay;
private UInt64 SlowioRarefyDelay;
private volatile Int32 SlowioTasksRunning;
private String VolumeLabel; private String VolumeLabel;
} }
@ -1170,6 +1367,9 @@ namespace memfs
UInt32 FileInfoTimeout = unchecked((UInt32)(-1)); UInt32 FileInfoTimeout = unchecked((UInt32)(-1));
UInt32 MaxFileNodes = 1024; UInt32 MaxFileNodes = 1024;
UInt32 MaxFileSize = 16 * 1024 * 1024; UInt32 MaxFileSize = 16 * 1024 * 1024;
UInt32 SlowioMaxDelay = 0;
UInt32 SlowioPercentDelay = 0;
UInt32 SlowioRarefyDelay = 0;
String FileSystemName = null; String FileSystemName = null;
String VolumePrefix = null; String VolumePrefix = null;
String MountPoint = null; String MountPoint = null;
@ -1202,9 +1402,18 @@ namespace memfs
case 'm': case 'm':
argtos(Args, ref I, ref MountPoint); argtos(Args, ref I, ref MountPoint);
break; break;
case 'M':
argtol(Args, ref I, ref SlowioMaxDelay);
break;
case 'n': case 'n':
argtol(Args, ref I, ref MaxFileNodes); argtol(Args, ref I, ref MaxFileNodes);
break; break;
case 'P':
argtol(Args, ref I, ref SlowioPercentDelay);
break;
case 'R':
argtol(Args, ref I, ref SlowioRarefyDelay);
break;
case 'S': case 'S':
argtos(Args, ref I, ref RootSddl); argtos(Args, ref I, ref RootSddl);
break; break;
@ -1233,7 +1442,8 @@ namespace memfs
throw new CommandLineUsageException("cannot open debug log file"); throw new CommandLineUsageException("cannot open debug log file");
Host = new FileSystemHost(Memfs = new Memfs( Host = new FileSystemHost(Memfs = new Memfs(
CaseInsensitive, MaxFileNodes, MaxFileSize, RootSddl)); CaseInsensitive, MaxFileNodes, MaxFileSize, RootSddl,
SlowioMaxDelay, SlowioPercentDelay, SlowioRarefyDelay));
Host.FileInfoTimeout = FileInfoTimeout; Host.FileInfoTimeout = FileInfoTimeout;
Host.Prefix = VolumePrefix; Host.Prefix = VolumePrefix;
Host.FileSystemName = null != FileSystemName ? FileSystemName : "-MEMFS"; Host.FileSystemName = null != FileSystemName ? FileSystemName : "-MEMFS";
@ -1262,6 +1472,9 @@ namespace memfs
" -t FileInfoTimeout [millis]\n" + " -t FileInfoTimeout [millis]\n" +
" -n MaxFileNodes\n" + " -n MaxFileNodes\n" +
" -s MaxFileSize [bytes]\n" + " -s MaxFileSize [bytes]\n" +
" -M MaxDelay [maximum slow IO delay in millis]\n" +
" -P PercentDelay [percent of slow IO to make pending]\n" +
" -R RarefyDelay [adjust the rarity of pending slow IO]\n" +
" -F FileSystemName\n" + " -F FileSystemName\n" +
" -S RootSddl [file rights: FA, etc; NO generic rights: GA, etc.]\n" + " -S RootSddl [file rights: FA, etc; NO generic rights: GA, etc.]\n" +
" -u \\Server\\Share [UNC prefix (single backslash)]\n" + " -u \\Server\\Share [UNC prefix (single backslash)]\n" +

View File

@ -70,6 +70,11 @@ FSP_FSCTL_STATIC_ASSERT(MEMFS_MAX_PATH > MAX_PATH,
#define MEMFS_EA #define MEMFS_EA
/* /*
* Define the MEMFS_WSL macro to include WSLinux support.
*/
#define MEMFS_WSL
/*
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes * Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
* a check for the Write buffer to ensure that it is read-only. * a check for the Write buffer to ensure that it is read-only.
* *
@ -1047,8 +1052,8 @@ static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem,
static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem, static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
#if defined(MEMFS_EA) #if defined(MEMFS_EA) || defined(MEMFS_WSL)
PFILE_FULL_EA_INFORMATION Ea, ULONG EaLength, PVOID ExtraBuffer, ULONG ExtraLength, BOOLEAN ExtraBufferIsReparsePoint,
#endif #endif
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
@ -1129,15 +1134,43 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem,
memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize); memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize);
} }
#if defined(MEMFS_EA) #if defined(MEMFS_EA) || defined(MEMFS_WSL)
if (0 != Ea) if (0 != ExtraBuffer)
{ {
Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode, Ea, EaLength); #if defined(MEMFS_EA)
if (!NT_SUCCESS(Result)) if (!ExtraBufferIsReparsePoint)
{ {
MemfsFileNodeDelete(FileNode); Result = FspFileSystemEnumerateEa(FileSystem, MemfsFileNodeSetEa, FileNode,
return Result; (PFILE_FULL_EA_INFORMATION)ExtraBuffer, ExtraLength);
if (!NT_SUCCESS(Result))
{
MemfsFileNodeDelete(FileNode);
return Result;
}
} }
#endif
#if defined(MEMFS_WSL)
if (ExtraBufferIsReparsePoint)
{
#if defined(MEMFS_REPARSE_POINTS)
FileNode->ReparseDataSize = ExtraLength;
FileNode->ReparseData = malloc(ExtraLength);
if (0 == FileNode->ReparseData && 0 != ExtraLength)
{
MemfsFileNodeDelete(FileNode);
return STATUS_INSUFFICIENT_RESOURCES;
}
FileNode->FileInfo.FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
FileNode->FileInfo.ReparseTag = *(PULONG)ExtraBuffer;
/* the first field in a reparse buffer is the reparse tag */
memcpy(FileNode->ReparseData, ExtraBuffer, ExtraLength);
#else
MemfsFileNodeDelete(FileNode);
return STATUS_INVALID_PARAMETER;
#endif
}
#endif
} }
#endif #endif
@ -2189,7 +2222,7 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
GetVolumeInfo, GetVolumeInfo,
SetVolumeLabel, SetVolumeLabel,
GetSecurityByName, GetSecurityByName,
#if defined(MEMFS_EA) #if defined(MEMFS_EA) || defined(MEMFS_WSL)
0, 0,
#else #else
Create, Create,
@ -2240,8 +2273,10 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
0, 0,
#endif #endif
0, 0,
#if defined(MEMFS_EA) #if defined(MEMFS_EA) || defined(MEMFS_WSL)
Create, Create,
#endif
#if defined(MEMFS_EA)
Overwrite, Overwrite,
GetEa, GetEa,
SetEa SetEa
@ -2347,6 +2382,9 @@ NTSTATUS MemfsCreateFunnel(
#endif #endif
#if defined(MEMFS_EA) #if defined(MEMFS_EA)
VolumeParams.ExtendedAttributes = 1; VolumeParams.ExtendedAttributes = 1;
#endif
#if defined(MEMFS_WSL)
VolumeParams.WslFeatures = 1;
#endif #endif
VolumeParams.AllowOpenInKernelMode = 1; VolumeParams.AllowOpenInKernelMode = 1;
if (0 != VolumePrefix) if (0 != VolumePrefix)

View File

@ -3,3 +3,6 @@ build
*.suo *.suo
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -22,32 +22,32 @@
<ProjectGuid>{E8A4060D-E6A4-42CC-9BCA-DC82E6EDB2C5}</ProjectGuid> <ProjectGuid>{E8A4060D-E6A4-42CC-9BCA-DC82E6EDB2C5}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>passthroughcpp</RootNamespace> <RootNamespace>passthroughcpp</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

View File

@ -4,3 +4,6 @@ build
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.csproj.user *.csproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -3,5 +3,8 @@ build
*.suo *.suo
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.VC.db
*.VC.opendb
.vs
*.exe *.exe
*.install *.install

View File

@ -22,32 +22,32 @@
<ProjectGuid>{C753851C-142F-4AAD-B2F7-CBF905C2A600}</ProjectGuid> <ProjectGuid>{C753851C-142F-4AAD-B2F7-CBF905C2A600}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>passthroughfuse</RootNamespace> <RootNamespace>passthroughfuse</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

View File

@ -3,5 +3,8 @@ build
*.suo *.suo
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.VC.db
*.VC.opendb
.vs
*.exe *.exe
*.install *.install

View File

@ -22,32 +22,32 @@
<ProjectGuid>{5E99498C-D30C-48EF-A04A-7977C0305FAC}</ProjectGuid> <ProjectGuid>{5E99498C-D30C-48EF-A04A-7977C0305FAC}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>passthroughfuse3</RootNamespace> <RootNamespace>passthroughfuse3</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

View File

@ -3,3 +3,6 @@ build
*.suo *.suo
*.vcproj.* *.vcproj.*
*.vcxproj.user *.vcxproj.user
*.VC.db
*.VC.opendb
.vs

View File

@ -25,32 +25,32 @@
<ProjectGuid>{9E0E5997-7316-4818-A130-00B3AF1AD354}</ProjectGuid> <ProjectGuid>{9E0E5997-7316-4818-A130-00B3AF1AD354}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>passthrough</RootNamespace> <RootNamespace>passthrough</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset> <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

Binary file not shown.

View File

@ -0,0 +1,112 @@
/**
* @file launcher-ptrans-test.c
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <winfsp/launch.h>
#include <tlib/testsuite.h>
#include "winfsp-tests.h"
#include <launcher/ptrans.c>
static void launcher_ptrans_test(void)
{
PWSTR ipaths[] =
{
L"", 0,
L"\\foo\\bar", 0,
L"", L"",
L"\\foo\\bar", L"",
L"\\foo\\bar", L"/",
L"\\foo\\bar", L"/_",
L"\\foo\\bar", L"/_1",
L"\\foo\\bar", L"\\_",
L"\\foo\\bar", L"\\_A",
L"\\foo\\bar", L"/a",
L"\\foo\\bar", L"/b",
L"\\foo\\bar", L"/c",
L"\\foo\\bar", L"/d",
L"\\foo\\bar", L"/a:b",
L"\\foo\\bar", L"/a:b&c!d",
L"\\foo\\bar", L"/b:a",
L"\\foo\\bar", L"/d!c&b:a",
L"\\foo\\bar", L"/a:_",
L"\\foo\\bar", L"/b:_",
L"\\foo\\bar", L"/c:_",
L"\\foo\\bar\\baz", L"/b:_",
L"\\foo\\bar\\baz\\bag", L"/b:_",
L"\\foo\\bar\\baz", L"/b:/_",
L"\\foo\\bar\\baz\\bag", L"/b:/_",
L"\\foo\\bar\\baz\\bag", L"/a:_:b:_",
L"\\foo\\bar\\baz\\bag", L"/_:_",
};
PWSTR opaths[] =
{
L"",
L"\\foo\\bar",
L"",
L"",
L"",
L"/foo/bar",
L"/foo/bar",
L"\\\\foo\\\\bar",
L"\\\\foo\\\\bar",
L"foo",
L"bar",
L"",
L"",
L"foo:bar",
L"foo:bar&!",
L"bar:foo",
L"!&bar:foo",
L"foo:bar",
L"bar:",
L":",
L"bar:baz",
L"bar:baz/bag",
L"bar:/baz",
L"bar:/baz/bag",
L"foo:bar/baz/bag:bar:baz/bag",
L"/foo/bar/baz/bag:/foo/bar/baz/bag",
};
for (size_t i = 0; sizeof ipaths / (sizeof ipaths[0] * 2) > i; i++)
{
WCHAR Buf[1024];
ULONG Length;
PWSTR Dest;
Length = (ULONG)(UINT_PTR)PathTransform(0, ipaths[2 * i + 0], ipaths[2 * i + 1]);
ASSERT(Length == wcslen(opaths[i]) * sizeof(WCHAR));
Dest = PathTransform(Buf, ipaths[2 * i + 0], ipaths[2 * i + 1]);
*Dest = L'\0';
ASSERT(Dest == Buf + wcslen(opaths[i]));
ASSERT(0 == wcscmp(Buf, opaths[i]));
}
}
void launcher_ptrans_tests(void)
{
if (OptExternal)
return;
TEST_OPT(launcher_ptrans_test);
}

View File

@ -261,8 +261,78 @@ void setsecurity_test(void)
} }
} }
void security_stress_meta_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
{
#define NumFiles 200/* 2*FspFsvolDeviceSecurityCacheCapacity */
void *memfs = memfs_start_ex(Flags, FileInfoTimeout);
HANDLE Handles[NumFiles];
WCHAR FilePath[MAX_PATH];
BOOL Success;
DWORD Length;
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Success = CreateDirectoryW(FilePath, 0);
ASSERT(Success);
for (int j = 0; NumFiles > j; j++)
{
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\file%d",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs), j + 1);
Handles[j] = CreateFileW(FilePath, GENERIC_ALL, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handles[j]);
}
for (int j = 0; NumFiles > j; j++)
{
Success = GetKernelObjectSecurity(Handles[j],
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
0, 0, &Length);
ASSERT(!Success);
ASSERT(ERROR_INSUFFICIENT_BUFFER == GetLastError());
}
for (int j = 0; NumFiles > j; j++)
{
Success = CloseHandle(Handles[j]);
ASSERT(Success);
}
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Success = RemoveDirectoryW(FilePath);
ASSERT(Success);
memfs_stop(memfs);
#undef NumFiles
}
void security_stress_meta_test(void)
{
if (NtfsTests)
{
WCHAR DirBuf[MAX_PATH];
GetTestDirectory(DirBuf);
security_stress_meta_dotest(-1, DirBuf, 0);
}
if (WinFspDiskTests)
{
security_stress_meta_dotest(MemfsDisk, 0, 0);
security_stress_meta_dotest(MemfsDisk, 0, 1000);
}
if (WinFspNetTests)
{
security_stress_meta_dotest(MemfsNet, L"\\\\memfs\\share", 0);
security_stress_meta_dotest(MemfsNet, L"\\\\memfs\\share", 1000);
}
}
void security_tests(void) void security_tests(void)
{ {
TEST(getsecurity_test); TEST(getsecurity_test);
TEST(setsecurity_test); TEST(setsecurity_test);
TEST_OPT(security_stress_meta_test);
} }

View File

@ -193,6 +193,7 @@ int main(int argc, char *argv[])
TESTSUITE(dirbuf_tests); TESTSUITE(dirbuf_tests);
TESTSUITE(version_tests); TESTSUITE(version_tests);
TESTSUITE(launch_tests); TESTSUITE(launch_tests);
TESTSUITE(launcher_ptrans_tests);
TESTSUITE(mount_tests); TESTSUITE(mount_tests);
TESTSUITE(timeout_tests); TESTSUITE(timeout_tests);
TESTSUITE(memfs_tests); TESTSUITE(memfs_tests);
@ -209,6 +210,7 @@ int main(int argc, char *argv[])
TESTSUITE(ea_tests); TESTSUITE(ea_tests);
TESTSUITE(stream_tests); TESTSUITE(stream_tests);
TESTSUITE(oplock_tests); TESTSUITE(oplock_tests);
TESTSUITE(wsl_tests);
atexit(exiting); atexit(exiting);
signal(SIGABRT, abort_handler); signal(SIGABRT, abort_handler);

188
tst/winfsp-tests/wsl-test.c Normal file
View File

@ -0,0 +1,188 @@
/**
* @file wsl-test.c
*
* @copyright 2015-2019 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <winfsp/winfsp.h>
#include <tlib/testsuite.h>
#include <strsafe.h>
#include "memfs.h"
#include "winfsp-tests.h"
typedef struct _FILE_STAT_INFORMATION
{
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ACCESS_MASK EffectiveAccess;
} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;
typedef struct _FILE_STAT_LX_INFORMATION
{
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ACCESS_MASK EffectiveAccess;
ULONG LxFlags;
ULONG LxUid;
ULONG LxGid;
ULONG LxMode;
ULONG LxDeviceIdMajor;
ULONG LxDeviceIdMinor;
} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;
NTSTATUS NTAPI NtQueryInformationFile(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
static void wsl_stat_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
{
void *memfs = memfs_start_ex(Flags, FileInfoTimeout);
HANDLE Handle;
WCHAR FilePath[MAX_PATH];
FILE_STAT_INFORMATION StatInfo;
FILE_STAT_LX_INFORMATION StatLxInfo;
FILETIME FileTime;
LONGLONG TimeLo, TimeHi;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Result;
GetSystemTimeAsFileTime(&FileTime);
TimeLo = ((PLARGE_INTEGER)&FileTime)->QuadPart;
TimeHi = TimeLo + 10000 * 10000/* 10 seconds */;
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Handle = CreateFileW(FilePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
for (int repeat = 0; 2 > repeat; repeat++)
{
/* repeat this test to ensure that any caches are tested */
Result = NtQueryInformationFile(Handle, &IoStatus, &StatInfo, sizeof StatInfo,
68/*FileStatInformation*/);
if (STATUS_SUCCESS == Result)
{
ASSERT(STATUS_SUCCESS == Result);
if (-1 != Flags)
ASSERT(
TimeLo <= StatInfo.CreationTime.QuadPart &&
TimeHi > StatInfo.CreationTime.QuadPart);
ASSERT(
TimeLo <= StatInfo.LastAccessTime.QuadPart &&
TimeHi > StatInfo.LastAccessTime.QuadPart);
ASSERT(
TimeLo <= StatInfo.LastWriteTime.QuadPart &&
TimeHi > StatInfo.LastWriteTime.QuadPart);
ASSERT(
TimeLo <= StatInfo.ChangeTime.QuadPart &&
TimeHi > StatInfo.ChangeTime.QuadPart);
ASSERT(0 == StatInfo.AllocationSize.QuadPart);
ASSERT(0 == StatInfo.EndOfFile.QuadPart);
//ASSERT(FILE_ATTRIBUTE_ARCHIVE == StatInfo.FileAttributes);
ASSERT(0 == StatInfo.ReparseTag);
ASSERT(1 == StatInfo.NumberOfLinks);
//tlib_printf("%lx %lx", FILE_GENERIC_READ | FILE_GENERIC_WRITE, StatInfo.EffectiveAccess);
//ASSERT((FILE_GENERIC_READ | FILE_GENERIC_WRITE) == StatInfo.EffectiveAccess);
Result = NtQueryInformationFile(Handle, &IoStatus, &StatLxInfo, sizeof StatLxInfo,
70/*FileStatLxInformation*/);
ASSERT(STATUS_SUCCESS == Result);
if (-1 != Flags)
ASSERT(
TimeLo <= StatLxInfo.CreationTime.QuadPart &&
TimeHi > StatLxInfo.CreationTime.QuadPart);
ASSERT(
TimeLo <= StatLxInfo.LastAccessTime.QuadPart &&
TimeHi > StatLxInfo.LastAccessTime.QuadPart);
ASSERT(
TimeLo <= StatLxInfo.LastWriteTime.QuadPart &&
TimeHi > StatLxInfo.LastWriteTime.QuadPart);
ASSERT(
TimeLo <= StatLxInfo.ChangeTime.QuadPart &&
TimeHi > StatLxInfo.ChangeTime.QuadPart);
ASSERT(0 == StatLxInfo.AllocationSize.QuadPart);
ASSERT(0 == StatLxInfo.EndOfFile.QuadPart);
//ASSERT(FILE_ATTRIBUTE_ARCHIVE == StatLxInfo.FileAttributes);
ASSERT(0 == StatLxInfo.ReparseTag);
ASSERT(1 == StatLxInfo.NumberOfLinks);
//tlib_printf("%lx %lx", FILE_GENERIC_READ | FILE_GENERIC_WRITE, StatLxInfo.EffectiveAccess);
//ASSERT((FILE_GENERIC_READ | FILE_GENERIC_WRITE) == StatLxInfo.EffectiveAccess);
}
else
{
ASSERT(
STATUS_INVALID_INFO_CLASS == Result ||
STATUS_NOT_IMPLEMENTED == Result/* value returned under WOW64 */);
FspDebugLog(__FUNCTION__ ": only works in Win10 with WSLinux\n");
}
}
CloseHandle(Handle);
memfs_stop(memfs);
}
static void wsl_stat_test(void)
{
if (NtfsTests)
{
WCHAR DirBuf[MAX_PATH];
GetTestDirectory(DirBuf);
wsl_stat_dotest(-1, DirBuf, 0);
}
if (WinFspDiskTests)
{
wsl_stat_dotest(MemfsDisk, 0, 0);
wsl_stat_dotest(MemfsDisk, 0, 1000);
}
if (WinFspNetTests)
{
wsl_stat_dotest(MemfsNet, L"\\\\memfs\\share", 0);
wsl_stat_dotest(MemfsNet, L"\\\\memfs\\share", 1000);
}
}
void wsl_tests(void)
{
TEST_OPT(wsl_stat_test);
}