mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 01:12:58 -05:00
Compare commits
141 Commits
v1.1.17192
...
v1.3B1
Author | SHA1 | Date | |
---|---|---|---|
b9915dcaa7 | |||
a7febb8265 | |||
d6aaf0088a | |||
f05af124e7 | |||
886b7cf9f7 | |||
e111451475 | |||
0c38f92082 | |||
9bd9cf4fbd | |||
2f026cbc6f | |||
68d8ade667 | |||
d9c450ecf4 | |||
e6d2ef9274 | |||
299f371dee | |||
bb8aee8673 | |||
08bf8e14ce | |||
ef1912bd8a | |||
ff155694ce | |||
e6ed6dbf4f | |||
f13b98c880 | |||
5d3b37122c | |||
9d1c892d68 | |||
7008871ed7 | |||
2a3eabfab2 | |||
35255526d3 | |||
b2e474658d | |||
4fe85222b1 | |||
fd3e5bad43 | |||
ea873ece22 | |||
42e01a9b27 | |||
c1c9dca94b | |||
dcabdff422 | |||
a2ec40008f | |||
f3819ba839 | |||
ead599e337 | |||
eb88f25f40 | |||
c2b066a054 | |||
266e0f4bab | |||
d02030897d | |||
c87ff75b8f | |||
2ca33665ef | |||
391dcf8a21 | |||
69d68eb22f | |||
d58f4b84a5 | |||
61935e4671 | |||
41838627c0 | |||
0b67329fc2 | |||
5c962c8fc5 | |||
a9080208d9 | |||
3cc9697248 | |||
9f45d513ca | |||
77349c1330 | |||
7c11a45e6e | |||
48ad297df1 | |||
3d2de57e9d | |||
658d873efb | |||
efc93cacd3 | |||
41b54ef57a | |||
fd662ee848 | |||
895bf67691 | |||
e06fe4153d | |||
9f2fe92db7 | |||
d3f829b2df | |||
fa4651b3ce | |||
5a44e5c04a | |||
68122b5c68 | |||
b672312c79 | |||
0ab35fde1a | |||
9be2b7a2b9 | |||
39dd7662bd | |||
244afc8a3c | |||
111955db84 | |||
76ff8232bc | |||
9a3ac3c7a1 | |||
4adc0d4700 | |||
91c714dd53 | |||
11cb57a0bf | |||
3a8ad9c8d7 | |||
fa388e57ad | |||
1952d0d941 | |||
1a02438488 | |||
07f15c236b | |||
93af1be861 | |||
b52c90f980 | |||
b154c307b7 | |||
697063af51 | |||
436e31da34 | |||
92e7dbad21 | |||
4812f5bbd0 | |||
045a1fa19c | |||
c9b2c0460b | |||
1468df78a2 | |||
0fb6299f17 | |||
0da43fe2d4 | |||
d824ba464d | |||
affca267c5 | |||
4b7684122b | |||
55eee2efdd | |||
f8a05eae95 | |||
9a4f04f46a | |||
98334208b9 | |||
aae0a5bc74 | |||
2438ece1cf | |||
487d2449fe | |||
6430b386da | |||
c70089a176 | |||
0dff9a4c07 | |||
86c0ffa942 | |||
5c613b2abd | |||
8a099f3faa | |||
1ac172d2f8 | |||
34546def3c | |||
3ede1a5c70 | |||
5194536ec3 | |||
c39bc81299 | |||
18bf6ca666 | |||
7eebdbd74e | |||
9a88791f61 | |||
6e578350f4 | |||
81afac9c3a | |||
10081e1a69 | |||
8e5c40bbbe | |||
7745bf4cdc | |||
c7a779fa98 | |||
3f90d60dc4 | |||
f73cbc0e37 | |||
c88a86f7c7 | |||
dbdbdf07cf | |||
6b2dcaef96 | |||
fcae6ce018 | |||
690d3e4c8e | |||
af37424ecc | |||
fd53e22f7e | |||
3df0fa02ba | |||
9484b50cbd | |||
14e6b402fe | |||
2227429d8e | |||
9deb9d5319 | |||
193d5f4e91 | |||
26485ffbd6 | |||
7302b4baea | |||
fc1586eb82 |
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(Enter your issue here.)
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Before submitting this issue please review this checklist. Ideally all checkmarks should be checked upon submitting. (Use an x inside square brackets like so: [x])
|
||||||
|
|
||||||
|
- [ ] **Issue type**: Please consider posting only bug reports or enhancement requests. Questions are better in the [WinFsp Google Group](https://groups.google.com/forum/#!forum/winfsp).
|
||||||
|
- [ ] **No Duplicate**: Ensure that your issue has not been filed before. (Check open and closed issues.)
|
||||||
|
- [ ] **Description**: Provide a descriptive title and a detailed explanation of the problem you are experiencing (for a bug report) or you are trying to solve (for an enhancement request).
|
||||||
|
- [ ] **Reproduce**: For bug reports provide detailed information on how to reproduce the problem. For enhancement requests you do not need to provide this information, unless you find it relevant.
|
||||||
|
- [ ] **Behaviors**: Provide information on the expected and actual behaviors.
|
||||||
|
- [ ] **Environment**: For bug reports provide information about your OS version and build (e.g. 10.0.14393) and WinFsp version and build (e.g. 2017.2 or 1.2.17341). For enhancement requests you do not need to provide this information, unless you find it relevant.
|
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(Enter your PR description here.)
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Before submitting this PR please review this checklist. Ideally all checkmarks should be checked upon submitting. (Use an x inside square brackets like so: [x])
|
||||||
|
|
||||||
|
- [ ] **Contributing**: You MUST read and be willing to accept the [CONTRIBUTOR AGREEMENT](https://github.com/billziss-gh/winfsp/blob/master/Contributors.asciidoc). The agreement gives joint copyright interests in your contributions to you and the original WinFsp author. If you have already accepted the [CONTRIBUTOR AGREEMENT](https://github.com/billziss-gh/winfsp/blob/master/Contributors.asciidoc) you do not need to do so again.
|
||||||
|
- [ ] **Topic branch**: Avoid creating the PR off the master branch of your fork. Consider creating a topic branch and request a pull from that. This allows you to add commits to the master branch of your fork without affecting this PR.
|
||||||
|
- [ ] **No tabs**: Consistently use SPACES everywhere. NO TABS, unless the file format requires it (e.g. Makefile).
|
||||||
|
- [ ] **Style**: Follow the same code style as the rest of the project.
|
||||||
|
- [ ] **Tests**: Include tests to the extent that it is possible, especially if you add a new feature.
|
||||||
|
- [ ] **Quality**: Your design and code should be of high quality and something that you are proud of.
|
@ -1,6 +1,73 @@
|
|||||||
= Changelog
|
= Changelog
|
||||||
|
|
||||||
|
|
||||||
|
v1.3B1 (2018.1 B1)::
|
||||||
|
|
||||||
|
Changes since v1.2POST1:
|
||||||
|
|
||||||
|
- The WinFsp Launcher can now be controlled by the new `FspLaunch` API. File systems can be started, stopped, queried and listed using `FspLaunchStart`, `FspLaunchStop`, `FspLaunchGetInfo` and `FspLaunchGetNameList`.
|
||||||
|
- The WinFsp launcher now supports new registry settings `RunAs` and `WorkDirectory`. `RunAs` allows the laucher to launch a file system process under the service accounts LocalService and NetworkService. `WorkDirectory` can be used to specify the work directory for a newly launched file system process.
|
||||||
|
- The MEMFS sample file systems are now launched under the LocalService account.
|
||||||
|
- The WinFsp network provider is now added first in the provider order list. Previously it was added last. (GitHub PR #131; thanks @felfert.)
|
||||||
|
- The WinFsp installer now uses the Wix `Provides` dependency extension to provide a `WinFsp` dependency key. (GitHub PR #129; thanks @felfert.)
|
||||||
|
|
||||||
|
|
||||||
|
v1.2POST1 (2017.2; issue #127)::
|
||||||
|
|
||||||
|
Changes since v1.1:
|
||||||
|
|
||||||
|
- WinFsp-FUSE now supports BSD flags (Windows file attributes) during `getattr` and `fgetattr`. It also adds the `chflags` operation. BSD flags support requires use of the `FSP_FUSE_CAP_STAT_EX` capability and the new `struct fuse_stat_ex` which includes an `st_flags` field. If the preprocessor macro `FSP_FUSE_USE_STAT_EX` is defined before inclusion of `<fuse.h>` then `struct fuse_stat` will also be defined to include the `st_flags` field.
|
||||||
|
- WinFsp-FUSE also adds the following OSXFUSE operations: `setcrtime`, `setchgtime`. These can be used to set the creation (birth) time and change (ctime) time of a file.
|
||||||
|
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`.
|
||||||
|
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`.
|
||||||
|
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
||||||
|
- The WinFsp launcher now passes the name of the user who launched the file system as a special parameter %U. This is useful to file systems that use the launcher infrastructure, such as SSHFS-Win. [Please note that in earlier betas the user name was passed as parameter %3; the previous method was insecure and is no longer supported.]
|
||||||
|
- Important GitHub issues fixed: #96, #97, #103, #107, #127
|
||||||
|
|
||||||
|
|
||||||
|
v1.2 (2017.2)::
|
||||||
|
|
||||||
|
Changes since v1.1:
|
||||||
|
|
||||||
|
- WinFsp-FUSE now supports BSD flags (Windows file attributes) during `getattr` and `fgetattr`. It also adds the `chflags` operation. BSD flags support requires use of the `FSP_FUSE_CAP_STAT_EX` capability and the new `struct fuse_stat_ex` which includes an `st_flags` field. If the preprocessor macro `FSP_FUSE_USE_STAT_EX` is defined before inclusion of `<fuse.h>` then `struct fuse_stat` will also be defined to include the `st_flags` field.
|
||||||
|
- WinFsp-FUSE also adds the following OSXFUSE operations: `setcrtime`, `setchgtime`. These can be used to set the creation (birth) time and change (ctime) time of a file.
|
||||||
|
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`.
|
||||||
|
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`.
|
||||||
|
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
||||||
|
- The WinFsp launcher now passes the name of the user who launched the file system as a special parameter %U. This is useful to file systems that use the launcher infrastructure, such as SSHFS-Win. [Please note that in earlier betas the user name was passed as parameter %3; the previous method was insecure and is no longer supported.]
|
||||||
|
- Important GitHub issues fixed: #96, #97, #103, #107
|
||||||
|
|
||||||
|
|
||||||
|
v1.2B3 (2017.2 B3)::
|
||||||
|
|
||||||
|
Changes since v1.1:
|
||||||
|
|
||||||
|
- WinFsp-FUSE now supports BSD flags (Windows file attributes) during `getattr` and `fgetattr`. It also adds the `chflags` operation. BSD flags support requires use of the `FSP_FUSE_CAP_STAT_EX` capability and the new `struct fuse_stat_ex` which includes an `st_flags` field. If the preprocessor macro `FSP_FUSE_USE_STAT_EX` is defined before inclusion of `<fuse.h>` then `struct fuse_stat` will also be defined to include the `st_flags` field.
|
||||||
|
- WinFsp-FUSE also adds the following OSXFUSE operations: `setcrtime`, `setchgtime`. These can be used to set the creation (birth) time and change (ctime) time of a file.
|
||||||
|
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`.
|
||||||
|
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`.
|
||||||
|
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
||||||
|
- The WinFsp launcher now passes the username of the user who launched the file system as parameter %3. This is useful to file systems that use the launcher infrastructure, such as SSHFS-Win.
|
||||||
|
- Important GitHub issues fixed: #96, #97, #103, #107
|
||||||
|
|
||||||
|
|
||||||
|
v1.2B2 (2017.2 B2)::
|
||||||
|
|
||||||
|
Changes since v1.1:
|
||||||
|
|
||||||
|
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
||||||
|
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`.
|
||||||
|
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`.
|
||||||
|
- Important GitHub issues fixed: #96, #97, #103, #107
|
||||||
|
|
||||||
|
|
||||||
|
v1.2B1 (2017.2 B1)::
|
||||||
|
|
||||||
|
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
||||||
|
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW("foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS.
|
||||||
|
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls.
|
||||||
|
|
||||||
|
|
||||||
v1.1 (2017.1)::
|
v1.1 (2017.1)::
|
||||||
|
|
||||||
This release brings some major new components and improvements.
|
This release brings some major new components and improvements.
|
||||||
|
@ -55,5 +55,8 @@ CONTRIBUTOR LIST
|
|||||||
----------------
|
----------------
|
||||||
|===
|
|===
|
||||||
|Bill Zissimopoulos |billziss at navimatics.com
|
|Bill Zissimopoulos |billziss at navimatics.com
|
||||||
|
|Fritz Elfert |fritz-github at fritz-elfert.de
|
||||||
|
|John Oberschelp |john at oberschelp.net
|
||||||
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|
|Sam Kelly (DuroSoft Technologies LLC, https://durosoft.com) |sam at durosoft.com
|
||||||
|
|Tobias Urlaub |saibotu at outlook.de
|
||||||
|===
|
|===
|
||||||
|
32
README.md
32
README.md
@ -30,21 +30,23 @@ WinFsp consists of a kernel mode FSD (File System Driver) and a user mode DLL (D
|
|||||||
|
|
||||||
The project source code is organized as follows:
|
The project source code is organized as follows:
|
||||||
|
|
||||||
* build/VStudio: WinFsp solution and project files.
|
* `build/VStudio`: WinFsp solution and project files.
|
||||||
* doc: The WinFsp design documents and additional documentation can be found here.
|
* `doc`: The WinFsp design documents and additional documentation can be found here.
|
||||||
* ext/tlib: A small test library originally from the secfs (Secure Cloud File System) project.
|
* `ext/tlib`: A small test library originally from the secfs (Secure Cloud File System) project.
|
||||||
* ext/test: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
|
* `ext/test`: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
|
||||||
* inc/winfsp: Public headers for the WinFsp API.
|
* `inc/fuse`: Public headers for the FUSE compatibility layer.
|
||||||
* inc/fuse: Public headers for the FUSE compatibility layer.
|
* `inc/winfsp`: Public headers for the WinFsp API.
|
||||||
* src/dll: Source code to the WinFsp DLL.
|
* `src/dll`: Source code to the WinFsp DLL.
|
||||||
* src/dll/fuse: Source code to the FUSE compatibility layer.
|
* `src/dll/fuse`: Source code to the FUSE compatibility layer.
|
||||||
* src/dotnet: Source code to the .NET layer.
|
* `src/dotnet`: Source code to the .NET layer.
|
||||||
* src/launcher: Source code to the launcher service and the launchctl utility.
|
* `src/fsptool`: Source code to fsptool command line utility.
|
||||||
* src/sys: Source code to the WinFsp FSD.
|
* `src/launcher`: Source code to the launcher service and the launchctl utility.
|
||||||
* opt/cygfuse: Source code for the Cygwin FUSE package.
|
* `src/sys`: Source code to the WinFsp FSD.
|
||||||
* tst/memfs*: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet).
|
* `opt/cygfuse`: Source code for the Cygwin FUSE package.
|
||||||
* tst/passthrough*: Source code to additional example file systems.
|
* `tst/memfs*`: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet).
|
||||||
* tst/winfsp-tests: WinFsp test suite.
|
* `tst/passthrough*`: Source code to additional example file systems.
|
||||||
|
* `tst/winfsp-tests`: WinFsp test suite.
|
||||||
|
* `tools`: Various tools for building and testing WinFsp.
|
||||||
|
|
||||||
## Building and Running
|
## Building and Running
|
||||||
|
|
||||||
|
@ -6,8 +6,10 @@ environment:
|
|||||||
TESTING: Func
|
TESTING: Func
|
||||||
- CONFIGURATION: Release
|
- CONFIGURATION: Release
|
||||||
TESTING: Func
|
TESTING: Func
|
||||||
- CONFIGURATION: Release
|
#- CONFIGURATION: Release
|
||||||
TESTING: Perf
|
# TESTING: Avast
|
||||||
|
#- CONFIGURATION: Release
|
||||||
|
# TESTING: Perf
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
@ -30,6 +32,9 @@ test_script:
|
|||||||
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION%
|
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION%
|
||||||
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% ifstest
|
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% ifstest
|
||||||
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% sample
|
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% sample
|
||||||
|
- if %TESTING%==Func tools\run-tests.bat %CONFIGURATION% compat
|
||||||
|
- if %TESTING%==Avast choco install avastfreeantivirus && fltmc instances -v "C:"
|
||||||
|
- if %TESTING%==Avast tools\run-tests.bat %CONFIGURATION% avast-tests
|
||||||
- if %TESTING%==Perf tools\run-perf-tests.bat %CONFIGURATION% baseline > perf-tests.csv && type perf-tests.csv & appveyor PushArtifact perf-tests.csv
|
- if %TESTING%==Perf tools\run-perf-tests.bat %CONFIGURATION% baseline > perf-tests.csv && type perf-tests.csv & appveyor PushArtifact perf-tests.csv
|
||||||
- choco uninstall winfsp -y
|
- choco uninstall winfsp -y
|
||||||
- if exist %SystemRoot%\memory.dmp exit 1
|
- if exist %SystemRoot%\memory.dmp exit 1
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file CustomActions.cpp
|
* @file CustomActions.cpp
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||||
|
xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension">
|
||||||
<Product
|
<Product
|
||||||
Id="*"
|
Id="*"
|
||||||
Name="$(var.MyProductName) $(var.MyProductVersion)"
|
Name="$(var.MyProductName) $(var.MyProductVersion)"
|
||||||
@ -53,8 +54,8 @@
|
|||||||
Key="[P.RegistryKey]"
|
Key="[P.RegistryKey]"
|
||||||
Name="InstallDir"
|
Name="InstallDir"
|
||||||
Type="string"
|
Type="string"
|
||||||
Value="[INSTALLDIR]"
|
Value="[INSTALLDIR]" />
|
||||||
KeyPath="yes" />
|
<dep:Provides Key="WinFsp" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.License.txt">
|
<Component Id="C.License.txt">
|
||||||
<File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" />
|
<File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" />
|
||||||
@ -158,6 +159,13 @@
|
|||||||
<File Name="launchctl-x86.exe" KeyPath="yes" />
|
<File Name="launchctl-x86.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
|
<Component Id="C.fsptool_x64.exe" Guid="013FE508-097D-4433-9C60-717F5446E7F4">
|
||||||
|
<File Name="fsptool-x64.exe" KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
|
<Component Id="C.fsptool_x86.exe" Guid="6C16DC2C-E12F-49FB-A665-3AF0475487AD">
|
||||||
|
<File Name="fsptool-x86.exe" KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
|
|
||||||
<Component Id="C.diag.bat">
|
<Component Id="C.diag.bat">
|
||||||
<File Name="diag.bat" Source="..\..\..\tools\diag.bat" KeyPath="yes" />
|
<File Name="diag.bat" Source="..\..\..\tools\diag.bat" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
@ -180,6 +188,10 @@
|
|||||||
Type="string"
|
Type="string"
|
||||||
Name="CommandLine"
|
Name="CommandLine"
|
||||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||||
|
<RegistryValue
|
||||||
|
Type="string"
|
||||||
|
Name="RunAs"
|
||||||
|
Value="LocalService" />
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="Security"
|
Name="Security"
|
||||||
@ -206,6 +218,10 @@
|
|||||||
Type="string"
|
Type="string"
|
||||||
Name="CommandLine"
|
Name="CommandLine"
|
||||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||||
|
<RegistryValue
|
||||||
|
Type="string"
|
||||||
|
Name="RunAs"
|
||||||
|
Value="LocalService" />
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="Security"
|
Name="Security"
|
||||||
@ -232,6 +248,10 @@
|
|||||||
Type="string"
|
Type="string"
|
||||||
Name="CommandLine"
|
Name="CommandLine"
|
||||||
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
Value="-i -F NTFS -n 65536 -s 67108864 -u %1 -m %2" />
|
||||||
|
<RegistryValue
|
||||||
|
Type="string"
|
||||||
|
Name="RunAs"
|
||||||
|
Value="LocalService" />
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Type="string"
|
Type="string"
|
||||||
Name="Security"
|
Name="Security"
|
||||||
@ -303,12 +323,12 @@
|
|||||||
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
|
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
|
||||||
<Directory Id="OPTDIR.cygfuse.x64" Name="x64">
|
<Directory Id="OPTDIR.cygfuse.x64" Name="x64">
|
||||||
<Component Id="C.fuse.tar.xz.x64">
|
<Component Id="C.fuse.tar.xz.x64">
|
||||||
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-5.tar.xz" KeyPath="yes" />
|
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-7.tar.xz" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory Id="OPTDIR.cygfuse.x86" Name="x86">
|
<Directory Id="OPTDIR.cygfuse.x86" Name="x86">
|
||||||
<Component Id="C.fuse.tar.xz.x86">
|
<Component Id="C.fuse.tar.xz.x86">
|
||||||
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-5.tar.xz" KeyPath="yes" />
|
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-7.tar.xz" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Component Id="C.fuse.install.sh">
|
<Component Id="C.fuse.install.sh">
|
||||||
@ -427,6 +447,12 @@
|
|||||||
<Component Id="C.launchctl_x86.pdb">
|
<Component Id="C.launchctl_x86.pdb">
|
||||||
<File Name="launchctl-x86.pdb" Source="..\build\$(var.Configuration)\launchctl-x86.public.pdb" KeyPath="yes" />
|
<File Name="launchctl-x86.pdb" Source="..\build\$(var.Configuration)\launchctl-x86.public.pdb" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component Id="C.fsptool_x64.pdb">
|
||||||
|
<File Name="fsptool-x64.pdb" Source="..\build\$(var.Configuration)\fsptool-x64.public.pdb" KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
|
<Component Id="C.fsptool_x86.pdb">
|
||||||
|
<File Name="fsptool-x86.pdb" Source="..\build\$(var.Configuration)\fsptool-x86.public.pdb" KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
<Component Id="C.memfs_x64.pdb">
|
<Component Id="C.memfs_x64.pdb">
|
||||||
<File Name="memfs-x64.pdb" Source="..\build\$(var.Configuration)\memfs-x64.public.pdb" KeyPath="yes" />
|
<File Name="memfs-x64.pdb" Source="..\build\$(var.Configuration)\memfs-x64.public.pdb" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
@ -448,6 +474,8 @@
|
|||||||
<ComponentRef Id="C.launcher_x86.exe.svcinst" />
|
<ComponentRef Id="C.launcher_x86.exe.svcinst" />
|
||||||
<ComponentRef Id="C.launchctl_x64.exe" />
|
<ComponentRef Id="C.launchctl_x64.exe" />
|
||||||
<ComponentRef Id="C.launchctl_x86.exe" />
|
<ComponentRef Id="C.launchctl_x86.exe" />
|
||||||
|
<ComponentRef Id="C.fsptool_x64.exe" />
|
||||||
|
<ComponentRef Id="C.fsptool_x86.exe" />
|
||||||
<ComponentRef Id="C.diag.bat" />
|
<ComponentRef Id="C.diag.bat" />
|
||||||
<ComponentRef Id="C.fsreg.bat" />
|
<ComponentRef Id="C.fsreg.bat" />
|
||||||
</ComponentGroup>
|
</ComponentGroup>
|
||||||
@ -504,6 +532,8 @@
|
|||||||
<ComponentRef Id="C.launcher_x64.pdb" />
|
<ComponentRef Id="C.launcher_x64.pdb" />
|
||||||
<ComponentRef Id="C.launchctl_x64.pdb" />
|
<ComponentRef Id="C.launchctl_x64.pdb" />
|
||||||
<ComponentRef Id="C.launchctl_x86.pdb" />
|
<ComponentRef Id="C.launchctl_x86.pdb" />
|
||||||
|
<ComponentRef Id="C.fsptool_x64.pdb" />
|
||||||
|
<ComponentRef Id="C.fsptool_x86.pdb" />
|
||||||
<ComponentRef Id="C.memfs_x64.pdb" />
|
<ComponentRef Id="C.memfs_x64.pdb" />
|
||||||
<ComponentRef Id="C.memfs_x86.pdb" />
|
<ComponentRef Id="C.memfs_x86.pdb" />
|
||||||
</ComponentGroup>
|
</ComponentGroup>
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||||
<Name>WixUIExtension</Name>
|
<Name>WixUIExtension</Name>
|
||||||
</WixExtension>
|
</WixExtension>
|
||||||
|
<WixExtension Include="WixDependencyExtension">
|
||||||
|
<HintPath>$(WixExtDir)\WixDependencyExtension.dll</HintPath>
|
||||||
|
<Name>WixDependencyExtension</Name>
|
||||||
|
</WixExtension>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(WixTargetsPath)" />
|
<Import Project="$(WixTargetsPath)" />
|
||||||
<!--
|
<!--
|
||||||
|
193
build/VStudio/tools/fsptool.vcxproj
Normal file
193
build/VStudio/tools/fsptool.vcxproj
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\version.properties" />
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{1E997BEC-1642-4A5C-B252-852DA094E11E}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>fsptool</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v140</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\$(ProjectName).build\$(Configuration)\$(PlatformTarget)\</IntDir>
|
||||||
|
<TargetName>$(ProjectName)-$(PlatformTarget)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||||
|
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>..\..\..\src;..\..\..\inc</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\winfsp_dll.vcxproj">
|
||||||
|
<Project>{4a7c0b21-9e10-4c81-92de-1493efcf24eb}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\fsptool\fsptool.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\..\..\src\fsptool\fsptool-version.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
23
build/VStudio/tools/fsptool.vcxproj.filters
Normal file
23
build/VStudio/tools/fsptool.vcxproj.filters
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Include">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\src\fsptool\fsptool.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\..\..\src\fsptool\fsptool-version.rc">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -20,7 +20,7 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{73EAAEDA-557B-48D5-A137-328934720FB4}</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>8.1</WindowsTargetPlatformVersion>
|
@ -20,7 +20,7 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{A5EFD487-0140-4184-8C54-FFAEC2F85E35}</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>8.1</WindowsTargetPlatformVersion>
|
||||||
@ -112,7 +112,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -134,7 +134,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -159,7 +159,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -184,7 +184,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
@ -7,7 +7,8 @@
|
|||||||
<!-- git revision -->
|
<!-- git revision -->
|
||||||
<MyGitRoot>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), .git/HEAD))</MyGitRoot>
|
<MyGitRoot>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), .git/HEAD))</MyGitRoot>
|
||||||
<MyGitHead>$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/HEAD).Trim())</MyGitHead>
|
<MyGitHead>$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/HEAD).Trim())</MyGitHead>
|
||||||
<MyGitRevision Condition="$(MyGitHead.StartsWith(ref: ))">$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/$(MyGitHead.Substring(5))).Trim().Substring(0, 7))</MyGitRevision>
|
<MyGitRevision Condition="$(MyGitHead.StartsWith(ref: )) And Exists('$(MyGitRoot)/.git/$(MyGitHead.Substring(5))')">$([System.IO.File]::ReadAllText($(MyGitRoot)/.git/$(MyGitHead.Substring(5))).Trim().Substring(0, 7))</MyGitRevision>
|
||||||
|
<MyGitRevision Condition="$(MyGitHead.StartsWith(ref: )) And !Exists('$(MyGitRoot)/.git/$(MyGitHead.Substring(5))')">$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText($(MyGitRoot)/.git/packed-refs)), '[0-9a-fA-F]{40,}.*$(MyGitHead.Substring(5))').Value.Substring(0, 7))</MyGitRevision>
|
||||||
<MyGitRevision Condition="!$(MyGitHead.StartsWith(ref: ))">$(MyGitHead.Substring(0, 7))</MyGitRevision>
|
<MyGitRevision Condition="!$(MyGitHead.StartsWith(ref: ))">$(MyGitHead.Substring(0, 7))</MyGitRevision>
|
||||||
|
|
||||||
<MyProductName>WinFsp</MyProductName>
|
<MyProductName>WinFsp</MyProductName>
|
||||||
@ -15,10 +16,10 @@
|
|||||||
<MyCompanyName>Navimatics Corporation</MyCompanyName>
|
<MyCompanyName>Navimatics Corporation</MyCompanyName>
|
||||||
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
|
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
|
||||||
|
|
||||||
<MyCanonicalVersion>1.1</MyCanonicalVersion>
|
<MyCanonicalVersion>1.3</MyCanonicalVersion>
|
||||||
|
|
||||||
<MyProductVersion>2017.1</MyProductVersion>
|
<MyProductVersion>2018.1 B1</MyProductVersion>
|
||||||
<MyProductStage>Gold</MyProductStage>
|
<MyProductStage>Beta</MyProductStage>
|
||||||
|
|
||||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||||
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
||||||
|
@ -32,19 +32,6 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "winfsp_msi", "installer\win
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomActions", "installer\CustomActions\CustomActions.vcxproj", "{95C223E6-B5F1-4FD0-9376-41CDBC824445}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomActions", "installer\CustomActions\CustomActions.vcxproj", "{95C223E6-B5F1-4FD0-9376-41CDBC824445}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "launcher", "launcher", "{FD28A504-431E-49B9-BB8C-DCA0E7019F66}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "launcher\launcher.vcxproj", "{A5EFD487-0140-4184-8C54-FFAEC2F85E35}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB} = {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}
|
|
||||||
{C85C26BA-8C22-4D30-83DA-46C3548E6332} = {C85C26BA-8C22-4D30-83DA-46C3548E6332}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launchctl", "launcher\launchctl.vcxproj", "{73EAAEDA-557B-48D5-A137-328934720FB4}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35} = {A5EFD487-0140-4184-8C54-FFAEC2F85E35}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fscrash", "testing\fscrash.vcxproj", "{10757011-749D-4954-873B-AE38D8145472}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fscrash", "testing\fscrash.vcxproj", "{10757011-749D-4954-873B-AE38D8145472}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB} = {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}
|
{4A7C0B21-9E10-4C81-92DE-1493EFCF24EB} = {4A7C0B21-9E10-4C81-92DE-1493EFCF24EB}
|
||||||
@ -63,6 +50,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dotnet", "dotnet", "{A998CE
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "memfs-dotnet", "testing\memfs-dotnet.csproj", "{4920E350-D496-4652-AE98-6C4208AEC1D8}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "memfs-dotnet", "testing\memfs-dotnet.csproj", "{4920E350-D496-4652-AE98-6C4208AEC1D8}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{04A4762C-FAB9-4196-9AC8-0757F3E8AB79}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launcher", "tools\launcher.vcxproj", "{6CDF9411-B852-4EAC-822D-8F930675F17B}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "launchctl", "tools\launchctl.vcxproj", "{264A5D09-126F-4760-A3F1-4B3B95C925AA}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsptool", "tools\fsptool.vcxproj", "{1E997BEC-1642-4A5C-B252-852DA094E11E}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -179,38 +174,6 @@ Global
|
|||||||
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|Any CPU.ActiveCfg = Release|Win32
|
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x64.ActiveCfg = Release|Win32
|
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x64.ActiveCfg = Release|Win32
|
||||||
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x86.ActiveCfg = Release|Win32
|
{95C223E6-B5F1-4FD0-9376-41CDBC824445}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Installer.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Release|x64.Build.0 = Release|x64
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35}.Release|x86.Build.0 = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Debug|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Installer.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|Any CPU.ActiveCfg = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x64.Build.0 = Release|x64
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4}.Release|x86.Build.0 = Release|Win32
|
|
||||||
{10757011-749D-4954-873B-AE38D8145472}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
{10757011-749D-4954-873B-AE38D8145472}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.ActiveCfg = Debug|x64
|
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.Build.0 = Debug|x64
|
{10757011-749D-4954-873B-AE38D8145472}.Debug|x64.Build.0 = Debug|x64
|
||||||
@ -268,23 +231,65 @@ Global
|
|||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.Build.0 = Debug|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Installer.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.Build.0 = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.ActiveCfg = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.Build.0 = Release|Any CPU
|
{4920E350-D496-4652-AE98-6C4208AEC1D8}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Installer.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x64.Build.0 = Release|x64
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Installer.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x64.Build.0 = Release|x64
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|Any CPU.ActiveCfg = Release|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Installer.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -294,11 +299,12 @@ Global
|
|||||||
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
{AA7190E8-877F-4827-8CDD-E0D85F83C8C1} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||||
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594} = {B464EF06-42AE-4674-81BB-FDDE80204822}
|
{D53AAC39-4C57-4CA5-A4F3-C2B24888C594} = {B464EF06-42AE-4674-81BB-FDDE80204822}
|
||||||
{95C223E6-B5F1-4FD0-9376-41CDBC824445} = {B464EF06-42AE-4674-81BB-FDDE80204822}
|
{95C223E6-B5F1-4FD0-9376-41CDBC824445} = {B464EF06-42AE-4674-81BB-FDDE80204822}
|
||||||
{A5EFD487-0140-4184-8C54-FFAEC2F85E35} = {FD28A504-431E-49B9-BB8C-DCA0E7019F66}
|
|
||||||
{73EAAEDA-557B-48D5-A137-328934720FB4} = {FD28A504-431E-49B9-BB8C-DCA0E7019F66}
|
|
||||||
{10757011-749D-4954-873B-AE38D8145472} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
{10757011-749D-4954-873B-AE38D8145472} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||||
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
{C4E1E9E5-0959-488E-8C6A-C327CC81BEFB} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||||
{94580219-CC8D-4FE5-A3BE-437B0B3481E1} = {A998CEC4-4B34-43DC-8457-F7761228BA67}
|
{94580219-CC8D-4FE5-A3BE-437B0B3481E1} = {A998CEC4-4B34-43DC-8457-F7761228BA67}
|
||||||
{4920E350-D496-4652-AE98-6C4208AEC1D8} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
{4920E350-D496-4652-AE98-6C4208AEC1D8} = {69439FD1-C07D-4BF1-98DC-3CCFECE53A49}
|
||||||
|
{6CDF9411-B852-4EAC-822D-8F930675F17B} = {04A4762C-FAB9-4196-9AC8-0757F3E8AB79}
|
||||||
|
{264A5D09-126F-4760-A3F1-4B3B95C925AA} = {04A4762C-FAB9-4196-9AC8-0757F3E8AB79}
|
||||||
|
{1E997BEC-1642-4A5C-B252-852DA094E11E} = {04A4762C-FAB9-4196-9AC8-0757F3E8AB79}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\fuse\fuse_intf.c" />
|
<ClCompile Include="..\..\src\dll\fuse\fuse_intf.c" />
|
||||||
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c" />
|
<ClCompile Include="..\..\src\dll\fuse\fuse_main.c" />
|
||||||
<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\np.c" />
|
<ClCompile Include="..\..\src\dll\np.c" />
|
||||||
<ClCompile Include="..\..\src\dll\posix.c" />
|
<ClCompile Include="..\..\src\dll\posix.c" />
|
||||||
<ClCompile Include="..\..\src\dll\security.c" />
|
<ClCompile Include="..\..\src\dll\security.c" />
|
||||||
@ -51,6 +52,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\path.c" />
|
<ClCompile Include="..\..\src\dll\path.c" />
|
||||||
<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" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
|
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
|
||||||
|
@ -112,6 +112,12 @@
|
|||||||
<ClCompile Include="..\..\src\dll\fuse\fuse_compat.c">
|
<ClCompile Include="..\..\src\dll\fuse\fuse_compat.c">
|
||||||
<Filter>Source\fuse</Filter>
|
<Filter>Source\fuse</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\dll\wksid.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\dll\launch.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\library.def">
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
@ -28,7 +28,7 @@ if ($key.Count -eq 1) {
|
|||||||
-File "$file"
|
-File "$file"
|
||||||
}
|
}
|
||||||
} elseif ($key.Count -eq 0) {
|
} elseif ($key.Count -eq 0) {
|
||||||
Write-Warning "$packageName has already been uninstalled by other means."
|
# Write-Warning "$packageName is not installed"
|
||||||
} elseif ($key.Count -gt 1) {
|
} elseif ($key.Count -gt 1) {
|
||||||
Write-Warning "Too many matching packages found! Package may not be uninstalled."
|
Write-Warning "Too many matching packages found! Package may not be uninstalled."
|
||||||
Write-Warning "Please alert package maintainer the following packages were matched:"
|
Write-Warning "Please alert package maintainer the following packages were matched:"
|
@ -1,16 +1,14 @@
|
|||||||
$ErrorActionPreference = 'Stop';
|
$ErrorActionPreference = 'Stop';
|
||||||
|
|
||||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||||
$fileLocation = @(Get-ChildItem $toolsDir -filter winfsp-*.msi)[0].FullName
|
. "$toolsdir\chocolateyHelper.ps1"
|
||||||
|
|
||||||
$packageArgs = @{
|
$packageArgs = @{
|
||||||
packageName = 'winfsp'
|
packageName = 'winfsp'
|
||||||
fileType = 'msi'
|
fileType = 'msi'
|
||||||
file = $fileLocation
|
file = @(Get-ChildItem $toolsDir -filter winfsp-*.msi)[0].FullName
|
||||||
silentArgs = "/qn /norestart INSTALLLEVEL=1000"
|
silentArgs = "/qn /norestart INSTALLLEVEL=1000"
|
||||||
validExitCodes = @(0, 3010, 1641)
|
validExitCodes = @(0, 3010, 1641)
|
||||||
}
|
}
|
||||||
|
|
||||||
Install-ChocolateyInstallPackage @packageArgs
|
Install-ChocolateyInstallPackage @packageArgs
|
||||||
|
|
||||||
Remove-Item -Force $packageArgs.file
|
Remove-Item -Force $packageArgs.file
|
||||||
|
4
build/choco/chocolateyUninstall.ps1
Normal file
4
build/choco/chocolateyUninstall.ps1
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
$ErrorActionPreference = 'Stop';
|
||||||
|
|
||||||
|
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||||
|
. "$toolsdir\chocolateyHelper.ps1"
|
@ -50,7 +50,8 @@ To verify installation:
|
|||||||
<file src="LICENSE.txt" target="tools" />
|
<file src="LICENSE.txt" target="tools" />
|
||||||
<file src="VERIFICATION.txt" target="tools" />
|
<file src="VERIFICATION.txt" target="tools" />
|
||||||
<file src="chocolateyInstall.ps1" target="tools" />
|
<file src="chocolateyInstall.ps1" target="tools" />
|
||||||
<file src="chocolateyBeforeModify.ps1" target="tools" />
|
<file src="chocolateyUninstall.ps1" target="tools" />
|
||||||
|
<file src="chocolateyHelper.ps1" target="tools" />
|
||||||
<file src="winfsp-$version$.msi" target="tools" />
|
<file src="winfsp-$version$.msi" target="tools" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
@ -4,6 +4,8 @@ This document contains a list of known file systems and file system libraries th
|
|||||||
|
|
||||||
== File Systems
|
== File Systems
|
||||||
|
|
||||||
|
- https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files
|
||||||
|
- https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive
|
||||||
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
|
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
|
||||||
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage
|
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage
|
||||||
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
|
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
|
||||||
@ -13,8 +15,7 @@ This document contains a list of known file systems and file system libraries th
|
|||||||
|
|
||||||
== File System Libraries
|
== File System Libraries
|
||||||
|
|
||||||
- https://github.com/billziss-gh/cgofuse[cgofuse] - Cross-platform FUSE library for Go
|
- https://github.com/billziss-gh/cgofuse[Go: cgofuse] - Cross-platform FUSE library for Go
|
||||||
- https://github.com/DuroSoft/fuse-bindings[fuse-bindings] - Fully maintained FUSE bindings for Node that aims to cover the entire FUSE api
|
- https://github.com/DuroSoft/fuse-bindings[Nodejs: fuse-bindings] - Fully maintained FUSE bindings for Node that aims to cover the entire FUSE api
|
||||||
- https://github.com/ui4j/fuse-jna[fuse-jna] - No-nonsense, actually-working Java bindings to FUSE using JNA
|
- https://github.com/SerCeMan/jnr-fuse[Java: jnr-fuse] - FUSE implementation in Java using Java Native Runtime (JNR)
|
||||||
- https://github.com/billziss-gh/fusepy[fusepy] - Simple ctypes bindings for FUSE
|
- https://github.com/billziss-gh/fusepy[Python: fusepy] - Simple ctypes bindings for FUSE
|
||||||
- https://github.com/yogendersolanki91/winfsp[WinFsp fork with .NET Layer] - by @yogendersolanki91
|
|
||||||
|
@ -95,7 +95,7 @@ if (!Success)
|
|||||||
|
|
||||||
In Release builds the +DEBUGTEST(90)+ macro will evaluate to +TRUE+ and the Cache Manager will be asked directly via +CcCanIWrite+ whether a WRITE should be deferred. In Debug builds the +DEBUGTEST(90)+ macro will evaluate to +FALSE+ sometimes (10% of the time) and the WRITE will be deferred, thus allowing us to test the retry code path.
|
In Release builds the +DEBUGTEST(90)+ macro will evaluate to +TRUE+ and the Cache Manager will be asked directly via +CcCanIWrite+ whether a WRITE should be deferred. In Debug builds the +DEBUGTEST(90)+ macro will evaluate to +FALSE+ sometimes (10% of the time) and the WRITE will be deferred, thus allowing us to test the retry code path.
|
||||||
|
|
||||||
== Compatibility Testing
|
== NTFS Compatibility Testing
|
||||||
|
|
||||||
WinFsp allows the creation of user mode file systems that exhibit behavior similar to NTFS. This means that Windows applications that use such a file system should not be able to tell the difference between NTFS and the WinFsp-based file system. OTOH specialized applications (such as Defrag) will not work properly on WinFsp file systems.
|
WinFsp allows the creation of user mode file systems that exhibit behavior similar to NTFS. This means that Windows applications that use such a file system should not be able to tell the difference between NTFS and the WinFsp-based file system. OTOH specialized applications (such as Defrag) will not work properly on WinFsp file systems.
|
||||||
|
|
||||||
@ -123,6 +123,12 @@ The goal of performance testing is to evaluate and understand how software behav
|
|||||||
|
|
||||||
WinFsp uses a tool called fsbench for this purpose. Fsbench is able to test specific scenarios, for example: "how long does it take to delete 1000 files?" Fsbench has been very useful for WinFsp and has helped improve its performance: in one situation it helped identify quadratic behavior with the MEMFS ReadDirectory operation, in another situation it helped fine tune the performance of the WinFsp I/O Queue.
|
WinFsp uses a tool called fsbench for this purpose. Fsbench is able to test specific scenarios, for example: "how long does it take to delete 1000 files?" Fsbench has been very useful for WinFsp and has helped improve its performance: in one situation it helped identify quadratic behavior with the MEMFS ReadDirectory operation, in another situation it helped fine tune the performance of the WinFsp I/O Queue.
|
||||||
|
|
||||||
|
== Backwards Compatibility testing
|
||||||
|
|
||||||
|
As the WinFsp API's mature it is important to verify that they remain backwards compatible with existing file system binaries. For this purpose binaries that have been compiled against earlier versions of WinFsp are used to verify that they run correctly against the latest version.
|
||||||
|
|
||||||
|
For example, in version v1.2B3 of WinFsp an +FSP_FUSE_CAP_STAT_EX+ FUSE extension was introduced. This can change the layout of +struct fuse_stat+ and is therefore a potentially dangerous change. To test against inadvertent breakage a FUSE file system binary that was compiled against v1.2B2 is regularly used to verify backwards compatibility.
|
||||||
|
|
||||||
== Code Analysis
|
== Code Analysis
|
||||||
|
|
||||||
WinFsp is regularly run under the Visual Studio's Code Analyzer. Any issues found are examined and if necessary acted upon.
|
WinFsp is regularly run under the Visual Studio's Code Analyzer. Any issues found are examined and if necessary acted upon.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.c
|
* @file tlib/callstack.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/callstack.h>
|
#include <tlib/callstack.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.h
|
* @file tlib/callstack.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
#ifndef TLIB_CALLSTACK_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/allfunc.h
|
* @file tlib/injected/allfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_ALLFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/curlfunc.c
|
* @file tlib/injected/curlfunc.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injected/curlfunc.h>
|
#include <tlib/injected/curlfunc.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/curlfunc.h
|
* @file tlib/injected/curlfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_CURLFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/stdfunc.c
|
* @file tlib/injected/stdfunc.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injected/stdfunc.h>
|
#include <tlib/injected/stdfunc.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injected/stdfunc.h
|
* @file tlib/injected/stdfunc.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
#ifndef TLIB_INJECTED_STDFUNC_H_INCLUDED
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injection.c
|
* @file tlib/injection.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injection.h>
|
#include <tlib/injection.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injection.h
|
* @file tlib/injection.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTE: This header may usefully be included multiple times.
|
/* NOTE: This header may usefully be included multiple times.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/testsuite.c
|
* @file tlib/testsuite.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/testsuite.h>
|
#include <tlib/testsuite.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/testsuite.h
|
* @file tlib/testsuite.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2017 Bill Zissimopoulos
|
* @copyright 2014-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
||||||
|
114
inc/fuse/fuse.h
114
inc/fuse/fuse.h
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -39,54 +39,82 @@ typedef int (*fuse_dirfil_t)(fuse_dirh_t h, const char *name,
|
|||||||
|
|
||||||
struct fuse_operations
|
struct fuse_operations
|
||||||
{
|
{
|
||||||
int (*getattr)(const char *path, struct fuse_stat *stbuf);
|
/* S - supported by WinFsp */
|
||||||
int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler);
|
/* S */ int (*getattr)(const char *path, struct fuse_stat *stbuf);
|
||||||
int (*readlink)(const char *path, char *buf, size_t size);
|
/* S */ int (*getdir)(const char *path, fuse_dirh_t h, fuse_dirfil_t filler);
|
||||||
int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
|
/* S */ int (*readlink)(const char *path, char *buf, size_t size);
|
||||||
int (*mkdir)(const char *path, fuse_mode_t mode);
|
/* S */ int (*mknod)(const char *path, fuse_mode_t mode, fuse_dev_t dev);
|
||||||
int (*unlink)(const char *path);
|
/* S */ int (*mkdir)(const char *path, fuse_mode_t mode);
|
||||||
int (*rmdir)(const char *path);
|
/* S */ int (*unlink)(const char *path);
|
||||||
int (*symlink)(const char *dstpath, const char *srcpath);
|
/* S */ int (*rmdir)(const char *path);
|
||||||
int (*rename)(const char *oldpath, const char *newpath);
|
/* S */ int (*symlink)(const char *dstpath, const char *srcpath);
|
||||||
int (*link)(const char *srcpath, const char *dstpath);
|
/* S */ int (*rename)(const char *oldpath, const char *newpath);
|
||||||
int (*chmod)(const char *path, fuse_mode_t mode);
|
/* _ */ int (*link)(const char *srcpath, const char *dstpath);
|
||||||
int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid);
|
/* S */ int (*chmod)(const char *path, fuse_mode_t mode);
|
||||||
int (*truncate)(const char *path, fuse_off_t size);
|
/* S */ int (*chown)(const char *path, fuse_uid_t uid, fuse_gid_t gid);
|
||||||
int (*utime)(const char *path, struct fuse_utimbuf *timbuf);
|
/* S */ int (*truncate)(const char *path, fuse_off_t size);
|
||||||
int (*open)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*utime)(const char *path, struct fuse_utimbuf *timbuf);
|
||||||
int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
|
/* S */ int (*open)(const char *path, struct fuse_file_info *fi);
|
||||||
|
/* S */ int (*read)(const char *path, char *buf, size_t size, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
|
/* S */ int (*write)(const char *path, const char *buf, size_t size, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
|
/* S */ int (*statfs)(const char *path, struct fuse_statvfs *stbuf);
|
||||||
int (*flush)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*flush)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*release)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*release)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi);
|
/* S */ int (*fsync)(const char *path, int datasync, struct fuse_file_info *fi);
|
||||||
int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
|
/* _ */ int (*setxattr)(const char *path, const char *name, const char *value, size_t size,
|
||||||
int flags);
|
int flags);
|
||||||
int (*getxattr)(const char *path, const char *name, char *value, size_t size);
|
/* _ */ int (*getxattr)(const char *path, const char *name, char *value, size_t size);
|
||||||
int (*listxattr)(const char *path, char *namebuf, size_t size);
|
/* _ */ int (*listxattr)(const char *path, char *namebuf, size_t size);
|
||||||
int (*removexattr)(const char *path, const char *name);
|
/* _ */ int (*removexattr)(const char *path, const char *name);
|
||||||
int (*opendir)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*opendir)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
|
/* S */ int (*readdir)(const char *path, void *buf, fuse_fill_dir_t filler, fuse_off_t off,
|
||||||
struct fuse_file_info *fi);
|
struct fuse_file_info *fi);
|
||||||
int (*releasedir)(const char *path, struct fuse_file_info *fi);
|
/* S */ int (*releasedir)(const char *path, struct fuse_file_info *fi);
|
||||||
int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
/* S */ int (*fsyncdir)(const char *path, int datasync, struct fuse_file_info *fi);
|
||||||
void *(*init)(struct fuse_conn_info *conn);
|
/* S */ void *(*init)(struct fuse_conn_info *conn);
|
||||||
void (*destroy)(void *data);
|
/* S */ void (*destroy)(void *data);
|
||||||
int (*access)(const char *path, int mask);
|
/* _ */ int (*access)(const char *path, int mask);
|
||||||
int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
/* S */ int (*create)(const char *path, fuse_mode_t mode, struct fuse_file_info *fi);
|
||||||
int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
/* S */ int (*ftruncate)(const char *path, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
/* S */ int (*fgetattr)(const char *path, struct fuse_stat *stbuf, struct fuse_file_info *fi);
|
||||||
int (*lock)(const char *path, struct fuse_file_info *fi, int cmd, struct fuse_flock *lock);
|
/* _ */ int (*lock)(const char *path,
|
||||||
int (*utimens)(const char *path, const struct fuse_timespec tv[2]);
|
struct fuse_file_info *fi, int cmd, struct fuse_flock *lock);
|
||||||
int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
|
/* S */ int (*utimens)(const char *path, const struct fuse_timespec tv[2]);
|
||||||
unsigned int flag_nullpath_ok:1;
|
/* _ */ int (*bmap)(const char *path, size_t blocksize, uint64_t *idx);
|
||||||
unsigned int flag_reserved:31;
|
/* _ */ unsigned int flag_nullpath_ok:1;
|
||||||
int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
|
/* _ */ unsigned int flag_nopath:1;
|
||||||
|
/* _ */ unsigned int flag_utime_omit_ok:1;
|
||||||
|
/* _ */ unsigned int flag_reserved:29;
|
||||||
|
/* _ */ int (*ioctl)(const char *path, int cmd, void *arg, struct fuse_file_info *fi,
|
||||||
unsigned int flags, void *data);
|
unsigned int flags, void *data);
|
||||||
int (*poll)(const char *path, struct fuse_file_info *fi,
|
/* _ */ int (*poll)(const char *path, struct fuse_file_info *fi,
|
||||||
struct fuse_pollhandle *ph, unsigned *reventsp);
|
struct fuse_pollhandle *ph, unsigned *reventsp);
|
||||||
|
/* FUSE 2.9 */
|
||||||
|
/* _ */ int (*write_buf)(const char *path,
|
||||||
|
struct fuse_bufvec *buf, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
|
/* _ */ int (*read_buf)(const char *path,
|
||||||
|
struct fuse_bufvec **bufp, size_t size, fuse_off_t off, struct fuse_file_info *fi);
|
||||||
|
/* _ */ int (*flock)(const char *path, struct fuse_file_info *, int op);
|
||||||
|
/* _ */ int (*fallocate)(const char *path, int mode, fuse_off_t off, fuse_off_t len,
|
||||||
|
struct fuse_file_info *fi);
|
||||||
|
/* OSXFUSE */
|
||||||
|
/* _ */ int (*reserved00)();
|
||||||
|
/* _ */ int (*reserved01)();
|
||||||
|
/* _ */ int (*reserved02)();
|
||||||
|
/* _ */ int (*statfs_x)(const char *path, struct fuse_statfs *stbuf);
|
||||||
|
/* _ */ int (*setvolname)(const char *volname);
|
||||||
|
/* _ */ int (*exchange)(const char *oldpath, const char *newpath, unsigned long flags);
|
||||||
|
/* _ */ int (*getxtimes)(const char *path,
|
||||||
|
struct fuse_timespec *bkuptime, struct fuse_timespec *crtime);
|
||||||
|
/* _ */ int (*setbkuptime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* S */ int (*setchgtime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* S */ int (*setcrtime)(const char *path, const struct fuse_timespec *tv);
|
||||||
|
/* S */ int (*chflags)(const char *path, uint32_t flags);
|
||||||
|
/* _ */ int (*setattr_x)(const char *path, struct fuse_setattr_x *attr);
|
||||||
|
/* _ */ int (*fsetattr_x)(const char *path, struct fuse_setattr_x *attr,
|
||||||
|
struct fuse_file_info *fi);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fuse_context
|
struct fuse_context
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -49,6 +49,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
#define FSP_FUSE_CAP_READDIR_PLUS (1 << 21) /* file system supports enhanced readdir */
|
||||||
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
#define FSP_FUSE_CAP_READ_ONLY (1 << 22) /* file system is marked read-only */
|
||||||
|
#define FSP_FUSE_CAP_STAT_EX (1 << 23) /* file system supports fuse_stat_ex */
|
||||||
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
#define FSP_FUSE_CAP_CASE_INSENSITIVE FUSE_CAP_CASE_INSENSITIVE
|
||||||
|
|
||||||
#define FUSE_IOCTL_COMPAT (1 << 0)
|
#define FUSE_IOCTL_COMPAT (1 << 0)
|
||||||
@ -56,6 +57,24 @@ extern "C" {
|
|||||||
#define FUSE_IOCTL_RETRY (1 << 2)
|
#define FUSE_IOCTL_RETRY (1 << 2)
|
||||||
#define FUSE_IOCTL_MAX_IOV 256
|
#define FUSE_IOCTL_MAX_IOV 256
|
||||||
|
|
||||||
|
/* from FreeBSD */
|
||||||
|
#define FSP_FUSE_UF_HIDDEN 0x00008000
|
||||||
|
#define FSP_FUSE_UF_READONLY 0x00001000
|
||||||
|
#define FSP_FUSE_UF_SYSTEM 0x00000080
|
||||||
|
#define FSP_FUSE_UF_ARCHIVE 0x00000800
|
||||||
|
#if !defined(UF_HIDDEN)
|
||||||
|
#define UF_HIDDEN FSP_FUSE_UF_HIDDEN
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_READONLY)
|
||||||
|
#define UF_READONLY FSP_FUSE_UF_READONLY
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_SYSTEM)
|
||||||
|
#define UF_SYSTEM FSP_FUSE_UF_SYSTEM
|
||||||
|
#endif
|
||||||
|
#if !defined(UF_ARCHIVE)
|
||||||
|
#define UF_ARCHIVE FSP_FUSE_UF_ARCHIVE
|
||||||
|
#endif
|
||||||
|
|
||||||
struct fuse_file_info
|
struct fuse_file_info
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
@ -85,6 +104,9 @@ struct fuse_conn_info
|
|||||||
struct fuse_session;
|
struct fuse_session;
|
||||||
struct fuse_chan;
|
struct fuse_chan;
|
||||||
struct fuse_pollhandle;
|
struct fuse_pollhandle;
|
||||||
|
struct fuse_bufvec;
|
||||||
|
struct fuse_statfs;
|
||||||
|
struct fuse_setattr_x;
|
||||||
|
|
||||||
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env);
|
FSP_FUSE_API int FSP_FUSE_API_NAME(fsp_fuse_version)(struct fsp_fuse_env *env);
|
||||||
FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env,
|
FSP_FUSE_API struct fuse_chan *FSP_FUSE_API_NAME(fsp_fuse_mount)(struct fsp_fuse_env *env,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file fuse/winfsp_fuse.h
|
* @file fuse/winfsp_fuse.h
|
||||||
* WinFsp FUSE compatible API.
|
* WinFsp FUSE compatible API.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -65,6 +65,27 @@ extern "C" {
|
|||||||
* to be usable from Cygwin.
|
* to be usable from Cygwin.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FSP_FUSE_STAT_FIELD_DEFN \
|
||||||
|
fuse_dev_t st_dev; \
|
||||||
|
fuse_ino_t st_ino; \
|
||||||
|
fuse_mode_t st_mode; \
|
||||||
|
fuse_nlink_t st_nlink; \
|
||||||
|
fuse_uid_t st_uid; \
|
||||||
|
fuse_gid_t st_gid; \
|
||||||
|
fuse_dev_t st_rdev; \
|
||||||
|
fuse_off_t st_size; \
|
||||||
|
struct fuse_timespec st_atim; \
|
||||||
|
struct fuse_timespec st_mtim; \
|
||||||
|
struct fuse_timespec st_ctim; \
|
||||||
|
fuse_blksize_t st_blksize; \
|
||||||
|
fuse_blkcnt_t st_blocks; \
|
||||||
|
struct fuse_timespec st_birthtim;
|
||||||
|
#define FSP_FUSE_STAT_EX_FIELD_DEFN \
|
||||||
|
FSP_FUSE_STAT_FIELD_DEFN \
|
||||||
|
uint32_t st_flags; \
|
||||||
|
uint32_t st_reserved32[3]; \
|
||||||
|
uint64_t st_reserved64[2];
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
|
||||||
typedef uint32_t fuse_uid_t;
|
typedef uint32_t fuse_uid_t;
|
||||||
@ -111,23 +132,17 @@ struct fuse_timespec
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(FSP_FUSE_USE_STAT_EX)
|
||||||
struct fuse_stat
|
struct fuse_stat
|
||||||
{
|
{
|
||||||
fuse_dev_t st_dev;
|
FSP_FUSE_STAT_FIELD_DEFN
|
||||||
fuse_ino_t st_ino;
|
|
||||||
fuse_mode_t st_mode;
|
|
||||||
fuse_nlink_t st_nlink;
|
|
||||||
fuse_uid_t st_uid;
|
|
||||||
fuse_gid_t st_gid;
|
|
||||||
fuse_dev_t st_rdev;
|
|
||||||
fuse_off_t st_size;
|
|
||||||
struct fuse_timespec st_atim;
|
|
||||||
struct fuse_timespec st_mtim;
|
|
||||||
struct fuse_timespec st_ctim;
|
|
||||||
fuse_blksize_t st_blksize;
|
|
||||||
fuse_blkcnt_t st_blocks;
|
|
||||||
struct fuse_timespec st_birthtim;
|
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct fuse_stat
|
||||||
|
{
|
||||||
|
FSP_FUSE_STAT_EX_FIELD_DEFN
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
struct fuse_statvfs
|
struct fuse_statvfs
|
||||||
@ -178,6 +193,7 @@ struct fuse_flock
|
|||||||
fsp_fuse_daemonize, \
|
fsp_fuse_daemonize, \
|
||||||
fsp_fuse_set_signal_handlers, \
|
fsp_fuse_set_signal_handlers, \
|
||||||
0/*conv_to_win_path*/, \
|
0/*conv_to_win_path*/, \
|
||||||
|
0/*winpid_to_pid*/, \
|
||||||
{ 0 }, \
|
{ 0 }, \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -188,6 +204,7 @@ struct fuse_flock
|
|||||||
fsp_fuse_daemonize, \
|
fsp_fuse_daemonize, \
|
||||||
fsp_fuse_set_signal_handlers, \
|
fsp_fuse_set_signal_handlers, \
|
||||||
0/*conv_to_win_path*/, \
|
0/*conv_to_win_path*/, \
|
||||||
|
0/*winpid_to_pid*/, \
|
||||||
{ 0 }, \
|
{ 0 }, \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -220,7 +237,14 @@ struct fuse_flock
|
|||||||
#define fuse_utimbuf utimbuf
|
#define fuse_utimbuf utimbuf
|
||||||
#define fuse_timespec timespec
|
#define fuse_timespec timespec
|
||||||
|
|
||||||
|
#if !defined(FSP_FUSE_USE_STAT_EX)
|
||||||
#define fuse_stat stat
|
#define fuse_stat stat
|
||||||
|
#else
|
||||||
|
struct fuse_stat
|
||||||
|
{
|
||||||
|
FSP_FUSE_STAT_EX_FIELD_DEFN
|
||||||
|
};
|
||||||
|
#endif
|
||||||
#define fuse_statvfs statvfs
|
#define fuse_statvfs statvfs
|
||||||
#define fuse_flock flock
|
#define fuse_flock flock
|
||||||
|
|
||||||
@ -231,6 +255,7 @@ struct fuse_flock
|
|||||||
fsp_fuse_daemonize, \
|
fsp_fuse_daemonize, \
|
||||||
fsp_fuse_set_signal_handlers, \
|
fsp_fuse_set_signal_handlers, \
|
||||||
fsp_fuse_conv_to_win_path, \
|
fsp_fuse_conv_to_win_path, \
|
||||||
|
fsp_fuse_winpid_to_pid, \
|
||||||
{ 0 }, \
|
{ 0 }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +268,11 @@ struct fuse_flock
|
|||||||
#error unsupported environment
|
#error unsupported environment
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct fuse_stat_ex
|
||||||
|
{
|
||||||
|
FSP_FUSE_STAT_EX_FIELD_DEFN
|
||||||
|
};
|
||||||
|
|
||||||
struct fsp_fuse_env
|
struct fsp_fuse_env
|
||||||
{
|
{
|
||||||
unsigned environment;
|
unsigned environment;
|
||||||
@ -251,7 +281,8 @@ struct fsp_fuse_env
|
|||||||
int (*daemonize)(int);
|
int (*daemonize)(int);
|
||||||
int (*set_signal_handlers)(void *);
|
int (*set_signal_handlers)(void *);
|
||||||
char *(*conv_to_win_path)(const char *);
|
char *(*conv_to_win_path)(const char *);
|
||||||
void (*reserved[3])();
|
fuse_pid_t (*winpid_to_pid)(uint32_t);
|
||||||
|
void (*reserved[2])();
|
||||||
};
|
};
|
||||||
|
|
||||||
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_signal_handler)(int sig);
|
FSP_FUSE_API void FSP_FUSE_API_NAME(fsp_fuse_signal_handler)(int sig);
|
||||||
@ -362,6 +393,13 @@ static inline char *fsp_fuse_conv_to_win_path(const char *path)
|
|||||||
0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/,
|
0/*CCP_POSIX_TO_WIN_A*/ | 0x100/*CCP_RELATIVE*/,
|
||||||
path);
|
path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline fuse_pid_t fsp_fuse_winpid_to_pid(uint32_t winpid)
|
||||||
|
{
|
||||||
|
pid_t cygwin_winpid_to_pid(int winpid);
|
||||||
|
pid_t pid = cygwin_winpid_to_pid(winpid);
|
||||||
|
return -1 != pid ? pid : (fuse_pid_t)winpid;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file winfsp/fsctl.h
|
* @file winfsp/fsctl.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -78,6 +78,9 @@ 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_PID(T) ((UINT32)(((T) >> 32) & 0xffffffff))
|
||||||
|
|
||||||
/* marshalling */
|
/* marshalling */
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4200) /* zero-sized array in struct/union */
|
#pragma warning(disable:4200) /* zero-sized array in struct/union */
|
||||||
@ -149,7 +152,8 @@ typedef struct
|
|||||||
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */
|
UINT32 PostCleanupWhenModifiedOnly:1; /* post Cleanup when a file was modified/deleted */
|
||||||
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
|
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
|
||||||
UINT32 AlwaysUseDoubleBuffering:1;
|
UINT32 AlwaysUseDoubleBuffering:1;
|
||||||
UINT32 KmReservedFlags:3;
|
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */
|
||||||
|
UINT32 KmReservedFlags:2;
|
||||||
/* user-mode flags */
|
/* user-mode flags */
|
||||||
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
||||||
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
|
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
|
||||||
@ -222,7 +226,7 @@ typedef struct
|
|||||||
UINT32 FileAttributes; /* file attributes for new files */
|
UINT32 FileAttributes; /* file attributes for new files */
|
||||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */
|
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* security descriptor for new files */
|
||||||
UINT64 AllocationSize; /* initial allocation size */
|
UINT64 AllocationSize; /* initial allocation size */
|
||||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
UINT64 AccessToken; /* request access token (PID,HANDLE) */
|
||||||
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} */
|
||||||
@ -315,7 +319,7 @@ typedef struct
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
FSP_FSCTL_TRANSACT_BUF NewFileName;
|
FSP_FSCTL_TRANSACT_BUF NewFileName;
|
||||||
UINT64 AccessToken; /* request access token (HANDLE) */
|
UINT64 AccessToken; /* request access token (PID,HANDLE) */
|
||||||
} Rename;
|
} Rename;
|
||||||
} Info;
|
} Info;
|
||||||
} SetInformation;
|
} SetInformation;
|
||||||
@ -344,6 +348,7 @@ typedef struct
|
|||||||
FSP_FSCTL_TRANSACT_BUF Pattern;
|
FSP_FSCTL_TRANSACT_BUF Pattern;
|
||||||
FSP_FSCTL_TRANSACT_BUF Marker;
|
FSP_FSCTL_TRANSACT_BUF Marker;
|
||||||
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
UINT32 CaseSensitive:1; /* FileName comparisons should be case-sensitive */
|
||||||
|
UINT32 PatternIsFileName:1; /* Pattern does not contain wildcards */
|
||||||
} QueryDirectory;
|
} QueryDirectory;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h>
|
* In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h>
|
||||||
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
|
* and link with the winfsp_x64.dll (or winfsp_x86.dll) library.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -802,12 +802,32 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*GetStreamInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext, PVOID Buffer, ULONG Length,
|
PVOID FileContext, PVOID Buffer, ULONG Length,
|
||||||
PULONG PBytesTransferred);
|
PULONG PBytesTransferred);
|
||||||
|
/**
|
||||||
|
* Get directory information for a single file or directory within a parent directory.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system on which this request is posted.
|
||||||
|
* @param FileContext
|
||||||
|
* The file context of the parent directory.
|
||||||
|
* @param FileName
|
||||||
|
* The name of the file or directory to get information for. This name is relative
|
||||||
|
* to the parent directory and is a single path component.
|
||||||
|
* @param DirInfo [out]
|
||||||
|
* Pointer to a structure that will receive the directory information on successful
|
||||||
|
* return from this call. This information includes the file name, but also file
|
||||||
|
* attributes, file times, etc.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS or error code.
|
||||||
|
*/
|
||||||
|
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileContext, PWSTR FileName,
|
||||||
|
FSP_FSCTL_DIR_INFO *DirInfo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This ensures that this interface will always contain 64 function pointers.
|
* This ensures that this interface will always contain 64 function pointers.
|
||||||
* Please update when changing the interface as it is important for future compatibility.
|
* Please update when changing the interface as it is important for future compatibility.
|
||||||
*/
|
*/
|
||||||
NTSTATUS (*Reserved[40])();
|
NTSTATUS (*Reserved[39])();
|
||||||
} FSP_FILE_SYSTEM_INTERFACE;
|
} FSP_FILE_SYSTEM_INTERFACE;
|
||||||
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
|
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
|
||||||
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
|
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
|
||||||
@ -961,14 +981,12 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
* The current operation context.
|
* The current operation context.
|
||||||
*/
|
*/
|
||||||
FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID);
|
FSP_API FSP_FILE_SYSTEM_OPERATION_CONTEXT *FspFileSystemGetOperationContext(VOID);
|
||||||
FSP_API PWSTR FspFileSystemMountPointF(FSP_FILE_SYSTEM *FileSystem);
|
|
||||||
static inline
|
static inline
|
||||||
PWSTR FspFileSystemMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
PWSTR FspFileSystemMountPoint(FSP_FILE_SYSTEM *FileSystem)
|
||||||
{
|
{
|
||||||
return FileSystem->MountPoint;
|
return FileSystem->MountPoint;
|
||||||
}
|
}
|
||||||
FSP_API NTSTATUS FspFileSystemEnterOperationF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API PWSTR FspFileSystemMountPointF(FSP_FILE_SYSTEM *FileSystem);
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
|
||||||
static inline
|
static inline
|
||||||
NTSTATUS FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
@ -978,7 +996,7 @@ NTSTATUS FspFileSystemEnterOperation(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
return FileSystem->EnterOperation(FileSystem, Request, Response);
|
return FileSystem->EnterOperation(FileSystem, Request, Response);
|
||||||
}
|
}
|
||||||
FSP_API NTSTATUS FspFileSystemLeaveOperationF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemEnterOperationF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
static inline
|
static inline
|
||||||
NTSTATUS FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -989,9 +1007,8 @@ NTSTATUS FspFileSystemLeaveOperation(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
return FileSystem->LeaveOperation(FileSystem, Request, Response);
|
return FileSystem->LeaveOperation(FileSystem, Request, Response);
|
||||||
}
|
}
|
||||||
FSP_API VOID FspFileSystemSetOperationGuardF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemLeaveOperationF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation,
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation);
|
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation,
|
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation,
|
||||||
@ -1000,6 +1017,9 @@ VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FileSystem->EnterOperation = EnterOperation;
|
FileSystem->EnterOperation = EnterOperation;
|
||||||
FileSystem->LeaveOperation = LeaveOperation;
|
FileSystem->LeaveOperation = LeaveOperation;
|
||||||
}
|
}
|
||||||
|
FSP_API VOID FspFileSystemSetOperationGuardF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION_GUARD *LeaveOperation);
|
||||||
/**
|
/**
|
||||||
* Set file system locking strategy.
|
* Set file system locking strategy.
|
||||||
*
|
*
|
||||||
@ -1010,17 +1030,14 @@ VOID FspFileSystemSetOperationGuard(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
* @see
|
* @see
|
||||||
* FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY
|
* FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY
|
||||||
*/
|
*/
|
||||||
FSP_API VOID FspFileSystemSetOperationGuardStrategyF(FSP_FILE_SYSTEM *FileSystem,
|
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy);
|
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemSetOperationGuardStrategy(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetOperationGuardStrategy(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
|
||||||
{
|
{
|
||||||
FileSystem->OpGuardStrategy = GuardStrategy;
|
FileSystem->OpGuardStrategy = GuardStrategy;
|
||||||
}
|
}
|
||||||
FSP_API VOID FspFileSystemSetOperationF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemSetOperationGuardStrategyF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
ULONG Index,
|
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy);
|
||||||
FSP_FILE_SYSTEM_OPERATION *Operation);
|
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
ULONG Index,
|
ULONG Index,
|
||||||
@ -1028,8 +1045,9 @@ VOID FspFileSystemSetOperation(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
{
|
{
|
||||||
FileSystem->Operations[Index] = Operation;
|
FileSystem->Operations[Index] = Operation;
|
||||||
}
|
}
|
||||||
FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemSetOperationF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
NTSTATUS *PDispatcherResult);
|
ULONG Index,
|
||||||
|
FSP_FILE_SYSTEM_OPERATION *Operation);
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
||||||
NTSTATUS *PDispatcherResult)
|
NTSTATUS *PDispatcherResult)
|
||||||
@ -1038,8 +1056,8 @@ VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
*PDispatcherResult = FileSystem->DispatcherResult;
|
*PDispatcherResult = FileSystem->DispatcherResult;
|
||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
}
|
}
|
||||||
FSP_API VOID FspFileSystemSetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
NTSTATUS DispatcherResult);
|
NTSTATUS *PDispatcherResult);
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
||||||
NTSTATUS DispatcherResult)
|
NTSTATUS DispatcherResult)
|
||||||
@ -1048,15 +1066,16 @@ VOID FspFileSystemSetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return;
|
return;
|
||||||
InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0);
|
InterlockedCompareExchange(&FileSystem->DispatcherResult, DispatcherResult, 0);
|
||||||
}
|
}
|
||||||
FSP_API VOID FspFileSystemSetDebugLogF(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemSetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
UINT32 DebugLog);
|
NTSTATUS DispatcherResult);
|
||||||
static inline
|
static inline
|
||||||
VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem,
|
VOID FspFileSystemSetDebugLog(FSP_FILE_SYSTEM *FileSystem,
|
||||||
UINT32 DebugLog)
|
UINT32 DebugLog)
|
||||||
{
|
{
|
||||||
FileSystem->DebugLog = DebugLog;
|
FileSystem->DebugLog = DebugLog;
|
||||||
}
|
}
|
||||||
FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID);
|
FSP_API VOID FspFileSystemSetDebugLogF(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
UINT32 DebugLog);
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
|
BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
|
||||||
{
|
{
|
||||||
@ -1065,6 +1084,29 @@ BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
|
|||||||
FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive ||
|
FspFsctlTransactCreateKind == Request->Kind && Request->Req.Create.CaseSensitive ||
|
||||||
FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive;
|
FspFsctlTransactQueryDirectoryKind == Request->Kind && Request->Req.QueryDirectory.CaseSensitive;
|
||||||
}
|
}
|
||||||
|
FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID);
|
||||||
|
/**
|
||||||
|
* Gets the originating process ID.
|
||||||
|
*
|
||||||
|
* Valid only during Create, Open and Rename requests when the target exists.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
UINT32 FspFileSystemOperationProcessId(VOID)
|
||||||
|
{
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request;
|
||||||
|
switch (Request->Kind)
|
||||||
|
{
|
||||||
|
case FspFsctlTransactCreateKind:
|
||||||
|
return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken);
|
||||||
|
case FspFsctlTransactSetInformationKind:
|
||||||
|
if (10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass)
|
||||||
|
return FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken);
|
||||||
|
/* fall through! */
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operations
|
* Operations
|
||||||
@ -1430,6 +1472,21 @@ NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPat
|
|||||||
FSP_API VOID FspPosixDeletePath(void *Path);
|
FSP_API VOID FspPosixDeletePath(void *Path);
|
||||||
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
||||||
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size);
|
||||||
|
static inline
|
||||||
|
VOID FspPosixFileTimeToUnixTime(UINT64 FileTime0, __int3264 UnixTime[2])
|
||||||
|
{
|
||||||
|
INT64 FileTime = (INT64)FileTime0 - 116444736000000000LL;
|
||||||
|
UnixTime[0] = (__int3264)(FileTime / 10000000);
|
||||||
|
UnixTime[1] = (__int3264)(FileTime % 10000000 * 100);
|
||||||
|
/* may produce negative nsec for times before UNIX epoch; strictly speaking this is incorrect */
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspPosixUnixTimeToFileTime(const __int3264 UnixTime[2], PUINT64 PFileTime)
|
||||||
|
{
|
||||||
|
INT64 FileTime = (INT64)UnixTime[0] * 10000000 + (INT64)UnixTime[1] / 100 +
|
||||||
|
116444736000000000LL;
|
||||||
|
*PFileTime = FileTime;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Path Handling
|
* Path Handling
|
||||||
@ -1618,6 +1675,19 @@ FSP_API VOID FspServiceStop(FSP_SERVICE *Service);
|
|||||||
* TRUE if the process is running in running user interactive mode.
|
* TRUE if the process is running in running user interactive mode.
|
||||||
*/
|
*/
|
||||||
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
||||||
|
/**
|
||||||
|
* Check if the supplied token is from the service context.
|
||||||
|
*
|
||||||
|
* @param Token
|
||||||
|
* Token to check. Pass NULL to check the current process token.
|
||||||
|
* @param PIsLocalSystem
|
||||||
|
* Pointer to a boolean that will receive a TRUE value if the token belongs to LocalSystem
|
||||||
|
* and FALSE otherwise. May be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the token is from the service context. STATUS_ACCESS_DENIED if it is not.
|
||||||
|
* Other error codes are possible.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem);
|
||||||
/**
|
/**
|
||||||
* Log a service message.
|
* Log a service message.
|
||||||
*
|
*
|
||||||
@ -1633,6 +1703,133 @@ FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
|||||||
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...);
|
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...);
|
||||||
FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap);
|
FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group Launch Control
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Call launcher pipe.
|
||||||
|
*
|
||||||
|
* This function is used to send a command to the launcher and receive a response.
|
||||||
|
*
|
||||||
|
* @param Command
|
||||||
|
* Launcher command to send. For example, the 'L' launcher command instructs
|
||||||
|
* the launcher to list all running service instances.
|
||||||
|
* @param Argc
|
||||||
|
* Command argument count. May be 0.
|
||||||
|
* @param Argv
|
||||||
|
* Command argument array. May be NULL.
|
||||||
|
* @param Argl
|
||||||
|
* Command argument length array. May be NULL. If this is NULL all command arguments
|
||||||
|
* are assumed to be NULL-terminated strings. It is also possible for specific arguments
|
||||||
|
* to be NULL-terminated; in this case pass -1 in the corresponding Argl position.
|
||||||
|
* @param Buffer
|
||||||
|
* Buffer that receives the command response. May be NULL.
|
||||||
|
* @param PSize
|
||||||
|
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it
|
||||||
|
* contains the number of bytes transferred. May be NULL.
|
||||||
|
* @param PLauncherError
|
||||||
|
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
|
||||||
|
* returns an error. Other status codes indicate a communication error. Launcher errors are
|
||||||
|
* reported through PLauncherError.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspLaunchCallLauncherPipe(
|
||||||
|
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
|
||||||
|
PWSTR Buffer, PULONG PSize, PULONG PLauncherError);
|
||||||
|
/**
|
||||||
|
* Start a service instance.
|
||||||
|
*
|
||||||
|
* @param ClassName
|
||||||
|
* Class name of the service instance to start.
|
||||||
|
* @param InstanceName
|
||||||
|
* Instance name of the service instance to start.
|
||||||
|
* @param Argc
|
||||||
|
* Service instance argument count. May be 0.
|
||||||
|
* @param Argv
|
||||||
|
* Service instance argument array. May be NULL.
|
||||||
|
* @param HasSecret
|
||||||
|
* Whether the last argument in Argv is assumed to be a secret (e.g. password) or not.
|
||||||
|
* Secrets are passed to service instances through standard input rather than the command
|
||||||
|
* line.
|
||||||
|
* @param PLauncherError
|
||||||
|
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
|
||||||
|
* returns an error. Other status codes indicate a communication error. Launcher errors are
|
||||||
|
* reported through PLauncherError.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspLaunchStart(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0,
|
||||||
|
BOOLEAN HasSecret,
|
||||||
|
PULONG PLauncherError);
|
||||||
|
/**
|
||||||
|
* Stop a service instance.
|
||||||
|
*
|
||||||
|
* @param ClassName
|
||||||
|
* Class name of the service instance to stop.
|
||||||
|
* @param InstanceName
|
||||||
|
* Instance name of the service instance to stop.
|
||||||
|
* @param PLauncherError
|
||||||
|
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
|
||||||
|
* returns an error. Other status codes indicate a communication error. Launcher errors are
|
||||||
|
* reported through PLauncherError.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspLaunchStop(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName,
|
||||||
|
PULONG PLauncherError);
|
||||||
|
/**
|
||||||
|
* Get information about a service instance.
|
||||||
|
*
|
||||||
|
* The information is a list of NULL-terminated strings: the class name of the service instance,
|
||||||
|
* the instance name of the service instance and the full command line used to start the service
|
||||||
|
* instance.
|
||||||
|
*
|
||||||
|
* @param ClassName
|
||||||
|
* Class name of the service instance to stop.
|
||||||
|
* @param InstanceName
|
||||||
|
* Instance name of the service instance to stop.
|
||||||
|
* @param Buffer
|
||||||
|
* Buffer that receives the command response. May be NULL.
|
||||||
|
* @param PSize
|
||||||
|
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it
|
||||||
|
* contains the number of bytes transferred. May be NULL.
|
||||||
|
* @param PLauncherError
|
||||||
|
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
|
||||||
|
* returns an error. Other status codes indicate a communication error. Launcher errors are
|
||||||
|
* reported through PLauncherError.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspLaunchGetInfo(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName,
|
||||||
|
PWSTR Buffer, PULONG PSize,
|
||||||
|
PULONG PLauncherError);
|
||||||
|
/**
|
||||||
|
* List service instances.
|
||||||
|
*
|
||||||
|
* The information is a list of pairs of NULL-terminated strings. Each pair contains the class
|
||||||
|
* name and instance name of a service instance. All currently running service instances are
|
||||||
|
* listed.
|
||||||
|
*
|
||||||
|
* @param Buffer
|
||||||
|
* Buffer that receives the command response. May be NULL.
|
||||||
|
* @param PSize
|
||||||
|
* Pointer to a ULONG. On input it contains the size of the Buffer. On output it
|
||||||
|
* contains the number of bytes transferred. May be NULL.
|
||||||
|
* @param PLauncherError
|
||||||
|
* Receives the launcher error if any. This is always a Win32 error code. May not be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher
|
||||||
|
* returns an error. Other status codes indicate a communication error. Launcher errors are
|
||||||
|
* reported through PLauncherError.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspLaunchGetNameList(
|
||||||
|
PWSTR Buffer, PULONG PSize,
|
||||||
|
PULONG PLauncherError);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility
|
* Utility
|
||||||
*/
|
*/
|
||||||
@ -1643,6 +1840,7 @@ FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap);
|
|||||||
FSP_API VOID FspDebugLogSetHandle(HANDLE Handle);
|
FSP_API VOID FspDebugLogSetHandle(HANDLE Handle);
|
||||||
FSP_API VOID FspDebugLog(const char *Format, ...);
|
FSP_API VOID FspDebugLog(const char *Format, ...);
|
||||||
FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||||
|
FSP_API VOID FspDebugLogSid(const char *format, PSID Sid);
|
||||||
FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime);
|
FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime);
|
||||||
FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request);
|
FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file winfsp/winfsp.hpp
|
* @file winfsp/winfsp.hpp
|
||||||
* WinFsp C++ Layer.
|
* WinFsp C++ Layer.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -22,7 +22,9 @@ cygport:
|
|||||||
dist: cygport
|
dist: cygport
|
||||||
case $(shell uname -m) in \
|
case $(shell uname -m) in \
|
||||||
x86_64)\
|
x86_64)\
|
||||||
|
mkdir -p dist/x64 && \
|
||||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\
|
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\
|
||||||
*)\
|
*)\
|
||||||
|
mkdir -p dist/x86 && \
|
||||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\
|
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\
|
||||||
esac
|
esac
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file cygfuse/cygfuse.c
|
* @file cygfuse/cygfuse.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
BIN
opt/cygfuse/dist/x64/fuse-2.8-5.tar.xz
vendored
BIN
opt/cygfuse/dist/x64/fuse-2.8-5.tar.xz
vendored
Binary file not shown.
BIN
opt/cygfuse/dist/x64/fuse-2.8-7.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x64/fuse-2.8-7.tar.xz
vendored
Normal file
Binary file not shown.
BIN
opt/cygfuse/dist/x86/fuse-2.8-5.tar.xz
vendored
BIN
opt/cygfuse/dist/x86/fuse-2.8-5.tar.xz
vendored
Binary file not shown.
BIN
opt/cygfuse/dist/x86/fuse-2.8-7.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x86/fuse-2.8-7.tar.xz
vendored
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
NAME="fuse"
|
NAME="fuse"
|
||||||
VERSION=2.8
|
VERSION=2.8
|
||||||
RELEASE=5
|
RELEASE=7
|
||||||
CATEGORY="Utils"
|
CATEGORY="Utils"
|
||||||
SUMMARY="WinFsp-FUSE compatibility layer"
|
SUMMARY="WinFsp-FUSE compatibility layer"
|
||||||
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin."
|
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin."
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/debug.c
|
* @file dll/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -63,6 +63,21 @@ FSP_API VOID FspDebugLogSD(const char *format, PSECURITY_DESCRIPTOR SecurityDesc
|
|||||||
FspDebugLog(format, "invalid security descriptor");
|
FspDebugLog(format, "invalid security descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspDebugLogSid(const char *format, PSID Sid)
|
||||||
|
{
|
||||||
|
char *S;
|
||||||
|
|
||||||
|
if (0 == Sid)
|
||||||
|
FspDebugLog(format, "null SID");
|
||||||
|
else if (ConvertSidToStringSidA(Sid, &S))
|
||||||
|
{
|
||||||
|
FspDebugLog(format, S);
|
||||||
|
LocalFree(S);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FspDebugLog(format, "invalid SID");
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime)
|
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime)
|
||||||
{
|
{
|
||||||
SYSTEMTIME SystemTime;
|
SYSTEMTIME SystemTime;
|
||||||
@ -302,7 +317,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c%c%c] \"%S\", "
|
FspDebugLog("%S[TID=%04lx]: %p: >>Create [%c%c%c%c%c%c] \"%S\", "
|
||||||
"%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, "
|
"%s, CreateOptions=%lx, FileAttributes=%lx, Security=%s%s%s, "
|
||||||
"AllocationSize=%lx:%lx, "
|
"AllocationSize=%lx:%lx, "
|
||||||
"AccessToken=%p, DesiredAccess=%lx, GrantedAccess=%lx, "
|
"AccessToken=%p[PID=%lx], DesiredAccess=%lx, GrantedAccess=%lx, "
|
||||||
"ShareAccess=%lx\n",
|
"ShareAccess=%lx\n",
|
||||||
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
|
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
|
||||||
Request->Req.Create.UserMode ? 'U' : 'K',
|
Request->Req.Create.UserMode ? 'U' : 'K',
|
||||||
@ -319,7 +334,8 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
Sddl ? Sddl : "NULL",
|
Sddl ? Sddl : "NULL",
|
||||||
Sddl ? "\"" : "",
|
Sddl ? "\"" : "",
|
||||||
MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize),
|
MAKE_UINT32_PAIR(Request->Req.Create.AllocationSize),
|
||||||
(PVOID)Request->Req.Create.AccessToken,
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken),
|
||||||
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.Create.AccessToken),
|
||||||
Request->Req.Create.DesiredAccess,
|
Request->Req.Create.DesiredAccess,
|
||||||
Request->Req.Create.GrantedAccess,
|
Request->Req.Create.GrantedAccess,
|
||||||
Request->Req.Create.ShareAccess);
|
Request->Req.Create.ShareAccess);
|
||||||
@ -459,7 +475,7 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
break;
|
break;
|
||||||
case 10/*FileRenameInformation*/:
|
case 10/*FileRenameInformation*/:
|
||||||
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [Rename] %s%S%s%s, "
|
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [Rename] %s%S%s%s, "
|
||||||
"NewFileName=\"%S\", AccessToken=%p\n",
|
"NewFileName=\"%S\", AccessToken=%p[PID=%lx]\n",
|
||||||
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
|
FspDiagIdent(), GetCurrentThreadId(), (PVOID)Request->Hint,
|
||||||
Request->FileName.Size ? "\"" : "",
|
Request->FileName.Size ? "\"" : "",
|
||||||
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
|
Request->FileName.Size ? (PWSTR)Request->Buffer : L"",
|
||||||
@ -468,7 +484,8 @@ FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request)
|
|||||||
Request->Req.SetInformation.UserContext, Request->Req.SetInformation.UserContext2,
|
Request->Req.SetInformation.UserContext, Request->Req.SetInformation.UserContext2,
|
||||||
UserContextBuf),
|
UserContextBuf),
|
||||||
(PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
|
(PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset),
|
||||||
(PVOID)Request->Req.SetInformation.Info.Rename.AccessToken);
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.SetInformation.Info.Rename.AccessToken),
|
||||||
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(Request->Req.SetInformation.Info.Rename.AccessToken));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [INVALID] %s%S%s%s\n",
|
FspDebugLog("%S[TID=%04lx]: %p: >>SetInformation [INVALID] %s%S%s%s\n",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/dirbuf.c
|
* @file dll/dirbuf.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/eventlog.c
|
* @file dll/eventlog.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
79
src/dll/fs.c
79
src/dll/fs.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fs.c
|
* @file dll/fs.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -187,17 +187,62 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
MemFree(FileSystem);
|
MemFree(FileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFileSystemLauncherDefineDosDevice(
|
||||||
|
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
|
||||||
|
{
|
||||||
|
if (2 != lstrlenW(MountPoint) ||
|
||||||
|
FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= lstrlenW(VolumeName))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
WCHAR Argv0[4];
|
||||||
|
PWSTR Argv[2];
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG ErrorCode;
|
||||||
|
|
||||||
|
Argv0[0] = Sign;
|
||||||
|
Argv0[1] = MountPoint[0];
|
||||||
|
Argv0[2] = MountPoint[1];
|
||||||
|
Argv0[3] = L'\0';
|
||||||
|
|
||||||
|
Argv[0] = Argv0;
|
||||||
|
Argv[1] = VolumeName;
|
||||||
|
|
||||||
|
Result = FspLaunchCallLauncherPipe('D', 2, Argv, 0, 0, 0, &ErrorCode);
|
||||||
|
return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
||||||
PHANDLE PMountHandle)
|
PHANDLE PMountHandle)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN IsLocalSystem, IsServiceContext;
|
||||||
|
|
||||||
*PMountHandle = 0;
|
*PMountHandle = 0;
|
||||||
|
|
||||||
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
Result = FspServiceContextCheck(0, &IsLocalSystem);
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
|
||||||
|
if (IsServiceContext)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can create global drives.
|
||||||
|
*
|
||||||
|
* In this case the launcher will also add DELETE access to the drive symlink
|
||||||
|
* for us, so that we can make it temporary below.
|
||||||
|
*/
|
||||||
|
Result = FspFileSystemLauncherDefineDosDevice(L'+', MountPoint, VolumeName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != FspNtOpenSymbolicLinkObject)
|
if (0 != FspNtOpenSymbolicLinkObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
|
||||||
WCHAR SymlinkBuf[6];
|
WCHAR SymlinkBuf[6];
|
||||||
UNICODE_STRING Symlink;
|
UNICODE_STRING Symlink;
|
||||||
OBJECT_ATTRIBUTES Obja;
|
OBJECT_ATTRIBUTES Obja;
|
||||||
@ -224,6 +269,13 @@ static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HACK:
|
||||||
|
*
|
||||||
|
* Handles do not use the low 2 bits (unless they are console handles).
|
||||||
|
* Abuse this fact to remember that we are running in the service context.
|
||||||
|
*/
|
||||||
|
*PMountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)*PMountHandle | IsServiceContext);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,8 +463,18 @@ exit:
|
|||||||
|
|
||||||
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
||||||
{
|
{
|
||||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
BOOLEAN IsServiceContext = 0 != ((DWORD)(UINT_PTR)MountHandle & 1);
|
||||||
MountPoint, VolumeName);
|
MountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)MountHandle & ~1);
|
||||||
|
if (IsServiceContext)
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can remove global drives.
|
||||||
|
*/
|
||||||
|
FspFileSystemLauncherDefineDosDevice(L'-', MountPoint, VolumeName);
|
||||||
|
else
|
||||||
|
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
|
MountPoint, VolumeName);
|
||||||
|
|
||||||
if (0 != MountHandle)
|
if (0 != MountHandle)
|
||||||
FspNtClose(MountHandle);
|
FspNtClose(MountHandle);
|
||||||
@ -683,3 +745,8 @@ FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID)
|
|||||||
{
|
{
|
||||||
return FspFileSystemIsOperationCaseSensitive();
|
return FspFileSystemIsOperationCaseSensitive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID)
|
||||||
|
{
|
||||||
|
return FspFileSystemOperationProcessId();
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsctl.c
|
* @file dll/fsctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -284,7 +284,7 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
* This function adds an ACE that allows Everyone to start a service.
|
* This function adds an ACE that allows Everyone to start a service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PSID WorldSid = 0;
|
PSID WorldSid;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
EXPLICIT_ACCESSW AccessEntry;
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
@ -296,18 +296,12 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
/* get the Everyone (World) SID */
|
/* get the Everyone (World) SID */
|
||||||
Size = SECURITY_MAX_SID_SIZE;
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
WorldSid = MemAlloc(Size);
|
|
||||||
if (0 == WorldSid)
|
if (0 == WorldSid)
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (!CreateWellKnownSid(WinWorldSid, 0, WorldSid, &Size))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the service security descriptor DACL */
|
/* get the service security descriptor DACL */
|
||||||
Size = 0;
|
Size = 0;
|
||||||
@ -394,7 +388,6 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
exit:
|
exit:
|
||||||
LocalFree(NewSecurityDescriptor);
|
LocalFree(NewSecurityDescriptor);
|
||||||
MemFree(SecurityDescriptor);
|
MemFree(SecurityDescriptor);
|
||||||
MemFree(WorldSid);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsop.c
|
* @file dll/fsop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1121,6 +1121,36 @@ FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFileSystemOpQueryDirectory_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileContext, PWSTR FileName,
|
||||||
|
PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
FSP_FSCTL_DIR_INFO V;
|
||||||
|
UINT8 B[sizeof(FSP_FSCTL_DIR_INFO) + 255 * sizeof(WCHAR)];
|
||||||
|
} DirInfoBuf;
|
||||||
|
FSP_FSCTL_DIR_INFO *DirInfo = &DirInfoBuf.V;
|
||||||
|
|
||||||
|
/* The FSD will never send us a Marker that we need to worry about! */
|
||||||
|
|
||||||
|
memset(DirInfo, 0, sizeof *DirInfo);
|
||||||
|
Result = FileSystem->Interface->GetDirInfoByName(FileSystem, FileContext, FileName, DirInfo);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (FspFileSystemAddDirInfo(DirInfo, Buffer, Length, PBytesTransferred))
|
||||||
|
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
||||||
|
}
|
||||||
|
else if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
FspFileSystemAddDirInfo(0, Buffer, Length, PBytesTransferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
@ -1131,15 +1161,24 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
BytesTransferred = 0;
|
BytesTransferred = 0;
|
||||||
Result = FileSystem->Interface->ReadDirectory(FileSystem,
|
if (0 != FileSystem->Interface->GetDirInfoByName &&
|
||||||
(PVOID)ValOfFileContext(Request->Req.QueryDirectory),
|
0 != Request->Req.QueryDirectory.Pattern.Size && Request->Req.QueryDirectory.PatternIsFileName)
|
||||||
0 != Request->Req.QueryDirectory.Pattern.Size ?
|
Result = FspFileSystemOpQueryDirectory_GetDirInfoByName(FileSystem,
|
||||||
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset) : 0,
|
(PVOID)ValOfFileContext(Request->Req.QueryDirectory),
|
||||||
0 != Request->Req.QueryDirectory.Marker.Size ?
|
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset),
|
||||||
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset) : 0,
|
(PVOID)Request->Req.QueryDirectory.Address,
|
||||||
(PVOID)Request->Req.QueryDirectory.Address,
|
Request->Req.QueryDirectory.Length,
|
||||||
Request->Req.QueryDirectory.Length,
|
&BytesTransferred);
|
||||||
&BytesTransferred);
|
else
|
||||||
|
Result = FileSystem->Interface->ReadDirectory(FileSystem,
|
||||||
|
(PVOID)ValOfFileContext(Request->Req.QueryDirectory),
|
||||||
|
0 != Request->Req.QueryDirectory.Pattern.Size ?
|
||||||
|
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset) : 0,
|
||||||
|
0 != Request->Req.QueryDirectory.Marker.Size ?
|
||||||
|
(PWSTR)(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset) : 0,
|
||||||
|
(PVOID)Request->Req.QueryDirectory.Address,
|
||||||
|
Request->Req.QueryDirectory.Length,
|
||||||
|
&BytesTransferred);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse.c
|
* @file dll/fuse/fuse.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -283,6 +283,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
context->private_data = f->data;
|
context->private_data = f->data;
|
||||||
context->uid = -1;
|
context->uid = -1;
|
||||||
context->gid = -1;
|
context->gid = -1;
|
||||||
|
context->pid = -1;
|
||||||
|
|
||||||
memset(&conn, 0, sizeof conn);
|
memset(&conn, 0, sizeof conn);
|
||||||
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
|
conn.proto_major = 7; /* pretend that we are FUSE kernel protocol 7.12 */
|
||||||
@ -298,12 +299,21 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
FUSE_CAP_DONT_MASK |
|
FUSE_CAP_DONT_MASK |
|
||||||
FSP_FUSE_CAP_READDIR_PLUS |
|
FSP_FUSE_CAP_READDIR_PLUS |
|
||||||
FSP_FUSE_CAP_READ_ONLY |
|
FSP_FUSE_CAP_READ_ONLY |
|
||||||
|
FSP_FUSE_CAP_STAT_EX |
|
||||||
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
FSP_FUSE_CAP_CASE_INSENSITIVE;
|
||||||
if (0 != f->ops.init)
|
if (0 != f->ops.init)
|
||||||
{
|
{
|
||||||
context->private_data = f->data = f->ops.init(&conn);
|
context->private_data = f->data = f->ops.init(&conn);
|
||||||
f->VolumeParams.ReadOnlyVolume = 0 != (conn.want & FSP_FUSE_CAP_READ_ONLY);
|
f->VolumeParams.ReadOnlyVolume = 0 != (conn.want & FSP_FUSE_CAP_READ_ONLY);
|
||||||
f->VolumeParams.CaseSensitiveSearch = 0 == (conn.want & FSP_FUSE_CAP_CASE_INSENSITIVE);
|
f->VolumeParams.CaseSensitiveSearch = 0 == (conn.want & FSP_FUSE_CAP_CASE_INSENSITIVE);
|
||||||
|
if (!f->VolumeParams.CaseSensitiveSearch)
|
||||||
|
/*
|
||||||
|
* Disable GetDirInfoByName when file system is case-insensitive.
|
||||||
|
* The reason is that Windows always sends us queries with uppercase
|
||||||
|
* file names in GetDirInfoByName and we have no way in FUSE to normalize
|
||||||
|
* those file names when embedding them in FSP_FSCTL_DIR_INFO.
|
||||||
|
*/
|
||||||
|
f->VolumeParams.PassQueryDirectoryFileName = FALSE;
|
||||||
f->conn_want = conn.want;
|
f->conn_want = conn.want;
|
||||||
}
|
}
|
||||||
f->fsinit = TRUE;
|
f->fsinit = TRUE;
|
||||||
@ -331,7 +341,7 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
}
|
}
|
||||||
if (0 != f->ops.getattr)
|
if (0 != f->ops.getattr)
|
||||||
{
|
{
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof stbuf);
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
@ -345,14 +355,12 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
if (0 == f->VolumeParams.VolumeCreationTime)
|
if (0 == f->VolumeParams.VolumeCreationTime)
|
||||||
{
|
{
|
||||||
if (0 != stbuf.st_birthtim.tv_sec)
|
if (0 != stbuf.st_birthtim.tv_sec)
|
||||||
f->VolumeParams.VolumeCreationTime =
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim,
|
||||||
Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 +
|
&f->VolumeParams.VolumeCreationTime);
|
||||||
stbuf.st_birthtim.tv_nsec / 100;
|
|
||||||
else
|
else
|
||||||
if (0 != stbuf.st_ctim.tv_sec)
|
if (0 != stbuf.st_ctim.tv_sec)
|
||||||
f->VolumeParams.VolumeCreationTime =
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim,
|
||||||
Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 +
|
&f->VolumeParams.VolumeCreationTime);
|
||||||
stbuf.st_ctim.tv_nsec / 100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,12 +610,14 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
|
|||||||
if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout)
|
if (!opt_data.set_FileInfoTimeout && opt_data.set_attr_timeout)
|
||||||
opt_data.VolumeParams.FileInfoTimeout = opt_data.set_attr_timeout * 1000;
|
opt_data.VolumeParams.FileInfoTimeout = opt_data.set_attr_timeout * 1000;
|
||||||
opt_data.VolumeParams.CaseSensitiveSearch = TRUE;
|
opt_data.VolumeParams.CaseSensitiveSearch = TRUE;
|
||||||
|
opt_data.VolumeParams.CasePreservedNames = TRUE;
|
||||||
opt_data.VolumeParams.PersistentAcls = TRUE;
|
opt_data.VolumeParams.PersistentAcls = TRUE;
|
||||||
opt_data.VolumeParams.ReparsePoints = TRUE;
|
opt_data.VolumeParams.ReparsePoints = TRUE;
|
||||||
opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE;
|
opt_data.VolumeParams.ReparsePointsAccessCheck = FALSE;
|
||||||
opt_data.VolumeParams.NamedStreams = FALSE;
|
opt_data.VolumeParams.NamedStreams = FALSE;
|
||||||
opt_data.VolumeParams.ReadOnlyVolume = FALSE;
|
opt_data.VolumeParams.ReadOnlyVolume = FALSE;
|
||||||
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
|
opt_data.VolumeParams.PostCleanupWhenModifiedOnly = TRUE;
|
||||||
|
opt_data.VolumeParams.PassQueryDirectoryFileName = TRUE;
|
||||||
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
|
opt_data.VolumeParams.UmFileContextIsUserContext2 = TRUE;
|
||||||
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
|
if (L'\0' == opt_data.VolumeParams.FileSystemName[0])
|
||||||
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
|
memcpy(opt_data.VolumeParams.FileSystemName, L"FUSE", 5 * sizeof(WCHAR));
|
||||||
@ -737,7 +747,6 @@ FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *env)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
context = FSP_FUSE_CONTEXT_FROM_HDR(contexthdr);
|
context = FSP_FUSE_CONTEXT_FROM_HDR(contexthdr);
|
||||||
context->pid = -1;
|
|
||||||
|
|
||||||
TlsSetValue(fsp_fuse_tlskey, context);
|
TlsSetValue(fsp_fuse_tlskey, context);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_compat.c
|
* @file dll/fuse/fuse_compat.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_intf.c
|
* @file dll/fuse/fuse_intf.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -112,10 +112,10 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct fuse_context *context;
|
struct fuse_context *context;
|
||||||
struct fsp_fuse_context_header *contexthdr;
|
struct fsp_fuse_context_header *contexthdr;
|
||||||
char *PosixPath = 0;
|
char *PosixPath = 0;
|
||||||
UINT32 Uid = -1, Gid = -1;
|
UINT32 Uid = -1, Gid = -1, Pid = -1;
|
||||||
PWSTR FileName = 0, Suffix;
|
PWSTR FileName = 0, Suffix;
|
||||||
WCHAR Root[2] = L"\\";
|
WCHAR Root[2] = L"\\";
|
||||||
HANDLE Token = 0;
|
UINT64 AccessToken = 0;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
if (FspFsctlTransactCreateKind == Request->Kind)
|
||||||
@ -124,13 +124,13 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root);
|
FspPathSuffix((PWSTR)Request->Buffer, &FileName, &Suffix, Root);
|
||||||
else
|
else
|
||||||
FileName = (PWSTR)Request->Buffer;
|
FileName = (PWSTR)Request->Buffer;
|
||||||
Token = (HANDLE)Request->Req.Create.AccessToken;
|
AccessToken = Request->Req.Create.AccessToken;
|
||||||
}
|
}
|
||||||
else if (FspFsctlTransactSetInformationKind == Request->Kind &&
|
else if (FspFsctlTransactSetInformationKind == Request->Kind &&
|
||||||
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass)
|
10/*FileRenameInformation*/ == Request->Req.SetInformation.FileInformationClass)
|
||||||
{
|
{
|
||||||
FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset);
|
FileName = (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset);
|
||||||
Token = (HANDLE)Request->Req.SetInformation.Info.Rename.AccessToken;
|
AccessToken = Request->Req.SetInformation.Info.Rename.AccessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != FileName)
|
if (0 != FileName)
|
||||||
@ -142,11 +142,16 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Token)
|
if (0 != AccessToken)
|
||||||
{
|
{
|
||||||
Result = fsp_fuse_get_token_uidgid(Token, TokenUser, &Uid, &Gid);
|
Result = fsp_fuse_get_token_uidgid(
|
||||||
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(AccessToken),
|
||||||
|
TokenUser,
|
||||||
|
&Uid, &Gid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
Pid = FSP_FSCTL_TRANSACT_REQ_TOKEN_PID(AccessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
context = fsp_fuse_get_context(f->env);
|
context = fsp_fuse_get_context(f->env);
|
||||||
@ -162,6 +167,7 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
context->private_data = f->data;
|
context->private_data = f->data;
|
||||||
context->uid = Uid;
|
context->uid = Uid;
|
||||||
context->gid = Gid;
|
context->gid = Gid;
|
||||||
|
context->pid = 0 != f->env->winpid_to_pid ? f->env->winpid_to_pid(Pid) : Pid;
|
||||||
|
|
||||||
contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
|
contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
|
||||||
contexthdr->PosixPath = PosixPath;
|
contexthdr->PosixPath = PosixPath;
|
||||||
@ -189,6 +195,7 @@ NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
context->private_data = 0;
|
context->private_data = 0;
|
||||||
context->uid = -1;
|
context->uid = -1;
|
||||||
context->gid = -1;
|
context->gid = -1;
|
||||||
|
context->pid = -1;
|
||||||
|
|
||||||
contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
|
contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
|
||||||
if (0 != contexthdr->PosixPath)
|
if (0 != contexthdr->PosixPath)
|
||||||
@ -212,7 +219,7 @@ static NTSTATUS fsp_fuse_intf_NewHiddenName(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct { UINT32 V[4]; } Values;
|
struct { UINT32 V[4]; } Values;
|
||||||
UUID Uuid;
|
UUID Uuid;
|
||||||
} UuidBuf;
|
} UuidBuf;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err, maxtries = 3;
|
int err, maxtries = 3;
|
||||||
|
|
||||||
*PPosixHiddenPath = 0;
|
*PPosixHiddenPath = 0;
|
||||||
@ -284,7 +291,7 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
char *PosixDotPath = 0;
|
char *PosixDotPath = 0;
|
||||||
size_t Length;
|
size_t Length;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
int err;
|
int err;
|
||||||
BOOLEAN Result = FALSE;
|
BOOLEAN Result = FALSE;
|
||||||
|
|
||||||
@ -297,6 +304,7 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
PosixDotPath[Length + 1] = '.';
|
PosixDotPath[Length + 1] = '.';
|
||||||
PosixDotPath[Length + 2] = '\0';
|
PosixDotPath[Length + 2] = '\0';
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
if (0 != f->ops.getattr)
|
if (0 != f->ops.getattr)
|
||||||
err = f->ops.getattr(PosixDotPath, (void *)&stbuf);
|
err = f->ops.getattr(PosixDotPath, (void *)&stbuf);
|
||||||
else
|
else
|
||||||
@ -310,25 +318,57 @@ static BOOLEAN fsp_fuse_intf_CheckSymlinkDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t fsp_fuse_intf_MapFileAttributesToFlags(UINT32 FileAttributes)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||||
|
flags |= FSP_FUSE_UF_READONLY;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_HIDDEN)
|
||||||
|
flags |= FSP_FUSE_UF_HIDDEN;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_SYSTEM)
|
||||||
|
flags |= FSP_FUSE_UF_SYSTEM;
|
||||||
|
if (FileAttributes & FILE_ATTRIBUTE_ARCHIVE)
|
||||||
|
flags |= FSP_FUSE_UF_ARCHIVE;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline UINT32 fsp_fuse_intf_MapFlagsToFileAttributes(uint32_t flags)
|
||||||
|
{
|
||||||
|
UINT32 FileAttributes = 0;
|
||||||
|
|
||||||
|
if (flags & FSP_FUSE_UF_READONLY)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||||
|
if (flags & FSP_FUSE_UF_HIDDEN)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||||
|
if (flags & FSP_FUSE_UF_SYSTEM)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
|
||||||
|
if (flags & FSP_FUSE_UF_ARCHIVE)
|
||||||
|
FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
|
||||||
|
|
||||||
|
return FileAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
#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,
|
||||||
const char *PosixPath, struct fuse_file_info *fi, const struct fuse_stat *stbufp,
|
const char *PosixPath, struct fuse_file_info *fi, const void *stbufp,
|
||||||
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode, PUINT32 PDev,
|
PUINT32 PUid, PUINT32 PGid, PUINT32 PMode, PUINT32 PDev,
|
||||||
FSP_FSCTL_FILE_INFO *FileInfo)
|
FSP_FSCTL_FILE_INFO *FileInfo)
|
||||||
{
|
{
|
||||||
struct fuse *f = FileSystem->UserContext;
|
struct fuse *f = FileSystem->UserContext;
|
||||||
UINT64 AllocationUnit;
|
UINT64 AllocationUnit;
|
||||||
struct fuse_stat stbuf;
|
struct fuse_stat_ex stbuf;
|
||||||
|
BOOLEAN StatEx = 0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX);
|
||||||
|
|
||||||
|
memset(&stbuf, 0, sizeof stbuf);
|
||||||
if (0 != stbufp)
|
if (0 != stbufp)
|
||||||
memcpy(&stbuf, stbufp, sizeof stbuf);
|
memcpy(&stbuf, stbufp, StatEx ? sizeof(struct fuse_stat_ex) : sizeof(struct fuse_stat));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
memset(&stbuf, 0, sizeof stbuf);
|
|
||||||
|
|
||||||
if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh)
|
if (0 != f->ops.fgetattr && 0 != fi && -1 != fi->fh)
|
||||||
err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi);
|
err = f->ops.fgetattr(PosixPath, (void *)&stbuf, fi);
|
||||||
else if (0 != f->ops.getattr)
|
else if (0 != f->ops.getattr)
|
||||||
@ -383,21 +423,15 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FileInfo->ReparseTag = 0;
|
FileInfo->ReparseTag = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (StatEx)
|
||||||
|
FileInfo->FileAttributes |= fsp_fuse_intf_MapFlagsToFileAttributes(stbuf.st_flags);
|
||||||
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;
|
||||||
FileInfo->CreationTime =
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim, &FileInfo->CreationTime);
|
||||||
Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 +
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_atim, &FileInfo->LastAccessTime);
|
||||||
stbuf.st_birthtim.tv_nsec / 100;
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_mtim, &FileInfo->LastWriteTime);
|
||||||
FileInfo->LastAccessTime =
|
FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim, &FileInfo->ChangeTime);
|
||||||
Int32x32To64(stbuf.st_atim.tv_sec, 10000000) + 116444736000000000 +
|
|
||||||
stbuf.st_atim.tv_nsec / 100;
|
|
||||||
FileInfo->LastWriteTime =
|
|
||||||
Int32x32To64(stbuf.st_mtim.tv_sec, 10000000) + 116444736000000000 +
|
|
||||||
stbuf.st_mtim.tv_nsec / 100;
|
|
||||||
FileInfo->ChangeTime =
|
|
||||||
Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 +
|
|
||||||
stbuf.st_ctim.tv_nsec / 100;
|
|
||||||
FileInfo->IndexNumber = stbuf.st_ino;
|
FileInfo->IndexNumber = stbuf.st_ino;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -731,9 +765,9 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
memset(&fi, 0, sizeof fi);
|
memset(&fi, 0, sizeof fi);
|
||||||
if ('C' == f->env->environment) /* Cygwin */
|
if ('C' == f->env->environment) /* Cygwin */
|
||||||
fi.flags = 0x0200 | 2 /*O_CREAT|O_RDWR*/;
|
fi.flags = 0x0200 | 0x0800 | 2 /*O_CREAT|O_EXCL|O_RDWR*/;
|
||||||
else
|
else
|
||||||
fi.flags = 0x0100 | 2 /*O_CREAT|O_RDWR*/;
|
fi.flags = 0x0100 | 0x0400 | 2 /*O_CREAT|O_EXCL|O_RDWR*/;
|
||||||
|
|
||||||
if (CreateOptions & FILE_DIRECTORY_FILE)
|
if (CreateOptions & FILE_DIRECTORY_FILE)
|
||||||
{
|
{
|
||||||
@ -787,22 +821,30 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
Opened = TRUE;
|
Opened = TRUE;
|
||||||
|
|
||||||
if (Uid != context->uid || Gid != context->gid)
|
if (0 != FileAttributes &&
|
||||||
if (0 != f->ops.chown)
|
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
||||||
{
|
{
|
||||||
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
|
err = f->ops.chflags(contexthdr->PosixPath,
|
||||||
if (0 != err)
|
fsp_fuse_intf_MapFileAttributesToFlags(CreateOptions & FILE_DIRECTORY_FILE ?
|
||||||
{
|
FileAttributes : FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
goto exit;
|
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
||||||
}
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((Uid != context->uid || Gid != context->gid) &&
|
||||||
|
0 != f->ops.chown)
|
||||||
|
{
|
||||||
|
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache
|
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
|
||||||
* WinFsp does not currently support disabling the cache manager
|
* NOTE: Originally WinFsp dit not support disabling the cache manager
|
||||||
* for an individual file although it should not be hard to add
|
* for an individual file. This is now possible and we should revisit.
|
||||||
* if required.
|
|
||||||
*
|
*
|
||||||
* Ignore fuse_file_info::nonseekable.
|
* Ignore fuse_file_info::nonseekable.
|
||||||
*/
|
*/
|
||||||
@ -982,6 +1024,22 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
|
if (0 != FileAttributes &&
|
||||||
|
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The code below is not strictly correct. File attributes should be
|
||||||
|
* replaced when ReplaceFileAttributes is TRUE and merged (or'ed) when
|
||||||
|
* ReplaceFileAttributes is FALSE. I am punting on this detail for now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
err = f->ops.chflags(filedesc->PosixPath,
|
||||||
|
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
&Uid, &Gid, &Mode, FileInfo);
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
}
|
}
|
||||||
@ -1141,7 +1199,8 @@ static NTSTATUS fsp_fuse_intf_Write(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
AllocationUnit = (UINT64)f->VolumeParams.SectorSize *
|
AllocationUnit = (UINT64)f->VolumeParams.SectorSize *
|
||||||
(UINT64)f->VolumeParams.SectorsPerAllocationUnit;
|
(UINT64)f->VolumeParams.SectorsPerAllocationUnit;
|
||||||
FileInfoBuf.FileSize = Offset + bytes;
|
if (Offset + bytes > FileInfoBuf.FileSize)
|
||||||
|
FileInfoBuf.FileSize = Offset + bytes;
|
||||||
FileInfoBuf.AllocationSize =
|
FileInfoBuf.AllocationSize =
|
||||||
(FileInfoBuf.FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
(FileInfoBuf.FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
||||||
|
|
||||||
@ -1234,67 +1293,74 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
int err;
|
int err;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == f->ops.utimens && 0 == f->ops.utime)
|
|
||||||
return STATUS_SUCCESS; /* liar! */
|
|
||||||
|
|
||||||
/* no way to set FileAttributes, CreationTime! */
|
|
||||||
if (0 == LastAccessTime && 0 == LastWriteTime)
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
memset(&fi, 0, sizeof fi);
|
memset(&fi, 0, sizeof fi);
|
||||||
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,
|
if (INVALID_FILE_ATTRIBUTES != FileAttributes &&
|
||||||
&Uid, &Gid, &Mode, &FileInfoBuf);
|
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
if (0 != LastAccessTime)
|
|
||||||
FileInfoBuf.LastAccessTime = LastAccessTime;
|
|
||||||
if (0 != LastWriteTime)
|
|
||||||
FileInfoBuf.LastWriteTime = LastWriteTime;
|
|
||||||
|
|
||||||
/* UNIX epoch in 100-ns intervals */
|
|
||||||
LastAccessTime = FileInfoBuf.LastAccessTime - 116444736000000000;
|
|
||||||
LastWriteTime = FileInfoBuf.LastWriteTime - 116444736000000000;
|
|
||||||
|
|
||||||
if (0 != f->ops.utimens)
|
|
||||||
{
|
{
|
||||||
#if defined(_WIN64)
|
err = f->ops.chflags(filedesc->PosixPath,
|
||||||
tv[0].tv_sec = (int64_t)(LastAccessTime / 10000000);
|
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes));
|
||||||
tv[0].tv_nsec = (int64_t)(LastAccessTime % 10000000) * 100;
|
|
||||||
tv[1].tv_sec = (int64_t)(LastWriteTime / 10000000);
|
|
||||||
tv[1].tv_nsec = (int64_t)(LastWriteTime % 10000000) * 100;
|
|
||||||
#else
|
|
||||||
tv[0].tv_sec = (int32_t)(LastAccessTime / 10000000);
|
|
||||||
tv[0].tv_nsec = (int32_t)(LastAccessTime % 10000000) * 100;
|
|
||||||
tv[1].tv_sec = (int32_t)(LastWriteTime / 10000000);
|
|
||||||
tv[1].tv_nsec = (int32_t)(LastWriteTime % 10000000) * 100;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
err = f->ops.utimens(filedesc->PosixPath, tv);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if ((0 != LastAccessTime || 0 != LastWriteTime) &&
|
||||||
|
(0 != f->ops.utimens || 0 != f->ops.utime))
|
||||||
{
|
{
|
||||||
#if defined(_WIN64)
|
if (0 == LastAccessTime || 0 == LastWriteTime)
|
||||||
timbuf.actime = (int64_t)(LastAccessTime / 10000000);
|
{
|
||||||
timbuf.modtime = (int64_t)(LastWriteTime / 10000000);
|
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
#else
|
&Uid, &Gid, &Mode, &FileInfoBuf);
|
||||||
timbuf.actime = (int32_t)(LastAccessTime / 10000000);
|
if (!NT_SUCCESS(Result))
|
||||||
timbuf.modtime = (int32_t)(LastWriteTime / 10000000);
|
return Result;
|
||||||
#endif
|
|
||||||
|
|
||||||
err = f->ops.utime(filedesc->PosixPath, &timbuf);
|
if (0 == LastAccessTime)
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
LastAccessTime = FileInfoBuf.LastAccessTime;
|
||||||
|
if (0 == LastWriteTime)
|
||||||
|
LastWriteTime = FileInfoBuf.LastWriteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspPosixFileTimeToUnixTime(LastAccessTime, (void *)&tv[0]);
|
||||||
|
FspPosixFileTimeToUnixTime(LastWriteTime, (void *)&tv[1]);
|
||||||
|
if (0 != f->ops.utimens)
|
||||||
|
{
|
||||||
|
err = f->ops.utimens(filedesc->PosixPath, tv);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timbuf.actime = tv[0].tv_sec;
|
||||||
|
timbuf.modtime = tv[1].tv_sec;
|
||||||
|
err = f->ops.utime(filedesc->PosixPath, &timbuf);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
memcpy(FileInfo, &FileInfoBuf, sizeof FileInfoBuf);
|
if (0 != CreationTime && 0 != f->ops.setcrtime)
|
||||||
|
{
|
||||||
|
FspPosixFileTimeToUnixTime(CreationTime, (void *)&tv[0]);
|
||||||
|
err = f->ops.setcrtime(filedesc->PosixPath, &tv[0]);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
if (0 != ChangeTime && 0 != f->ops.setchgtime)
|
||||||
|
{
|
||||||
|
FspPosixFileTimeToUnixTime(ChangeTime, (void *)&tv[0]);
|
||||||
|
err = f->ops.setchgtime(filedesc->PosixPath, &tv[0]);
|
||||||
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_SetFileSize(FSP_FILE_SYSTEM *FileSystem,
|
||||||
@ -1749,6 +1815,63 @@ static NTSTATUS fsp_fuse_intf_ReadDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS fsp_fuse_intf_GetDirInfoByName(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileNode, PWSTR FileName,
|
||||||
|
FSP_FSCTL_DIR_INFO *DirInfo)
|
||||||
|
{
|
||||||
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
struct fsp_fuse_file_desc *filedesc = FileNode;
|
||||||
|
char *PosixName = 0;
|
||||||
|
char PosixPath[FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)];
|
||||||
|
int ParentLength, FSlashLength, PosixNameLength;
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspPosixMapWindowsToPosixPath(FileName, &PosixName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
Result = STATUS_OBJECT_NAME_NOT_FOUND; //Result?
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParentLength = lstrlenA(filedesc->PosixPath);
|
||||||
|
FSlashLength = 1 < ParentLength;
|
||||||
|
PosixNameLength = lstrlenA(PosixName);
|
||||||
|
if (FSP_FSCTL_TRANSACT_PATH_SIZEMAX <= (ParentLength + FSlashLength + PosixNameLength) * sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
Result = STATUS_OBJECT_NAME_NOT_FOUND; //STATUS_OBJECT_NAME_INVALID?
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(PosixPath, filedesc->PosixPath, ParentLength);
|
||||||
|
memcpy(PosixPath + ParentLength, "/", FSlashLength);
|
||||||
|
memcpy(PosixPath + ParentLength + FSlashLength, PosixName, PosixNameLength + 1);
|
||||||
|
|
||||||
|
Result = fsp_fuse_intf_GetFileInfoEx(FileSystem, PosixPath, 0,
|
||||||
|
&Uid, &Gid, &Mode, &DirInfo->FileInfo);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
Result = STATUS_OBJECT_NAME_NOT_FOUND; //Result?
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUSE does not do FileName normalization; so just return the FileName as given to us!
|
||||||
|
*/
|
||||||
|
|
||||||
|
//memset(DirInfo->Padding, 0, sizeof DirInfo->Padding);
|
||||||
|
DirInfo->Size = (UINT16)(sizeof(FSP_FSCTL_DIR_INFO) + lstrlenW(FileName) * sizeof(WCHAR));
|
||||||
|
memcpy(DirInfo->FileNameBuf, FileName, DirInfo->Size - sizeof(FSP_FSCTL_DIR_INFO));
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PosixName)
|
||||||
|
FspPosixDeletePath(PosixName);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
static NTSTATUS fsp_fuse_intf_ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent,
|
PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent,
|
||||||
PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize)
|
PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize)
|
||||||
@ -2022,6 +2145,8 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
|||||||
fsp_fuse_intf_GetReparsePoint,
|
fsp_fuse_intf_GetReparsePoint,
|
||||||
fsp_fuse_intf_SetReparsePoint,
|
fsp_fuse_intf_SetReparsePoint,
|
||||||
fsp_fuse_intf_DeleteReparsePoint,
|
fsp_fuse_intf_DeleteReparsePoint,
|
||||||
|
0,
|
||||||
|
fsp_fuse_intf_GetDirInfoByName,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_main.c
|
* @file dll/fuse/fuse_main.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_opt.c
|
* @file dll/fuse/fuse_opt.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/library.h
|
* @file dll/fuse/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
152
src/dll/launch.c
Normal file
152
src/dll/launch.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* @file dll/launch.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dll/library.h>
|
||||||
|
#include <launcher/launcher.h>
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspLaunchCallLauncherPipe(
|
||||||
|
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
|
||||||
|
PWSTR Buffer, PULONG PSize, PULONG PLauncherError)
|
||||||
|
{
|
||||||
|
PWSTR PipeBuf = 0, P;
|
||||||
|
ULONG Length, BytesTransferred;
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG ErrorCode;
|
||||||
|
|
||||||
|
if (0 != PSize)
|
||||||
|
*PSize = 0;
|
||||||
|
*PLauncherError = 0;
|
||||||
|
|
||||||
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
if (0 == PipeBuf)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
P = PipeBuf;
|
||||||
|
*P++ = Command;
|
||||||
|
for (ULONG I = 0; Argc > I; I++)
|
||||||
|
if (0 != Argv[I])
|
||||||
|
{
|
||||||
|
Length = 0 == Argl || -1 == Argl[I] ? lstrlenW(Argv[I]) : Argl[I];
|
||||||
|
if (LAUNCHER_PIPE_BUFFER_SIZE < ((ULONG)(P - PipeBuf) + Length + 1) * sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME,
|
||||||
|
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE,
|
||||||
|
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
ErrorCode = ERROR_BROKEN_PIPE; /* protocol error! */
|
||||||
|
if (sizeof(WCHAR) <= BytesTransferred)
|
||||||
|
{
|
||||||
|
if (LauncherSuccess == PipeBuf[0])
|
||||||
|
{
|
||||||
|
ErrorCode = 0;
|
||||||
|
|
||||||
|
if (0 != PSize)
|
||||||
|
{
|
||||||
|
BytesTransferred -= sizeof(WCHAR);
|
||||||
|
memcpy(Buffer, PipeBuf, *PSize < BytesTransferred ? *PSize : BytesTransferred);
|
||||||
|
*PSize = BytesTransferred;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (LauncherFailure == PipeBuf[0])
|
||||||
|
{
|
||||||
|
ErrorCode = 0;
|
||||||
|
|
||||||
|
for (PWSTR P = PipeBuf + 1, EndP = PipeBuf + BytesTransferred / sizeof(WCHAR); EndP > P; P++)
|
||||||
|
{
|
||||||
|
if (L'0' > *P || *P > L'9')
|
||||||
|
break;
|
||||||
|
ErrorCode = 10 * ErrorCode + (*P - L'0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == ErrorCode)
|
||||||
|
ErrorCode = ERROR_BROKEN_PIPE; /* protocol error! */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*PLauncherError = ErrorCode;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(PipeBuf);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspLaunchStart(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0,
|
||||||
|
BOOLEAN HasSecret,
|
||||||
|
PULONG PLauncherError)
|
||||||
|
{
|
||||||
|
PWSTR Argv[9 + 2];
|
||||||
|
|
||||||
|
if (9 < Argc)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Argv[0] = ClassName;
|
||||||
|
Argv[1] = InstanceName;
|
||||||
|
memcpy(Argv + 2, Argv, Argc * sizeof(PWSTR));
|
||||||
|
|
||||||
|
return FspLaunchCallLauncherPipe(
|
||||||
|
HasSecret ? LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart,
|
||||||
|
Argc + 2, Argv, 0, 0, 0, PLauncherError);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspLaunchStop(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName,
|
||||||
|
PULONG PLauncherError)
|
||||||
|
{
|
||||||
|
PWSTR Argv[2];
|
||||||
|
|
||||||
|
Argv[0] = ClassName;
|
||||||
|
Argv[1] = InstanceName;
|
||||||
|
|
||||||
|
return FspLaunchCallLauncherPipe(LauncherSvcInstanceStop,
|
||||||
|
2, Argv, 0, 0, 0, PLauncherError);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspLaunchGetInfo(
|
||||||
|
PWSTR ClassName, PWSTR InstanceName,
|
||||||
|
PWSTR Buffer, PULONG PSize,
|
||||||
|
PULONG PLauncherError)
|
||||||
|
{
|
||||||
|
PWSTR Argv[2];
|
||||||
|
|
||||||
|
Argv[0] = ClassName;
|
||||||
|
Argv[1] = InstanceName;
|
||||||
|
|
||||||
|
return FspLaunchCallLauncherPipe(LauncherSvcInstanceInfo,
|
||||||
|
2, Argv, 0, Buffer, PSize, PLauncherError);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspLaunchGetNameList(
|
||||||
|
PWSTR Buffer, PULONG PSize,
|
||||||
|
PULONG PLauncherError)
|
||||||
|
{
|
||||||
|
return FspLaunchCallLauncherPipe(LauncherSvcInstanceList,
|
||||||
|
0, 0, 0, Buffer, PSize, PLauncherError);
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.c
|
* @file dll/library.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -44,6 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
|||||||
FspServiceFinalize(Dynamic);
|
FspServiceFinalize(Dynamic);
|
||||||
FspEventLogFinalize(Dynamic);
|
FspEventLogFinalize(Dynamic);
|
||||||
FspPosixFinalize(Dynamic);
|
FspPosixFinalize(Dynamic);
|
||||||
|
FspWksidFinalize(Dynamic);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.h
|
* @file dll/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -31,11 +31,15 @@
|
|||||||
FspDebugLog("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", __VA_ARGS__)
|
FspDebugLog("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", __VA_ARGS__)
|
||||||
#define DEBUGLOGSD(fmt, SD) \
|
#define DEBUGLOGSD(fmt, SD) \
|
||||||
FspDebugLogSD("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", SD)
|
FspDebugLogSD("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", SD)
|
||||||
|
#define DEBUGLOGSID(fmt, Sid) \
|
||||||
|
FspDebugLogSid("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", Sid)
|
||||||
#else
|
#else
|
||||||
#define DEBUGLOG(fmt, ...) ((void)0)
|
#define DEBUGLOG(fmt, ...) ((void)0)
|
||||||
#define DEBUGLOGSD(fmt, SD) ((void)0)
|
#define DEBUGLOGSD(fmt, SD) ((void)0)
|
||||||
|
#define DEBUGLOGSID(fmt, Sid) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VOID FspWksidFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
||||||
@ -49,6 +53,9 @@ NTSTATUS FspNpUnregister(VOID);
|
|||||||
NTSTATUS FspEventLogRegister(VOID);
|
NTSTATUS FspEventLogRegister(VOID);
|
||||||
NTSTATUS FspEventLogUnregister(VOID);
|
NTSTATUS FspEventLogUnregister(VOID);
|
||||||
|
|
||||||
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
||||||
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
||||||
|
|
||||||
PWSTR FspDiagIdent(VOID);
|
PWSTR FspDiagIdent(VOID);
|
||||||
|
|
||||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
|
136
src/dll/np.c
136
src/dll/np.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/np.c
|
* @file dll/np.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -35,6 +35,12 @@
|
|||||||
*/
|
*/
|
||||||
#define FSP_NP_CREDENTIAL_MANAGER
|
#define FSP_NP_CREDENTIAL_MANAGER
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the following macro to register ourselves as the first network provider.
|
||||||
|
* Otherwise we will be registered as the last network provider.
|
||||||
|
*/
|
||||||
|
#define FSP_NP_ORDER_FIRST
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FSP_NP_CREDENTIALS_NONE = 0,
|
FSP_NP_CREDENTIALS_NONE = 0,
|
||||||
@ -147,7 +153,7 @@ static inline BOOLEAN FspNpParseRemoteName(PWSTR RemoteName,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOLEAN FspNpParseUserName(PWSTR RemoteName,
|
static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName,
|
||||||
PWSTR UserName, ULONG UserNameSize/* in chars */)
|
PWSTR UserName, ULONG UserNameSize/* in chars */)
|
||||||
{
|
{
|
||||||
PWSTR ClassName, InstanceName, P;
|
PWSTR ClassName, InstanceName, P;
|
||||||
@ -168,39 +174,17 @@ static inline BOOLEAN FspNpParseUserName(PWSTR RemoteName,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
static inline DWORD FspNpCallLauncherPipe(
|
||||||
|
WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl,
|
||||||
|
PWSTR Buffer, PULONG PSize)
|
||||||
{
|
{
|
||||||
DWORD NpResult;
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
DWORD BytesTransferred;
|
ULONG ErrorCode;
|
||||||
|
|
||||||
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
Result = FspLaunchCallLauncherPipe(Command, Argc, Argv, Argl, Buffer, PSize, &ErrorCode);
|
||||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
return !NT_SUCCESS(Result) ?
|
||||||
|
WN_NO_NETWORK :
|
||||||
if (!NT_SUCCESS(Result))
|
(ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode);
|
||||||
NpResult = WN_NO_NETWORK;
|
|
||||||
else if (sizeof(WCHAR) > BytesTransferred)
|
|
||||||
NpResult = WN_NO_NETWORK;
|
|
||||||
else if (LauncherSuccess == PipeBuf[0])
|
|
||||||
NpResult = WN_SUCCESS;
|
|
||||||
else if (LauncherFailure == PipeBuf[0])
|
|
||||||
{
|
|
||||||
NpResult = 0;
|
|
||||||
for (PWSTR P = PipeBuf + 1, EndP = PipeBuf + BytesTransferred / sizeof(WCHAR); EndP > P; P++)
|
|
||||||
{
|
|
||||||
if (L'0' > *P || *P > L'9')
|
|
||||||
break;
|
|
||||||
|
|
||||||
NpResult = 10 * NpResult + (*P - L'0');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == NpResult)
|
|
||||||
NpResult = WN_NO_NETWORK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
NpResult = WN_NO_NETWORK;
|
|
||||||
|
|
||||||
return NpResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspNpGetVolumeList(
|
static NTSTATUS FspNpGetVolumeList(
|
||||||
@ -490,7 +474,9 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
PWSTR ClassName, InstanceName, RemoteName, P;
|
PWSTR ClassName, InstanceName, RemoteName, P;
|
||||||
ULONG ClassNameLen, InstanceNameLen;
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
DWORD CredentialsKind;
|
DWORD CredentialsKind;
|
||||||
PWSTR PipeBuf = 0;
|
ULONG Argc;
|
||||||
|
PWSTR Argv[6];
|
||||||
|
ULONG Argl[6];
|
||||||
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
||||||
PCREDENTIALW Credential = 0;
|
PCREDENTIALW Credential = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -556,32 +542,24 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
Argc = 0;
|
||||||
if (0 == PipeBuf)
|
Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++;
|
||||||
{
|
Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++;
|
||||||
NpResult = WN_OUT_OF_MEMORY;
|
Argv[Argc] = RemoteName; Argl[Argc] = -1; Argc++;
|
||||||
goto exit;
|
Argv[Argc] = LocalNameBuf; Argl[Argc] = -1; Argc++;
|
||||||
}
|
|
||||||
|
|
||||||
/* we do not explicitly check, but assumption is it all fits in LAUNCHER_PIPE_BUFFER_SIZE */
|
|
||||||
P = PipeBuf;
|
|
||||||
*P++ = FSP_NP_CREDENTIALS_NONE != CredentialsKind ?
|
|
||||||
LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart;
|
|
||||||
memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
|
|
||||||
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
|
||||||
lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1;
|
|
||||||
lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1;
|
|
||||||
if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
|
if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
|
||||||
{
|
{
|
||||||
lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1;
|
Argv[Argc] = lpUserName; Argl[Argc] = -1; Argc++;
|
||||||
}
|
}
|
||||||
if (FSP_NP_CREDENTIALS_NONE != CredentialsKind)
|
if (FSP_NP_CREDENTIALS_NONE != CredentialsKind)
|
||||||
{
|
{
|
||||||
lstrcpyW(P, lpPassword); P += lstrlenW(lpPassword) + 1;
|
Argv[Argc] = lpPassword; Argl[Argc] = -1; Argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpResult = FspNpCallLauncherPipe(
|
NpResult = FspNpCallLauncherPipe(
|
||||||
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE);
|
FSP_NP_CREDENTIALS_NONE != CredentialsKind ?
|
||||||
|
LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart,
|
||||||
|
Argc, Argv, Argl, 0, 0);
|
||||||
switch (NpResult)
|
switch (NpResult)
|
||||||
{
|
{
|
||||||
case WN_SUCCESS:
|
case WN_SUCCESS:
|
||||||
@ -627,13 +605,13 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
P = PipeBuf;
|
Argc = 0;
|
||||||
*P++ = LauncherSvcInstanceInfo;
|
Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++;
|
||||||
memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
|
Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++;
|
||||||
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
|
||||||
|
|
||||||
if (WN_SUCCESS != FspNpCallLauncherPipe(
|
if (WN_SUCCESS != FspNpCallLauncherPipe(
|
||||||
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE))
|
LauncherSvcInstanceInfo,
|
||||||
|
Argc, Argv, Argl, 0, 0))
|
||||||
{
|
{
|
||||||
/* looks like the file system is gone! */
|
/* looks like the file system is gone! */
|
||||||
NpResult = WN_NO_NETWORK;
|
NpResult = WN_NO_NETWORK;
|
||||||
@ -677,8 +655,6 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MemFree(PipeBuf);
|
|
||||||
|
|
||||||
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
||||||
if (0 != Credential)
|
if (0 != Credential)
|
||||||
CredFree(Credential);
|
CredFree(Credential);
|
||||||
@ -721,7 +697,7 @@ DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
|
|||||||
lstrcpyW(UserName, L"UNSPECIFIED");
|
lstrcpyW(UserName, L"UNSPECIFIED");
|
||||||
Password[0] = L'\0';
|
Password[0] = L'\0';
|
||||||
if (FSP_NP_CREDENTIALS_PASSWORD == CredentialsKind)
|
if (FSP_NP_CREDENTIALS_PASSWORD == CredentialsKind)
|
||||||
FspNpParseUserName(RemoteName, UserName, sizeof UserName / sizeof UserName[0]);
|
FspNpParseRemoteUserName(RemoteName, UserName, sizeof UserName / sizeof UserName[0]);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
NpResult = FspNpGetCredentials(
|
NpResult = FspNpGetCredentials(
|
||||||
@ -767,9 +743,11 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
|
|||||||
DWORD NpResult;
|
DWORD NpResult;
|
||||||
WCHAR RemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)];
|
WCHAR RemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)];
|
||||||
DWORD RemoteNameSize;
|
DWORD RemoteNameSize;
|
||||||
PWSTR ClassName, InstanceName, RemoteName, P;
|
PWSTR ClassName, InstanceName, RemoteName;
|
||||||
ULONG ClassNameLen, InstanceNameLen;
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
PWSTR PipeBuf = 0;
|
ULONG Argc;
|
||||||
|
PWSTR Argv[2];
|
||||||
|
ULONG Argl[2];
|
||||||
|
|
||||||
if (FspNpCheckLocalName(lpName))
|
if (FspNpCheckLocalName(lpName))
|
||||||
{
|
{
|
||||||
@ -789,17 +767,13 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
|
|||||||
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
|
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
|
||||||
return WN_BAD_NETNAME;
|
return WN_BAD_NETNAME;
|
||||||
|
|
||||||
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
Argc = 0;
|
||||||
if (0 == PipeBuf)
|
Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++;
|
||||||
return WN_OUT_OF_MEMORY;
|
Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++;
|
||||||
|
|
||||||
P = PipeBuf;
|
|
||||||
*P++ = LauncherSvcInstanceStop;
|
|
||||||
memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
|
|
||||||
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
|
||||||
|
|
||||||
NpResult = FspNpCallLauncherPipe(
|
NpResult = FspNpCallLauncherPipe(
|
||||||
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE);
|
LauncherSvcInstanceStop,
|
||||||
|
Argc, Argv, Argl, 0, 0);
|
||||||
switch (NpResult)
|
switch (NpResult)
|
||||||
{
|
{
|
||||||
case WN_SUCCESS:
|
case WN_SUCCESS:
|
||||||
@ -812,8 +786,6 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemFree(PipeBuf);
|
|
||||||
|
|
||||||
return NpResult;
|
return NpResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +988,7 @@ NTSTATUS FspNpRegister(VOID)
|
|||||||
WCHAR ProviderPath[MAX_PATH];
|
WCHAR ProviderPath[MAX_PATH];
|
||||||
WCHAR RegBuffer[1024];
|
WCHAR RegBuffer[1024];
|
||||||
PWSTR P, Part;
|
PWSTR P, Part;
|
||||||
DWORD RegResult, RegType, RegBufferSize;
|
DWORD RegResult, RegType, RegBufferSize, RegBufferOffset;
|
||||||
HKEY RegKey;
|
HKEY RegKey;
|
||||||
BOOLEAN FoundProvider;
|
BOOLEAN FoundProvider;
|
||||||
|
|
||||||
@ -1082,15 +1054,20 @@ NTSTATUS FspNpRegister(VOID)
|
|||||||
return FspNtStatusFromWin32(RegResult);
|
return FspNtStatusFromWin32(RegResult);
|
||||||
|
|
||||||
RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME;
|
RegBufferSize = sizeof RegBuffer - sizeof L"," FSP_NP_NAME;
|
||||||
|
#ifdef FSP_NP_ORDER_FIRST
|
||||||
|
RegBufferOffset = sizeof "" FSP_NP_NAME;
|
||||||
|
#else
|
||||||
|
RegBufferOffset = 0;
|
||||||
|
#endif
|
||||||
RegResult = RegQueryValueExW(RegKey,
|
RegResult = RegQueryValueExW(RegKey,
|
||||||
L"ProviderOrder", 0, &RegType, (PVOID)RegBuffer, &RegBufferSize);
|
L"ProviderOrder", 0, &RegType, (PVOID)&RegBuffer[RegBufferOffset], &RegBufferSize);
|
||||||
if (ERROR_SUCCESS != RegResult)
|
if (ERROR_SUCCESS != RegResult)
|
||||||
goto close_and_exit;
|
goto close_and_exit;
|
||||||
RegBufferSize /= sizeof(WCHAR);
|
RegBufferSize /= sizeof(WCHAR);
|
||||||
|
|
||||||
FoundProvider = FALSE;
|
FoundProvider = FALSE;
|
||||||
RegBuffer[RegBufferSize] = L'\0';
|
RegBuffer[RegBufferSize + RegBufferOffset] = L'\0';
|
||||||
P = RegBuffer, Part = P;
|
P = &RegBuffer[RegBufferOffset], Part = P;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (L',' == *P || '\0' == *P)
|
if (L',' == *P || '\0' == *P)
|
||||||
@ -1107,8 +1084,11 @@ NTSTATUS FspNpRegister(VOID)
|
|||||||
|
|
||||||
if (!FoundProvider)
|
if (!FoundProvider)
|
||||||
{
|
{
|
||||||
P--;
|
#ifdef FSP_NP_ORDER_FIRST
|
||||||
memcpy(P, L"," FSP_NP_NAME, sizeof L"," FSP_NP_NAME);
|
memcpy((PWSTR)RegBuffer, L"" FSP_NP_NAME ",", sizeof L"" FSP_NP_NAME);
|
||||||
|
#else
|
||||||
|
memcpy(--P, L"," FSP_NP_NAME, sizeof L"," FSP_NP_NAME);
|
||||||
|
#endif
|
||||||
|
|
||||||
RegBufferSize = lstrlenW(RegBuffer);
|
RegBufferSize = lstrlenW(RegBuffer);
|
||||||
RegBufferSize++;
|
RegBufferSize++;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/ntstatus.c
|
* @file dll/ntstatus.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/path.c
|
* @file dll/path.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* [SNAME]
|
* [SNAME]
|
||||||
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
* https://www.cygwin.com/cygwin-ug-net/using-specialnames.html
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -453,9 +453,12 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspPosixMapUidToSid(0x10100, &WorldSid);
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == WorldSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
OwnerPerm = (Mode & 0700) >> 6;
|
OwnerPerm = (Mode & 0700) >> 6;
|
||||||
GroupPerm = (Mode & 0070) >> 3;
|
GroupPerm = (Mode & 0070) >> 3;
|
||||||
@ -579,9 +582,6 @@ exit:
|
|||||||
|
|
||||||
MemFree(Acl);
|
MemFree(Acl);
|
||||||
|
|
||||||
if (0 != WorldSid)
|
|
||||||
FspDeleteSid(WorldSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
if (0 != GroupSid)
|
if (0 != GroupSid)
|
||||||
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
|
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
@ -649,13 +649,19 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
|||||||
|
|
||||||
if (0 != Acl)
|
if (0 != Acl)
|
||||||
{
|
{
|
||||||
Result = FspPosixMapUidToSid(0x10100, &WorldSid);
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == WorldSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
Result = FspPosixMapUidToSid(11, &AuthUsersSid);
|
AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == AuthUsersSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
|
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
|
||||||
|
|
||||||
@ -771,12 +777,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (0 != AuthUsersSid)
|
|
||||||
FspDeleteSid(AuthUsersSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
if (0 != WorldSid)
|
|
||||||
FspDeleteSid(WorldSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
lasterror:
|
lasterror:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/security.c
|
* @file dll/security.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -172,8 +172,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
if (0 < SecurityDescriptorSize)
|
if (0 < SecurityDescriptorSize)
|
||||||
{
|
{
|
||||||
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, FILE_TRAVERSE,
|
if (AccessCheck(SecurityDescriptor,
|
||||||
&FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, &TraverseAccess, &AccessStatus))
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken),
|
||||||
|
FILE_TRAVERSE,
|
||||||
|
&FspFileGenericMapping,
|
||||||
|
PrivilegeSet, &PrivilegeSetLength,
|
||||||
|
&TraverseAccess, &AccessStatus))
|
||||||
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
else
|
else
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
@ -202,8 +206,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
{
|
{
|
||||||
if (0 == DesiredAccess)
|
if (0 == DesiredAccess)
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
else if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess,
|
else if (AccessCheck(SecurityDescriptor,
|
||||||
&FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken),
|
||||||
|
DesiredAccess,
|
||||||
|
&FspFileGenericMapping,
|
||||||
|
PrivilegeSet, &PrivilegeSetLength,
|
||||||
|
PGrantedAccess, &AccessStatus))
|
||||||
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
else
|
else
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
@ -244,8 +252,12 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
((FILE_LIST_DIRECTORY & ParentAccess) ? FILE_READ_ATTRIBUTES : 0));
|
((FILE_LIST_DIRECTORY & ParentAccess) ? FILE_READ_ATTRIBUTES : 0));
|
||||||
if (0 != DesiredAccess2)
|
if (0 != DesiredAccess2)
|
||||||
{
|
{
|
||||||
if (AccessCheck(SecurityDescriptor, (HANDLE)Request->Req.Create.AccessToken, DesiredAccess2,
|
if (AccessCheck(SecurityDescriptor,
|
||||||
&FspFileGenericMapping, PrivilegeSet, &PrivilegeSetLength, PGrantedAccess, &AccessStatus))
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken),
|
||||||
|
DesiredAccess2,
|
||||||
|
&FspFileGenericMapping,
|
||||||
|
PrivilegeSet, &PrivilegeSetLength,
|
||||||
|
PGrantedAccess, &AccessStatus))
|
||||||
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
Result = AccessStatus ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
else
|
else
|
||||||
/* any failure just becomes ACCESS DENIED at this point */
|
/* any failure just becomes ACCESS DENIED at this point */
|
||||||
@ -396,7 +408,7 @@ FSP_API NTSTATUS FspCreateSecurityDescriptor(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
(PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0,
|
(PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset) : 0,
|
||||||
PSecurityDescriptor,
|
PSecurityDescriptor,
|
||||||
0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE),
|
0 != (Request->Req.Create.CreateOptions & FILE_DIRECTORY_FILE),
|
||||||
(HANDLE)Request->Req.Create.AccessToken,
|
FSP_FSCTL_TRANSACT_REQ_TOKEN_HANDLE(Request->Req.Create.AccessToken),
|
||||||
&FspFileGenericMapping))
|
&FspFileGenericMapping))
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/service.c
|
* @file dll/service.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -566,6 +566,106 @@ FSP_API BOOLEAN FspServiceIsInteractive(VOID)
|
|||||||
return IsInteractive;
|
return IsInteractive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PSID LocalSystemSid, ServiceSid;
|
||||||
|
BOOLEAN IsLocalSystem = FALSE;
|
||||||
|
BOOL HasServiceSid = FALSE;
|
||||||
|
HANDLE ProcessToken = 0, ImpersonationToken = 0;
|
||||||
|
DWORD SessionId, Size;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TOKEN_USER V;
|
||||||
|
UINT8 B[128];
|
||||||
|
} UserInfoBuf;
|
||||||
|
PTOKEN_USER UserInfo = &UserInfoBuf.V;
|
||||||
|
|
||||||
|
LocalSystemSid = FspWksidGet(WinLocalSystemSid);
|
||||||
|
ServiceSid = FspWksidGet(WinServiceSid);
|
||||||
|
if (0 == LocalSystemSid || 0 == ServiceSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == Token)
|
||||||
|
{
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &ProcessToken) ||
|
||||||
|
!DuplicateToken(ProcessToken, SecurityImpersonation, &ImpersonationToken))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = ImpersonationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenSessionId, &SessionId, sizeof SessionId, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != SessionId)
|
||||||
|
{
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, sizeof UserInfoBuf, &Size))
|
||||||
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo = MemAlloc(Size);
|
||||||
|
if (0 == UserInfo)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsLocalSystem = EqualSid(LocalSystemSid, UserInfo->User.Sid);
|
||||||
|
if (IsLocalSystem)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckTokenMembership(Token, ServiceSid, &HasServiceSid))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = HasServiceSid ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PIsLocalSystem)
|
||||||
|
*PIsLocalSystem = NT_SUCCESS(Result) ? IsLocalSystem : FALSE;
|
||||||
|
|
||||||
|
if (UserInfo != &UserInfoBuf.V)
|
||||||
|
MemFree(UserInfo);
|
||||||
|
|
||||||
|
if (0 != ImpersonationToken)
|
||||||
|
CloseHandle(ImpersonationToken);
|
||||||
|
|
||||||
|
if (0 != ProcessToken)
|
||||||
|
CloseHandle(ProcessToken);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/util.c
|
* @file dll/util.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -97,24 +97,14 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
|
|||||||
{
|
{
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSID OwnerSid, WellKnownSid = 0;
|
PSID OwnerSid, WellKnownSid = 0;
|
||||||
DWORD SidSize, LastError;
|
DWORD LastError;
|
||||||
|
|
||||||
/* if it is a small number treat it like a well known SID */
|
/* if it is a small number treat it like a well known SID */
|
||||||
if (1024 > (INT_PTR)Sid)
|
if (1024 > (INT_PTR)Sid)
|
||||||
{
|
{
|
||||||
SidSize = SECURITY_MAX_SID_SIZE;
|
WellKnownSid = FspWksidNew((INT_PTR)Sid, &Result);
|
||||||
WellKnownSid = MemAlloc(SidSize);
|
|
||||||
if (0 == WellKnownSid)
|
if (0 == WellKnownSid)
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto sid_exit;
|
goto sid_exit;
|
||||||
}
|
|
||||||
|
|
||||||
if (!CreateWellKnownSid((INT_PTR)Sid, 0, WellKnownSid, &SidSize))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto sid_exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LastError = GetSecurityInfo(Pipe, SE_FILE_OBJECT,
|
LastError = GetSecurityInfo(Pipe, SE_FILE_OBJECT,
|
||||||
|
108
src/dll/wksid.c
Normal file
108
src/dll/wksid.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* @file dll/wksid.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dll/library.h>
|
||||||
|
|
||||||
|
static INIT_ONCE FspWksidInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
|
static PSID FspWksidWorld;
|
||||||
|
static PSID FspWksidAuthenticatedUser;
|
||||||
|
static PSID FspWksidLocalSystem;
|
||||||
|
static PSID FspWksidService;
|
||||||
|
|
||||||
|
static BOOL WINAPI FspWksidInitialize(
|
||||||
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
|
{
|
||||||
|
FspWksidWorld = FspWksidNew(WinWorldSid, 0);
|
||||||
|
FspWksidAuthenticatedUser = FspWksidNew(WinAuthenticatedUserSid, 0);
|
||||||
|
FspWksidLocalSystem = FspWksidNew(WinLocalSystemSid, 0);
|
||||||
|
FspWksidService = FspWksidNew(WinServiceSid, 0);
|
||||||
|
|
||||||
|
//DEBUGLOGSID("FspWksidWorld=%s", FspWksidWorld);
|
||||||
|
//DEBUGLOGSID("FspWksidAuthenticatedUser=%s", FspWksidAuthenticatedUser);
|
||||||
|
//DEBUGLOGSID("FspWksidLocalSystem=%s", FspWksidLocalSystem);
|
||||||
|
//DEBUGLOGSID("FspWksidService=%s", FspWksidService);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspWksidFinalize(BOOLEAN Dynamic)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
|
||||||
|
* finalization tasks to a minimum.
|
||||||
|
*
|
||||||
|
* We must deregister our event source (if any). We only do so if the library
|
||||||
|
* is being explicitly unloaded (rather than the process exiting).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Dynamic)
|
||||||
|
{
|
||||||
|
MemFree(FspWksidWorld); FspWksidWorld = 0;
|
||||||
|
MemFree(FspWksidAuthenticatedUser); FspWksidAuthenticatedUser = 0;
|
||||||
|
MemFree(FspWksidLocalSystem); FspWksidLocalSystem = 0;
|
||||||
|
MemFree(FspWksidService); FspWksidService = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PSID Sid;
|
||||||
|
DWORD Size;
|
||||||
|
|
||||||
|
Size = SECURITY_MAX_SID_SIZE;
|
||||||
|
Sid = MemAlloc(Size);
|
||||||
|
if (0 == Sid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateWellKnownSid(WellKnownSidType, 0, Sid, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
MemFree(Sid); Sid = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PResult)
|
||||||
|
*PResult = Result;
|
||||||
|
|
||||||
|
return Sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType)
|
||||||
|
{
|
||||||
|
InitOnceExecuteOnce(&FspWksidInitOnce, FspWksidInitialize, 0, 0);
|
||||||
|
|
||||||
|
switch (WellKnownSidType)
|
||||||
|
{
|
||||||
|
case WinWorldSid:
|
||||||
|
return FspWksidWorld;
|
||||||
|
case WinAuthenticatedUserSid:
|
||||||
|
return FspWksidAuthenticatedUser;
|
||||||
|
case WinLocalSystemSid:
|
||||||
|
return FspWksidLocalSystem;
|
||||||
|
case WinServiceSid:
|
||||||
|
return FspWksidService;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/FileSystemBase+Const.cs
|
* dotnet/FileSystemBase+Const.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2017 Bill Zissimopoulos
|
* Copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/FileSystemBase.cs
|
* dotnet/FileSystemBase.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2017 Bill Zissimopoulos
|
* Copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -935,6 +935,37 @@ namespace Fsp
|
|||||||
StreamAllocationSize = default(UInt64);
|
StreamAllocationSize = default(UInt64);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets directory information for a single file or directory within a parent directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FileNode">
|
||||||
|
/// The file node of the parent directory.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="FileDesc">
|
||||||
|
/// The file descriptor of the parent directory.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="FileName">
|
||||||
|
/// The name of the file or directory to get information for. This name is relative
|
||||||
|
/// to the parent directory and is a single path component.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="NormalizedName">
|
||||||
|
/// Receives the normalized name from the directory entry.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="FileInfo">
|
||||||
|
/// Receives the file information.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>STATUS_SUCCESS or error code.</returns>
|
||||||
|
public virtual Int32 GetDirInfoByName(
|
||||||
|
Object FileNode,
|
||||||
|
Object FileDesc,
|
||||||
|
String FileName,
|
||||||
|
out String NormalizedName,
|
||||||
|
out FileInfo FileInfo)
|
||||||
|
{
|
||||||
|
NormalizedName = default(String);
|
||||||
|
FileInfo = default(FileInfo);
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -952,6 +983,16 @@ namespace Fsp
|
|||||||
return Api.FspWin32FromNtStatus(Status);
|
return Api.FspWin32FromNtStatus(Status);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Gets the originating process ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Valid only during Create, Open and Rename requests when the target exists.
|
||||||
|
/// </remarks>
|
||||||
|
public static int GetOperationProcessId()
|
||||||
|
{
|
||||||
|
return (int)Api.FspFileSystemOperationProcessId();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// Modifies a security descriptor.
|
/// Modifies a security descriptor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/FileSystemHost.cs
|
* dotnet/FileSystemHost.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2017 Bill Zissimopoulos
|
* Copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -189,6 +189,11 @@ namespace Fsp
|
|||||||
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryPattern); }
|
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryPattern); }
|
||||||
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryPattern : 0); }
|
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryPattern : 0); }
|
||||||
}
|
}
|
||||||
|
public Boolean PassQueryDirectoryFileName
|
||||||
|
{
|
||||||
|
get { return 0 != (_VolumeParams.Flags & VolumeParams.PassQueryDirectoryFileName); }
|
||||||
|
set { _VolumeParams.Flags |= (value ? VolumeParams.PassQueryDirectoryFileName : 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>
|
||||||
@ -987,6 +992,34 @@ namespace Fsp
|
|||||||
return ExceptionHandler(FileSystem, ex);
|
return ExceptionHandler(FileSystem, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static Int32 GetDirInfoByName(
|
||||||
|
IntPtr FileSystemPtr,
|
||||||
|
ref FullContext FullContext,
|
||||||
|
String FileName,
|
||||||
|
out DirInfo DirInfo)
|
||||||
|
{
|
||||||
|
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object FileNode, FileDesc;
|
||||||
|
String NormalizedName;
|
||||||
|
Api.GetFullContext(ref FullContext, out FileNode, out FileDesc);
|
||||||
|
DirInfo = default(DirInfo);
|
||||||
|
Int32 Result = FileSystem.GetDirInfoByName(
|
||||||
|
FileNode,
|
||||||
|
FileDesc,
|
||||||
|
FileName,
|
||||||
|
out NormalizedName,
|
||||||
|
out DirInfo.FileInfo);
|
||||||
|
DirInfo.SetFileNameBuf(NormalizedName);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
DirInfo = default(DirInfo);
|
||||||
|
return ExceptionHandler(FileSystem, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static FileSystemHost()
|
static FileSystemHost()
|
||||||
{
|
{
|
||||||
@ -1014,6 +1047,7 @@ namespace Fsp
|
|||||||
_FileSystemInterface.SetReparsePoint = SetReparsePoint;
|
_FileSystemInterface.SetReparsePoint = SetReparsePoint;
|
||||||
_FileSystemInterface.DeleteReparsePoint = DeleteReparsePoint;
|
_FileSystemInterface.DeleteReparsePoint = DeleteReparsePoint;
|
||||||
_FileSystemInterface.GetStreamInfo = GetStreamInfo;
|
_FileSystemInterface.GetStreamInfo = GetStreamInfo;
|
||||||
|
_FileSystemInterface.GetDirInfoByName = GetDirInfoByName;
|
||||||
|
|
||||||
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
|
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
|
||||||
Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false);
|
Marshal.StructureToPtr(_FileSystemInterface, _FileSystemInterfacePtr, false);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/Interop.cs
|
* dotnet/Interop.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2017 Bill Zissimopoulos
|
* Copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -42,6 +42,7 @@ namespace Fsp.Interop
|
|||||||
internal const UInt32 PostCleanupWhenModifiedOnly = 0x00000400;
|
internal const UInt32 PostCleanupWhenModifiedOnly = 0x00000400;
|
||||||
internal const UInt32 PassQueryDirectoryPattern = 0x00000800;
|
internal const UInt32 PassQueryDirectoryPattern = 0x00000800;
|
||||||
internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000;
|
internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000;
|
||||||
|
internal const UInt32 PassQueryDirectoryFileName = 0x00002000;
|
||||||
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
|
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
|
||||||
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
|
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
|
||||||
internal const int PrefixSize = 192;
|
internal const int PrefixSize = 192;
|
||||||
@ -450,6 +451,12 @@ namespace Fsp.Interop
|
|||||||
IntPtr Buffer,
|
IntPtr Buffer,
|
||||||
UInt32 Length,
|
UInt32 Length,
|
||||||
out UInt32 PBytesTransferred);
|
out UInt32 PBytesTransferred);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate Int32 GetDirInfoByName(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
ref FullContext FullContext,
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
||||||
|
out DirInfo DirInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int Size = IntPtr.Size * 64;
|
internal static int Size = IntPtr.Size * 64;
|
||||||
@ -478,7 +485,8 @@ namespace Fsp.Interop
|
|||||||
internal Proto.SetReparsePoint SetReparsePoint;
|
internal Proto.SetReparsePoint SetReparsePoint;
|
||||||
internal Proto.DeleteReparsePoint DeleteReparsePoint;
|
internal Proto.DeleteReparsePoint DeleteReparsePoint;
|
||||||
internal Proto.GetStreamInfo GetStreamInfo;
|
internal Proto.GetStreamInfo GetStreamInfo;
|
||||||
/* NTSTATUS (*Reserved[40])(); */
|
internal Proto.GetDirInfoByName GetDirInfoByName;
|
||||||
|
/* NTSTATUS (*Reserved[39])(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressUnmanagedCodeSecurity]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
@ -531,6 +539,8 @@ namespace Fsp.Interop
|
|||||||
IntPtr FileSystem,
|
IntPtr FileSystem,
|
||||||
UInt32 DebugLog);
|
UInt32 DebugLog);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate UInt32 FspFileSystemOperationProcessIdF();
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal delegate Boolean FspFileSystemAddDirInfo(
|
internal delegate Boolean FspFileSystemAddDirInfo(
|
||||||
IntPtr DirInfo,
|
IntPtr DirInfo,
|
||||||
@ -698,6 +708,7 @@ namespace Fsp.Interop
|
|||||||
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;
|
||||||
|
internal static Proto.FspFileSystemOperationProcessIdF FspFileSystemOperationProcessId;
|
||||||
internal static Proto.FspFileSystemAddDirInfo _FspFileSystemAddDirInfo;
|
internal static Proto.FspFileSystemAddDirInfo _FspFileSystemAddDirInfo;
|
||||||
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
||||||
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
||||||
@ -1007,6 +1018,7 @@ namespace Fsp.Interop
|
|||||||
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);
|
||||||
|
FspFileSystemOperationProcessId = GetEntryPoint<Proto.FspFileSystemOperationProcessIdF>(Module);
|
||||||
_FspFileSystemAddDirInfo = GetEntryPoint<Proto.FspFileSystemAddDirInfo>(Module);
|
_FspFileSystemAddDirInfo = GetEntryPoint<Proto.FspFileSystemAddDirInfo>(Module);
|
||||||
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
||||||
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/Service.cs
|
* dotnet/Service.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2017 Bill Zissimopoulos
|
* Copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
37
src/fsptool/fsptool-version.rc
Normal file
37
src/fsptool/fsptool-version.rc
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include <winver.h>
|
||||||
|
|
||||||
|
#define STR(x) STR_(x)
|
||||||
|
#define STR_(x) #x
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION MyVersionWithCommas
|
||||||
|
PRODUCTVERSION MyVersionWithCommas
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0
|
||||||
|
#endif
|
||||||
|
FILEOS VOS_NT
|
||||||
|
FILETYPE VFT_APP
|
||||||
|
FILESUBTYPE 0
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", STR(MyCompanyName)
|
||||||
|
VALUE "FileDescription", STR(MyDescription)
|
||||||
|
VALUE "FileVersion", STR(MyFullVersion)
|
||||||
|
VALUE "InternalName", "fsptool.exe"
|
||||||
|
VALUE "LegalCopyright", STR(MyCopyright)
|
||||||
|
VALUE "OriginalFilename", "fsptool.exe"
|
||||||
|
VALUE "ProductName", STR(MyProductName)
|
||||||
|
VALUE "ProductVersion", STR(MyProductVersion)
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
602
src/fsptool/fsptool.c
Normal file
602
src/fsptool/fsptool.c
Normal file
@ -0,0 +1,602 @@
|
|||||||
|
/**
|
||||||
|
* @file fsptool/fsptool.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <winfsp/winfsp.h>
|
||||||
|
#include <shared/minimal.h>
|
||||||
|
#include <aclapi.h>
|
||||||
|
#include <sddl.h>
|
||||||
|
|
||||||
|
#define PROGNAME "fsptool"
|
||||||
|
|
||||||
|
#define info(format, ...) printlog(GetStdHandle(STD_OUTPUT_HANDLE), format, __VA_ARGS__)
|
||||||
|
#define warn(format, ...) printlog(GetStdHandle(STD_ERROR_HANDLE), format, __VA_ARGS__)
|
||||||
|
#define fatal(ExitCode, format, ...) (warn(format, __VA_ARGS__), ExitProcess(ExitCode))
|
||||||
|
|
||||||
|
static void vprintlog(HANDLE h, const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
/* wvsprintf is only safe with a 1024 byte buffer */
|
||||||
|
size_t len;
|
||||||
|
DWORD BytesTransferred;
|
||||||
|
|
||||||
|
wvsprintfA(buf, format, ap);
|
||||||
|
buf[sizeof buf - 1] = '\0';
|
||||||
|
|
||||||
|
len = lstrlenA(buf);
|
||||||
|
buf[len++] = '\n';
|
||||||
|
|
||||||
|
WriteFile(h, buf, (DWORD)len, &BytesTransferred, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printlog(HANDLE h, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
vprintlog(h, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned wcstoint(const wchar_t *p, const wchar_t **endp, int base)
|
||||||
|
{
|
||||||
|
unsigned v;
|
||||||
|
int maxdig, maxalp;
|
||||||
|
|
||||||
|
maxdig = 10 < base ? '9' : (base - 1) + '0';
|
||||||
|
maxalp = 10 < base ? (base - 1 - 10) + 'a' : 0;
|
||||||
|
|
||||||
|
for (v = 0; *p; p++)
|
||||||
|
{
|
||||||
|
int c = *p;
|
||||||
|
|
||||||
|
if ('0' <= c && c <= maxdig)
|
||||||
|
v = base * v + (c - '0');
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c |= 0x20;
|
||||||
|
if ('a' <= c && c <= maxalp)
|
||||||
|
v = base * v + (c - 'a') + 10;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != endp)
|
||||||
|
*endp = (wchar_t *)p;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(void)
|
||||||
|
{
|
||||||
|
fatal(ERROR_INVALID_PARAMETER,
|
||||||
|
"usage: %s COMMAND ARGS\n"
|
||||||
|
"\n"
|
||||||
|
"commands:\n"
|
||||||
|
" lsvol list file system devices (volumes)\n"
|
||||||
|
//" list list running file system processes\n"
|
||||||
|
//" kill kill file system process\n"
|
||||||
|
" id [NAME|SID|UID] print user id\n"
|
||||||
|
" perm [PATH|SDDL|UID:GID:MODE] print permissions\n",
|
||||||
|
PROGNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspToolGetVolumeList(PWSTR DeviceName,
|
||||||
|
PWCHAR *PVolumeListBuf, PSIZE_T PVolumeListSize)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWCHAR VolumeListBuf;
|
||||||
|
SIZE_T VolumeListSize;
|
||||||
|
|
||||||
|
*PVolumeListBuf = 0;
|
||||||
|
*PVolumeListSize = 0;
|
||||||
|
|
||||||
|
for (VolumeListSize = 1024;; VolumeListSize *= 2)
|
||||||
|
{
|
||||||
|
VolumeListBuf = MemAlloc(VolumeListSize);
|
||||||
|
if (0 == VolumeListBuf)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
Result = FspFsctlGetVolumeList(DeviceName,
|
||||||
|
VolumeListBuf, &VolumeListSize);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
*PVolumeListBuf = VolumeListBuf;
|
||||||
|
*PVolumeListSize = VolumeListSize;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(VolumeListBuf);
|
||||||
|
|
||||||
|
if (STATUS_BUFFER_TOO_SMALL != Result)
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR FspToolGetDriveLetter(PDWORD PLogicalDrives, PWSTR VolumeName)
|
||||||
|
{
|
||||||
|
WCHAR VolumeNameBuf[MAX_PATH];
|
||||||
|
WCHAR LocalNameBuf[3];
|
||||||
|
WCHAR Drive;
|
||||||
|
|
||||||
|
if (0 == *PLogicalDrives)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
LocalNameBuf[1] = L':';
|
||||||
|
LocalNameBuf[2] = L'\0';
|
||||||
|
|
||||||
|
for (Drive = 'Z'; 'A' <= Drive; Drive--)
|
||||||
|
if (0 != (*PLogicalDrives & (1 << (Drive - 'A'))))
|
||||||
|
{
|
||||||
|
LocalNameBuf[0] = Drive;
|
||||||
|
if (QueryDosDeviceW(LocalNameBuf, VolumeNameBuf, sizeof VolumeNameBuf / sizeof(WCHAR)))
|
||||||
|
{
|
||||||
|
if (0 == invariant_wcscmp(VolumeNameBuf, VolumeName))
|
||||||
|
{
|
||||||
|
*PLogicalDrives &= ~(1 << (Drive - 'A'));
|
||||||
|
return Drive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspToolGetTokenInfo(HANDLE Token,
|
||||||
|
TOKEN_INFORMATION_CLASS TokenInformationClass, PVOID *PInfo)
|
||||||
|
{
|
||||||
|
PVOID Info = 0;
|
||||||
|
DWORD Size;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (GetTokenInformation(Token, TokenInformationClass, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info = MemAlloc(Size);
|
||||||
|
if (0 == Info)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenInformationClass, Info, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*PInfo = Info;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
MemFree(Info);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspToolGetNameFromSid(PSID Sid, PWSTR *PName)
|
||||||
|
{
|
||||||
|
WCHAR Name[256], Domn[256];
|
||||||
|
DWORD NameSize, DomnSize;
|
||||||
|
SID_NAME_USE Use;
|
||||||
|
PWSTR P;
|
||||||
|
|
||||||
|
NameSize = sizeof Name / sizeof Name[0];
|
||||||
|
DomnSize = sizeof Domn / sizeof Domn[0];
|
||||||
|
if (!LookupAccountSidW(0, Sid, Name, &NameSize, Domn, &DomnSize, &Use))
|
||||||
|
{
|
||||||
|
Name[0] = L'\0';
|
||||||
|
Domn[0] = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
NameSize = lstrlenW(Name);
|
||||||
|
DomnSize = lstrlenW(Domn);
|
||||||
|
|
||||||
|
P = *PName = MemAlloc((DomnSize + 1 + NameSize + 1) * sizeof(WCHAR));
|
||||||
|
if (0 == P)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
if (0 < DomnSize)
|
||||||
|
{
|
||||||
|
memcpy(P, Domn, DomnSize * sizeof(WCHAR));
|
||||||
|
P[DomnSize] = L'\\';
|
||||||
|
P += DomnSize + 1;
|
||||||
|
}
|
||||||
|
memcpy(P, Name, NameSize * sizeof(WCHAR));
|
||||||
|
P[NameSize] = L'\0';
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspToolGetSidFromName(PWSTR Name, PSID *PSid)
|
||||||
|
{
|
||||||
|
PSID Sid;
|
||||||
|
WCHAR Domn[256];
|
||||||
|
DWORD SidSize, DomnSize;
|
||||||
|
SID_NAME_USE Use;
|
||||||
|
|
||||||
|
SidSize = 0;
|
||||||
|
DomnSize = sizeof Domn / sizeof Domn[0];
|
||||||
|
if (LookupAccountNameW(0, Name, 0, &SidSize, Domn, &DomnSize, &Use))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
Sid = MemAlloc(SidSize);
|
||||||
|
if (0 == Sid)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
DomnSize = sizeof Domn / sizeof Domn[0];
|
||||||
|
if (!LookupAccountNameW(0, Name, Sid, &SidSize, Domn, &DomnSize, &Use))
|
||||||
|
{
|
||||||
|
MemFree(Sid);
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
*PSid = Sid;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS lsvol_dev(PWSTR DeviceName)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWCHAR VolumeListBuf, VolumeListBufEnd;
|
||||||
|
SIZE_T VolumeListSize;
|
||||||
|
DWORD LogicalDrives;
|
||||||
|
WCHAR Drive[3] = L"\0:";
|
||||||
|
|
||||||
|
Result = FspToolGetVolumeList(DeviceName, &VolumeListBuf, &VolumeListSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
VolumeListBufEnd = (PVOID)((PUINT8)VolumeListBuf + VolumeListSize);
|
||||||
|
|
||||||
|
LogicalDrives = GetLogicalDrives();
|
||||||
|
for (PWCHAR P = VolumeListBuf, VolumeName = P; VolumeListBufEnd > P; P++)
|
||||||
|
if (L'\0' == *P)
|
||||||
|
{
|
||||||
|
Drive[0] = FspToolGetDriveLetter(&LogicalDrives, VolumeName);
|
||||||
|
info("%-4S%S", Drive[0] ? Drive : L"", VolumeName);
|
||||||
|
VolumeName = P + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemFree(VolumeListBuf);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lsvol(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = lsvol_dev(L"" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
Result = lsvol_dev(L"" FSP_FSCTL_NET_DEVICE_NAME);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS id_print_sid(const char *format, PSID Sid)
|
||||||
|
{
|
||||||
|
PWSTR Str = 0;
|
||||||
|
PWSTR Name = 0;
|
||||||
|
UINT32 Uid;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (!ConvertSidToStringSidW(Sid, &Str))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspToolGetNameFromSid(Sid, &Name);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspPosixMapSidToUid(Sid, &Uid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
info(format, Str, Name, Uid);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Name);
|
||||||
|
LocalFree(Str);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS id_name(PWSTR Name)
|
||||||
|
{
|
||||||
|
PSID Sid = 0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspToolGetSidFromName(Name, &Sid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
id_print_sid("%S(%S) (uid=%u)", Sid);
|
||||||
|
|
||||||
|
MemFree(Sid);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS id_sid(PWSTR SidStr)
|
||||||
|
{
|
||||||
|
PSID Sid = 0;
|
||||||
|
|
||||||
|
if (!ConvertStringSidToSid(SidStr, &Sid))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
id_print_sid("%S(%S) (uid=%u)", Sid);
|
||||||
|
|
||||||
|
LocalFree(Sid);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS id_uid(PWSTR UidStr)
|
||||||
|
{
|
||||||
|
PSID Sid = 0;
|
||||||
|
UINT32 Uid;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Uid = wcstoint(UidStr, &UidStr, 10);
|
||||||
|
if (L'\0' != *UidStr)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspPosixMapUidToSid(Uid, &Sid);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
id_print_sid("%S(%S) (uid=%u)", Sid);
|
||||||
|
|
||||||
|
FspDeleteSid(Sid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS id_user(void)
|
||||||
|
{
|
||||||
|
HANDLE Token = 0;
|
||||||
|
TOKEN_USER *Uinfo = 0;
|
||||||
|
TOKEN_OWNER *Oinfo = 0;
|
||||||
|
TOKEN_PRIMARY_GROUP *Ginfo = 0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspToolGetTokenInfo(Token, TokenUser, &Uinfo);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspToolGetTokenInfo(Token, TokenOwner, &Oinfo);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = FspToolGetTokenInfo(Token, TokenPrimaryGroup, &Ginfo);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
id_print_sid("User=%S(%S) (uid=%u)", Uinfo->User.Sid);
|
||||||
|
id_print_sid("Owner=%S(%S) (uid=%u)", Oinfo->Owner);
|
||||||
|
id_print_sid("Group=%S(%S) (gid=%u)", Ginfo->PrimaryGroup);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Ginfo);
|
||||||
|
MemFree(Oinfo);
|
||||||
|
MemFree(Uinfo);
|
||||||
|
|
||||||
|
if (0 != Token)
|
||||||
|
CloseHandle(Token);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int id(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (2 < argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (2 == argc)
|
||||||
|
{
|
||||||
|
if (L'S' == argv[1][0] && L'-' == argv[1][1] && L'1' == argv[1][2] && L'-' == argv[1][3])
|
||||||
|
Result = id_sid(argv[1]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = id_uid(argv[1]);
|
||||||
|
if (STATUS_INVALID_PARAMETER == Result)
|
||||||
|
Result = id_name(argv[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = id_user();
|
||||||
|
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS perm_print_sd(PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||||
|
{
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
PWSTR Sddl = 0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspPosixMapSecurityDescriptorToPermissions(SecurityDescriptor, &Uid, &Gid, &Mode);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (!ConvertSecurityDescriptorToStringSecurityDescriptorW(
|
||||||
|
SecurityDescriptor, SDDL_REVISION_1,
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
&Sddl, 0))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
info("%S (perm=%u:%u:%d%d%d%d)",
|
||||||
|
Sddl, Uid, Gid, (Mode >> 9) & 7, (Mode >> 6) & 7, (Mode >> 3) & 7, Mode & 7);
|
||||||
|
|
||||||
|
LocalFree(Sddl);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS perm_path(PWSTR Path)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
int ErrorCode;
|
||||||
|
|
||||||
|
ErrorCode = GetNamedSecurityInfoW(Path, SE_FILE_OBJECT,
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
0, 0, 0, 0, &SecurityDescriptor);
|
||||||
|
if (0 != ErrorCode)
|
||||||
|
return FspNtStatusFromWin32(ErrorCode);
|
||||||
|
|
||||||
|
perm_print_sd(SecurityDescriptor);
|
||||||
|
|
||||||
|
LocalFree(SecurityDescriptor);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS perm_sddl(PWSTR Sddl)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
|
||||||
|
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||||
|
Sddl, SDDL_REVISION_1, &SecurityDescriptor, 0))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
perm_print_sd(SecurityDescriptor);
|
||||||
|
|
||||||
|
LocalFree(SecurityDescriptor);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS perm_mode(PWSTR PermStr)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
UINT32 Uid, Gid, Mode;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Uid = wcstoint(PermStr, &PermStr, 10);
|
||||||
|
if (L':' != *PermStr)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
Gid = wcstoint(PermStr + 1, &PermStr, 10);
|
||||||
|
if (L':' != *PermStr)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
Mode = wcstoint(PermStr + 1, &PermStr, 8);
|
||||||
|
if (L'\0' != *PermStr)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspPosixMapPermissionsToSecurityDescriptor(Uid, Gid, Mode, &SecurityDescriptor);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
perm_print_sd(SecurityDescriptor);
|
||||||
|
|
||||||
|
FspDeleteSecurityDescriptor(SecurityDescriptor,
|
||||||
|
FspPosixMapPermissionsToSecurityDescriptor);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int perm(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (2 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWSTR P;
|
||||||
|
|
||||||
|
for (P = argv[1]; *P; P++)
|
||||||
|
if (L'\\' == *P)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (L'\\' == *P)
|
||||||
|
Result = perm_path(argv[1]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = perm_mode(argv[1]);
|
||||||
|
if (STATUS_INVALID_PARAMETER == Result)
|
||||||
|
Result = perm_sddl(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wmain(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
if (0 == argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
if (0 == invariant_wcscmp(L"lsvol", argv[0]))
|
||||||
|
return lsvol(argc, argv);
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"id", argv[0]))
|
||||||
|
return id(argc, argv);
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"perm", argv[0]))
|
||||||
|
return perm(argc, argv);
|
||||||
|
else
|
||||||
|
usage();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wmainCRTStartup(void)
|
||||||
|
{
|
||||||
|
DWORD Argc;
|
||||||
|
PWSTR *Argv;
|
||||||
|
|
||||||
|
Argv = CommandLineToArgvW(GetCommandLineW(), &Argc);
|
||||||
|
if (0 == Argv)
|
||||||
|
ExitProcess(GetLastError());
|
||||||
|
|
||||||
|
ExitProcess(wmain(Argc, Argv));
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launchctl.c
|
* @file launcher/launchctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launcher.c
|
* @file launcher/launcher.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -16,17 +16,30 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <launcher/launcher.h>
|
#include <launcher/launcher.h>
|
||||||
|
#include <aclapi.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
#include <userenv.h>
|
||||||
|
|
||||||
#define PROGNAME "WinFsp.Launcher"
|
#define PROGNAME "WinFsp.Launcher"
|
||||||
|
|
||||||
BOOL CreateOverlappedPipe(
|
static NTSTATUS (NTAPI *SvcNtOpenSymbolicLinkObject)(
|
||||||
PHANDLE PReadPipe, PHANDLE PWritePipe, PSECURITY_ATTRIBUTES SecurityAttributes, DWORD Size,
|
PHANDLE LinkHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes);
|
||||||
|
static NTSTATUS (NTAPI *SvcNtClose)(
|
||||||
|
HANDLE Handle);
|
||||||
|
|
||||||
|
static BOOL CreateOverlappedPipe(
|
||||||
|
PHANDLE PReadPipe, PHANDLE PWritePipe,
|
||||||
|
DWORD Size,
|
||||||
|
BOOL ReadInherit, BOOL WriteInherit,
|
||||||
DWORD ReadMode, DWORD WriteMode)
|
DWORD ReadMode, DWORD WriteMode)
|
||||||
{
|
{
|
||||||
RPC_STATUS RpcStatus;
|
RPC_STATUS RpcStatus;
|
||||||
UUID Uuid;
|
UUID Uuid;
|
||||||
WCHAR PipeNameBuf[MAX_PATH];
|
WCHAR PipeNameBuf[MAX_PATH];
|
||||||
|
SECURITY_ATTRIBUTES ReadSecurityAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, ReadInherit };
|
||||||
|
SECURITY_ATTRIBUTES WriteSecurityAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, WriteInherit };
|
||||||
HANDLE ReadPipe, WritePipe;
|
HANDLE ReadPipe, WritePipe;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
|
|
||||||
@ -46,13 +59,13 @@ BOOL CreateOverlappedPipe(
|
|||||||
ReadPipe = CreateNamedPipeW(PipeNameBuf,
|
ReadPipe = CreateNamedPipeW(PipeNameBuf,
|
||||||
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | ReadMode,
|
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | ReadMode,
|
||||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
||||||
1, Size, Size, 120 * 1000, SecurityAttributes);
|
1, Size, Size, 120 * 1000, &ReadSecurityAttributes);
|
||||||
if (INVALID_HANDLE_VALUE == ReadPipe)
|
if (INVALID_HANDLE_VALUE == ReadPipe)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
WritePipe = CreateFileW(PipeNameBuf,
|
WritePipe = CreateFileW(PipeNameBuf,
|
||||||
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
SecurityAttributes, OPEN_EXISTING, WriteMode, 0);
|
&WriteSecurityAttributes, OPEN_EXISTING, WriteMode, 0);
|
||||||
if (INVALID_HANDLE_VALUE == WritePipe)
|
if (INVALID_HANDLE_VALUE == WritePipe)
|
||||||
{
|
{
|
||||||
LastError = GetLastError();
|
LastError = GetLastError();
|
||||||
@ -67,6 +80,279 @@ BOOL CreateOverlappedPipe(
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS GetTokenUserName(HANDLE Token, PWSTR *PUserName)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TOKEN_USER V;
|
||||||
|
UINT8 B[128];
|
||||||
|
} UserInfoBuf;
|
||||||
|
PTOKEN_USER UserInfo = &UserInfoBuf.V;
|
||||||
|
WCHAR Name[256], Domn[256];
|
||||||
|
DWORD UserSize, NameSize, DomnSize;
|
||||||
|
SID_NAME_USE Use;
|
||||||
|
PWSTR P;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PUserName = 0;
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, sizeof UserInfoBuf, &UserSize))
|
||||||
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo = MemAlloc(UserSize);
|
||||||
|
if (0 == UserInfo)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, UserSize, &UserSize))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NameSize = sizeof Name / sizeof Name[0];
|
||||||
|
DomnSize = sizeof Domn / sizeof Domn[0];
|
||||||
|
if (!LookupAccountSidW(0, UserInfo->User.Sid, Name, &NameSize, Domn, &DomnSize, &Use))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
NameSize = lstrlenW(Name);
|
||||||
|
DomnSize = lstrlenW(Domn);
|
||||||
|
|
||||||
|
P = *PUserName = MemAlloc((DomnSize + 1 + NameSize + 1) * sizeof(WCHAR));
|
||||||
|
if (0 == P)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < DomnSize)
|
||||||
|
{
|
||||||
|
memcpy(P, Domn, DomnSize * sizeof(WCHAR));
|
||||||
|
P[DomnSize] = L'\\';
|
||||||
|
P += DomnSize + 1;
|
||||||
|
}
|
||||||
|
memcpy(P, Name, NameSize * sizeof(WCHAR));
|
||||||
|
P[NameSize] = L'\0';
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (UserInfo != &UserInfoBuf.V)
|
||||||
|
MemFree(UserInfo);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS AddAccessForTokenUser(HANDLE Handle, DWORD Access, HANDLE Token)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TOKEN_USER V;
|
||||||
|
UINT8 B[128];
|
||||||
|
} UserInfoBuf;
|
||||||
|
PTOKEN_USER UserInfo = &UserInfoBuf.V;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
DWORD Size, LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, sizeof UserInfoBuf, &Size))
|
||||||
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo = MemAlloc(Size);
|
||||||
|
if (0 == UserInfo)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityDescriptor = MemAlloc(Size);
|
||||||
|
if (0 == SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessEntry.grfAccessPermissions = Access;
|
||||||
|
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
||||||
|
AccessEntry.grfInheritance = NO_INHERITANCE;
|
||||||
|
AccessEntry.Trustee.pMultipleTrustee = 0;
|
||||||
|
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
|
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
|
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
|
AccessEntry.Trustee.ptstrName = UserInfo->User.Sid;
|
||||||
|
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
LocalFree(NewSecurityDescriptor);
|
||||||
|
MemFree(SecurityDescriptor);
|
||||||
|
if (UserInfo != &UserInfoBuf.V)
|
||||||
|
MemFree(UserInfo);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL LogonCreateProcess(
|
||||||
|
PWSTR UserName,
|
||||||
|
LPCWSTR ApplicationName,
|
||||||
|
LPWSTR CommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES ProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES ThreadAttributes,
|
||||||
|
BOOL InheritHandles,
|
||||||
|
DWORD CreationFlags,
|
||||||
|
LPVOID Environment,
|
||||||
|
LPCWSTR CurrentDirectory,
|
||||||
|
LPSTARTUPINFOW StartupInfo,
|
||||||
|
LPPROCESS_INFORMATION ProcessInformation)
|
||||||
|
{
|
||||||
|
PWSTR DomainName = 0;
|
||||||
|
|
||||||
|
if (0 != UserName)
|
||||||
|
{
|
||||||
|
if (0 == invariant_wcsicmp(UserName, L"LocalSystem"))
|
||||||
|
UserName = 0;
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcsicmp(UserName, L"LocalService") ||
|
||||||
|
0 == invariant_wcsicmp(UserName, L"NetworkService"))
|
||||||
|
DomainName = L"NT AUTHORITY";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == UserName)
|
||||||
|
/* without a user name go ahead and call CreateProcessW */
|
||||||
|
return CreateProcessW(
|
||||||
|
ApplicationName,
|
||||||
|
CommandLine,
|
||||||
|
ProcessAttributes,
|
||||||
|
ThreadAttributes,
|
||||||
|
InheritHandles,
|
||||||
|
CreationFlags,
|
||||||
|
Environment,
|
||||||
|
CurrentDirectory,
|
||||||
|
StartupInfo,
|
||||||
|
ProcessInformation);
|
||||||
|
|
||||||
|
HANDLE LogonToken = 0;
|
||||||
|
PVOID EnvironmentBlock = 0;
|
||||||
|
DWORD LastError;
|
||||||
|
BOOL Success;
|
||||||
|
|
||||||
|
Success = LogonUserW(
|
||||||
|
UserName,
|
||||||
|
DomainName,
|
||||||
|
0,
|
||||||
|
LOGON32_LOGON_SERVICE,
|
||||||
|
LOGON32_PROVIDER_DEFAULT,
|
||||||
|
&LogonToken);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (0 == Environment)
|
||||||
|
{
|
||||||
|
Success = CreateEnvironmentBlock(&EnvironmentBlock, LogonToken, FALSE);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
CreationFlags |= CREATE_UNICODE_ENVIRONMENT;
|
||||||
|
Environment = EnvironmentBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ImpersonateLoggedOnUser(LogonToken);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Success = CreateProcessAsUserW(
|
||||||
|
LogonToken,
|
||||||
|
ApplicationName,
|
||||||
|
CommandLine,
|
||||||
|
ProcessAttributes,
|
||||||
|
ThreadAttributes,
|
||||||
|
InheritHandles,
|
||||||
|
CreationFlags,
|
||||||
|
Environment,
|
||||||
|
CurrentDirectory,
|
||||||
|
StartupInfo,
|
||||||
|
ProcessInformation);
|
||||||
|
|
||||||
|
if (!RevertToSelf())
|
||||||
|
/* should not happen! */
|
||||||
|
ExitProcess(GetLastError());
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!Success)
|
||||||
|
LastError = GetLastError();
|
||||||
|
|
||||||
|
if (0 != EnvironmentBlock)
|
||||||
|
DestroyEnvironmentBlock(EnvironmentBlock);
|
||||||
|
if (0 != LogonToken)
|
||||||
|
CloseHandle(LogonToken);
|
||||||
|
|
||||||
|
if (!Success)
|
||||||
|
SetLastError(LastError);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Process;
|
HANDLE Process;
|
||||||
@ -75,7 +361,7 @@ typedef struct
|
|||||||
|
|
||||||
static VOID CALLBACK KillProcessWait(PVOID Context, BOOLEAN Timeout);
|
static VOID CALLBACK KillProcessWait(PVOID Context, BOOLEAN Timeout);
|
||||||
|
|
||||||
VOID KillProcess(ULONG ProcessId, HANDLE Process, ULONG Timeout)
|
static VOID KillProcess(ULONG ProcessId, HANDLE Process, ULONG Timeout)
|
||||||
{
|
{
|
||||||
if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, ProcessId))
|
if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, ProcessId))
|
||||||
{
|
{
|
||||||
@ -142,6 +428,17 @@ typedef struct
|
|||||||
static CRITICAL_SECTION SvcInstanceLock;
|
static CRITICAL_SECTION SvcInstanceLock;
|
||||||
static HANDLE SvcInstanceEvent;
|
static HANDLE SvcInstanceEvent;
|
||||||
static LIST_ENTRY SvcInstanceList = { &SvcInstanceList, &SvcInstanceList };
|
static LIST_ENTRY SvcInstanceList = { &SvcInstanceList, &SvcInstanceList };
|
||||||
|
static DWORD SvcInstanceTlsKey = TLS_OUT_OF_INDEXES;
|
||||||
|
|
||||||
|
static inline PWSTR SvcInstanceUserName(VOID)
|
||||||
|
{
|
||||||
|
return TlsGetValue(SvcInstanceTlsKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VOID SvcInstanceSetUserName(PWSTR UserName)
|
||||||
|
{
|
||||||
|
TlsSetValue(SvcInstanceTlsKey, UserName);
|
||||||
|
}
|
||||||
|
|
||||||
static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout);
|
static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout);
|
||||||
|
|
||||||
@ -210,6 +507,14 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
else
|
else
|
||||||
Length += SvcInstanceArgumentLength(EmptyArg);
|
Length += SvcInstanceArgumentLength(EmptyArg);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (L'U' == *P)
|
||||||
|
{
|
||||||
|
if (0 != SvcInstanceUserName())
|
||||||
|
Length += SvcInstanceArgumentLength(SvcInstanceUserName());
|
||||||
|
else
|
||||||
|
Length += SvcInstanceArgumentLength(EmptyArg);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Length++;
|
Length++;
|
||||||
break;
|
break;
|
||||||
@ -236,6 +541,14 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
else
|
else
|
||||||
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (L'U' == *P)
|
||||||
|
{
|
||||||
|
if (0 != SvcInstanceUserName())
|
||||||
|
Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName());
|
||||||
|
else
|
||||||
|
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*Q++ = *P;
|
*Q++ = *P;
|
||||||
break;
|
break;
|
||||||
@ -251,6 +564,67 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS SvcInstanceAddUserRights(HANDLE Token,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR *PNewSecurityDescriptor)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor;
|
||||||
|
TOKEN_USER *User = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
DWORD Size, LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PNewSecurityDescriptor = 0;
|
||||||
|
|
||||||
|
if (GetTokenInformation(Token, TokenUser, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
User = MemAlloc(Size);
|
||||||
|
if (0 == User)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, User, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessEntry.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_STOP;
|
||||||
|
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
||||||
|
AccessEntry.grfInheritance = NO_INHERITANCE;
|
||||||
|
AccessEntry.Trustee.pMultipleTrustee = 0;
|
||||||
|
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
|
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
|
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
|
AccessEntry.Trustee.ptstrName = User->User.Sid;
|
||||||
|
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*PNewSecurityDescriptor = NewSecurityDescriptor;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(User);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor)
|
PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||||
{
|
{
|
||||||
@ -279,18 +653,35 @@ static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
static NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
|
||||||
|
PWSTR Executable, PWSTR CommandLine, PWSTR WorkDirectory,
|
||||||
HANDLE StdioHandles[2],
|
HANDLE StdioHandles[2],
|
||||||
PPROCESS_INFORMATION ProcessInfo)
|
PPROCESS_INFORMATION ProcessInfo)
|
||||||
{
|
{
|
||||||
|
WCHAR WorkDirectoryBuf[MAX_PATH];
|
||||||
STARTUPINFOEXW StartupInfoEx;
|
STARTUPINFOEXW StartupInfoEx;
|
||||||
HANDLE ChildHandles[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0/* DO NOT CLOSE!*/ };
|
HANDLE ChildHandles[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0/* DO NOT CLOSE!*/ };
|
||||||
HANDLE ParentHandles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
HANDLE ParentHandles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
|
||||||
SECURITY_ATTRIBUTES PipeAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE };
|
|
||||||
PPROC_THREAD_ATTRIBUTE_LIST AttrList = 0;
|
PPROC_THREAD_ATTRIBUTE_LIST AttrList = 0;
|
||||||
SIZE_T Size;
|
SIZE_T Size;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 != WorkDirectory && L'.' == WorkDirectory[0] && L'\0' == WorkDirectory[1])
|
||||||
|
{
|
||||||
|
PWSTR Backslash = 0, P;
|
||||||
|
|
||||||
|
if (0 == GetModuleFileNameW(0, WorkDirectoryBuf, MAX_PATH))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
for (P = WorkDirectoryBuf; *P; P++)
|
||||||
|
if (L'\\' == *P)
|
||||||
|
Backslash = P;
|
||||||
|
if (0 != Backslash && WorkDirectoryBuf < Backslash && L':' != Backslash[-1])
|
||||||
|
*Backslash = L'\0';
|
||||||
|
|
||||||
|
WorkDirectory = WorkDirectoryBuf;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&StartupInfoEx, 0, sizeof StartupInfoEx);
|
memset(&StartupInfoEx, 0, sizeof StartupInfoEx);
|
||||||
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
|
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
|
||||||
|
|
||||||
@ -304,16 +695,16 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* create stdin read/write ends; make them inheritable */
|
/* create stdin read/write ends; make them inheritable */
|
||||||
if (!CreateOverlappedPipe(&ChildHandles[0], &ParentHandles[0], &PipeAttributes, 0,
|
if (!CreateOverlappedPipe(&ChildHandles[0], &ParentHandles[0],
|
||||||
0, 0))
|
0, TRUE, FALSE, 0, 0))
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create stdout read/write ends; make them inheritable */
|
/* create stdout read/write ends; make them inheritable */
|
||||||
if (!CreateOverlappedPipe(&ParentHandles[1], &ChildHandles[1], &PipeAttributes, 0,
|
if (!CreateOverlappedPipe(&ParentHandles[1], &ChildHandles[1],
|
||||||
FILE_FLAG_OVERLAPPED, 0))
|
0, FALSE, TRUE, FILE_FLAG_OVERLAPPED, 0))
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -357,18 +748,44 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
|||||||
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
|
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
|
||||||
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
|
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
|
||||||
|
|
||||||
if (!CreateProcessW(Executable, CommandLine, 0, 0, TRUE,
|
if (!LogonCreateProcess(UserName,
|
||||||
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0,
|
Executable, CommandLine, 0, 0, TRUE,
|
||||||
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT,
|
||||||
|
0, WorkDirectory,
|
||||||
&StartupInfoEx.StartupInfo, ProcessInfo))
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
if (ERROR_NO_SYSTEM_RESOURCES != GetLastError())
|
||||||
goto exit;
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On Win7 CreateProcessW with EXTENDED_STARTUPINFO_PRESENT
|
||||||
|
* may fail with ERROR_NO_SYSTEM_RESOURCES.
|
||||||
|
*
|
||||||
|
* In that case go ahead and retry with a CreateProcessW with
|
||||||
|
* bInheritHandles==TRUE, but without EXTENDED_STARTUPINFO_PRESENT.
|
||||||
|
* Not ideal, but...
|
||||||
|
*/
|
||||||
|
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
|
||||||
|
if (!LogonCreateProcess(UserName,
|
||||||
|
Executable, CommandLine, 0, 0, TRUE,
|
||||||
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
|
||||||
|
0, WorkDirectory,
|
||||||
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!CreateProcessW(Executable, CommandLine, 0, 0, FALSE,
|
if (!LogonCreateProcess(UserName,
|
||||||
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
|
Executable, CommandLine, 0, 0, FALSE,
|
||||||
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP,
|
||||||
|
0, WorkDirectory,
|
||||||
&StartupInfoEx.StartupInfo, ProcessInfo))
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
{
|
{
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
@ -411,10 +828,11 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
HKEY RegKey = 0;
|
HKEY RegKey = 0;
|
||||||
DWORD RegResult, RegSize;
|
DWORD RegResult, RegSize;
|
||||||
DWORD ClassNameSize, InstanceNameSize;
|
DWORD ClassNameSize, InstanceNameSize;
|
||||||
WCHAR Executable[MAX_PATH], CommandLineBuf[512], SecurityBuf[512];
|
WCHAR Executable[MAX_PATH], CommandLineBuf[512], WorkDirectory[MAX_PATH],
|
||||||
|
SecurityBuf[512], RunAsBuf[64];
|
||||||
PWSTR CommandLine, Security;
|
PWSTR CommandLine, Security;
|
||||||
DWORD JobControl, Credentials;
|
DWORD JobControl, Credentials;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0, NewSecurityDescriptor;
|
||||||
PWSTR Argv[10];
|
PWSTR Argv[10];
|
||||||
PROCESS_INFORMATION ProcessInfo;
|
PROCESS_INFORMATION ProcessInfo;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -488,6 +906,16 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
CommandLine[-1] = L'\0';
|
CommandLine[-1] = L'\0';
|
||||||
CommandLine = CommandLineBuf;
|
CommandLine = CommandLineBuf;
|
||||||
|
|
||||||
|
RegSize = sizeof WorkDirectory;
|
||||||
|
WorkDirectory[0] = L'\0';
|
||||||
|
RegResult = RegGetValueW(RegKey, ClassName, L"WorkDirectory", RRF_RT_REG_SZ, 0,
|
||||||
|
WorkDirectory, &RegSize);
|
||||||
|
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(RegResult);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
Security = SecurityBuf + lstrlenW(SecurityBuf);
|
Security = SecurityBuf + lstrlenW(SecurityBuf);
|
||||||
RegSize = (DWORD)(sizeof SecurityBuf - (Security - SecurityBuf) * sizeof(WCHAR));
|
RegSize = (DWORD)(sizeof SecurityBuf - (Security - SecurityBuf) * sizeof(WCHAR));
|
||||||
RegResult = RegGetValueW(RegKey, ClassName, L"Security", RRF_RT_REG_SZ, 0,
|
RegResult = RegGetValueW(RegKey, ClassName, L"Security", RRF_RT_REG_SZ, 0,
|
||||||
@ -498,6 +926,16 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegSize = sizeof RunAsBuf;
|
||||||
|
RunAsBuf[0] = L'\0';
|
||||||
|
RegResult = RegGetValueW(RegKey, ClassName, L"RunAs", RRF_RT_REG_SZ, 0,
|
||||||
|
RunAsBuf, &RegSize);
|
||||||
|
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(RegResult);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
RegSize = sizeof JobControl;
|
RegSize = sizeof JobControl;
|
||||||
JobControl = 1; /* default is YES! */
|
JobControl = 1; /* default is YES! */
|
||||||
RegResult = RegGetValueW(RegKey, ClassName, L"JobControl", RRF_RT_REG_DWORD, 0,
|
RegResult = RegGetValueW(RegKey, ClassName, L"JobControl", RRF_RT_REG_DWORD, 0,
|
||||||
@ -529,6 +967,14 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
Result = SvcInstanceAddUserRights(ClientToken, SecurityDescriptor, &NewSecurityDescriptor);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
LocalFree(SecurityDescriptor);
|
||||||
|
SecurityDescriptor = NewSecurityDescriptor;
|
||||||
|
|
||||||
|
//FspDebugLogSD(__FUNCTION__ ": SDDL = %s\n", SecurityDescriptor);
|
||||||
|
|
||||||
ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR);
|
ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR);
|
||||||
InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR);
|
InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
@ -553,7 +999,8 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = SvcInstanceCreateProcess(Executable, SvcInstance->CommandLine,
|
Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0,
|
||||||
|
Executable, SvcInstance->CommandLine, L'\0' != WorkDirectory[0] ? WorkDirectory : 0,
|
||||||
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
|
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -624,6 +1071,9 @@ exit:
|
|||||||
|
|
||||||
LeaveCriticalSection(&SvcInstanceLock);
|
LeaveCriticalSection(&SvcInstanceLock);
|
||||||
|
|
||||||
|
FspServiceLog(EVENTLOG_INFORMATION_TYPE,
|
||||||
|
L"create %s\\%s = %lx", ClassName, InstanceName, Result);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,6 +1107,9 @@ static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout)
|
|||||||
{
|
{
|
||||||
SVC_INSTANCE *SvcInstance = Context;
|
SVC_INSTANCE *SvcInstance = Context;
|
||||||
|
|
||||||
|
FspServiceLog(EVENTLOG_INFORMATION_TYPE,
|
||||||
|
L"terminated %s\\%s", SvcInstance->ClassName, SvcInstance->InstanceName);
|
||||||
|
|
||||||
SvcInstanceRelease(SvcInstance);
|
SvcInstanceRelease(SvcInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,6 +1205,10 @@ exit:
|
|||||||
|
|
||||||
SvcInstanceRelease(SvcInstance);
|
SvcInstanceRelease(SvcInstance);
|
||||||
|
|
||||||
|
if (STATUS_TIMEOUT == Result)
|
||||||
|
/* convert to an error! */
|
||||||
|
Result = 0x80070000 | ERROR_TIMEOUT;
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,6 +1342,53 @@ NTSTATUS SvcInstanceStopAndWaitAll(VOID)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS SvcDefineDosDevice(HANDLE ClientToken,
|
||||||
|
PWSTR DeviceName, PWSTR TargetPath)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (L'+' != DeviceName[0] && L'-' != DeviceName[0])
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspServiceContextCheck(ClientToken, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (!DefineDosDeviceW(
|
||||||
|
DDD_RAW_TARGET_PATH |
|
||||||
|
(L'+' == DeviceName[0] ? 0 : DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE),
|
||||||
|
DeviceName + 1, TargetPath))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (L'+' == DeviceName[0] && 0 != SvcNtOpenSymbolicLinkObject)
|
||||||
|
{
|
||||||
|
/* The drive symlink now exists; add DELETE access to it for the ClientToken. */
|
||||||
|
WCHAR SymlinkBuf[6];
|
||||||
|
UNICODE_STRING Symlink;
|
||||||
|
OBJECT_ATTRIBUTES Obja;
|
||||||
|
HANDLE MountHandle;
|
||||||
|
|
||||||
|
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||||
|
SymlinkBuf[4] = DeviceName[1];
|
||||||
|
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||||
|
Symlink.Buffer = SymlinkBuf;
|
||||||
|
|
||||||
|
memset(&Obja, 0, sizeof Obja);
|
||||||
|
Obja.Length = sizeof Obja;
|
||||||
|
Obja.ObjectName = &Symlink;
|
||||||
|
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
Result = SvcNtOpenSymbolicLinkObject(&MountHandle, READ_CONTROL | WRITE_DAC, &Obja);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
AddAccessForTokenUser(MountHandle, DELETE, ClientToken);
|
||||||
|
SvcNtClose(MountHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static HANDLE SvcJob, SvcThread, SvcEvent;
|
static HANDLE SvcJob, SvcThread, SvcEvent;
|
||||||
static DWORD SvcThreadId;
|
static DWORD SvcThreadId;
|
||||||
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
||||||
@ -918,6 +1422,10 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
if (0 == SvcInstanceEvent)
|
if (0 == SvcInstanceEvent)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
SvcInstanceTlsKey = TlsAlloc();
|
||||||
|
if (TLS_OUT_OF_INDEXES == SvcInstanceTlsKey)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
SvcJob = CreateJobObjectW(0, 0);
|
SvcJob = CreateJobObjectW(0, 0);
|
||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
{
|
{
|
||||||
@ -980,6 +1488,9 @@ fail:
|
|||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
CloseHandle(SvcJob);
|
CloseHandle(SvcJob);
|
||||||
|
|
||||||
|
if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey)
|
||||||
|
TlsFree(SvcInstanceTlsKey);
|
||||||
|
|
||||||
if (0 != SvcInstanceEvent)
|
if (0 != SvcInstanceEvent)
|
||||||
CloseHandle(SvcInstanceEvent);
|
CloseHandle(SvcInstanceEvent);
|
||||||
|
|
||||||
@ -1023,6 +1534,9 @@ static NTSTATUS SvcStop(FSP_SERVICE *Service)
|
|||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
CloseHandle(SvcJob);
|
CloseHandle(SvcJob);
|
||||||
|
|
||||||
|
if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey)
|
||||||
|
TlsFree(SvcInstanceTlsKey);
|
||||||
|
|
||||||
if (0 != SvcInstanceEvent)
|
if (0 != SvcInstanceEvent)
|
||||||
CloseHandle(SvcInstanceEvent);
|
CloseHandle(SvcInstanceEvent);
|
||||||
|
|
||||||
@ -1194,13 +1708,17 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
||||||
PWSTR ClassName, InstanceName;
|
PWSTR ClassName, InstanceName, UserName;
|
||||||
|
PWSTR DeviceName, TargetPath;
|
||||||
ULONG Argc; PWSTR Argv[9];
|
ULONG Argc; PWSTR Argv[9];
|
||||||
BOOLEAN HasSecret = FALSE;
|
BOOLEAN HasSecret = FALSE;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
*PSize = 0;
|
*PSize = 0;
|
||||||
|
|
||||||
|
GetTokenUserName(ClientToken, &UserName);
|
||||||
|
SvcInstanceSetUserName(UserName);
|
||||||
|
|
||||||
switch (*P++)
|
switch (*P++)
|
||||||
{
|
{
|
||||||
case LauncherSvcInstanceStartWithSecret:
|
case LauncherSvcInstanceStartWithSecret:
|
||||||
@ -1253,6 +1771,17 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LauncherDefineDosDevice:
|
||||||
|
DeviceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
TargetPath = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
if (0 != DeviceName && 0 != TargetPath)
|
||||||
|
Result = SvcDefineDosDevice(ClientToken, DeviceName, TargetPath);
|
||||||
|
|
||||||
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
|
break;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
case LauncherQuit:
|
case LauncherQuit:
|
||||||
SetEvent(SvcEvent);
|
SetEvent(SvcEvent);
|
||||||
@ -1264,10 +1793,26 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
SvcPipeTransactResult(STATUS_INVALID_PARAMETER, PipeBuf, PSize);
|
SvcPipeTransactResult(STATUS_INVALID_PARAMETER, PipeBuf, PSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SvcInstanceSetUserName(0);
|
||||||
|
MemFree(UserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
|
HANDLE Handle = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
if (0 != Handle)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
|
||||||
|
SvcNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
|
||||||
|
|
||||||
|
if (0 == SvcNtOpenSymbolicLinkObject || 0 == SvcNtClose)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = 0;
|
||||||
|
SvcNtClose = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launcher.h
|
* @file launcher/launcher.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
||||||
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
||||||
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT 3000
|
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT (2 * 15000 + 1000)
|
||||||
|
|
||||||
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ enum
|
|||||||
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
||||||
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
||||||
LauncherSvcInstanceList = 'L', /* requires: none*/
|
LauncherSvcInstanceList = 'L', /* requires: none*/
|
||||||
|
LauncherDefineDosDevice = 'D',
|
||||||
LauncherQuit = 'Q', /* DEBUG version only */
|
LauncherQuit = 'Q', /* DEBUG version only */
|
||||||
|
|
||||||
LauncherSuccess = '$',
|
LauncherSuccess = '$',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/minimal.h
|
* @file shared/minimal.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file sys/callbacks.c
|
* @file sys/callbacks.c
|
||||||
* Fast I/O and resource acquisition callbacks.
|
* Fast I/O and resource acquisition callbacks.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/cleanup.c
|
* @file sys/cleanup.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/close.c
|
* @file sys/close.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/create.c
|
* @file sys/create.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -545,6 +545,7 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
||||||
HANDLE UserModeAccessToken;
|
HANDLE UserModeAccessToken;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
|
ULONG OriginatingProcessId;
|
||||||
FSP_FILE_NODE *FileNode;
|
FSP_FILE_NODE *FileNode;
|
||||||
FSP_FILE_DESC *FileDesc;
|
FSP_FILE_DESC *FileDesc;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
@ -579,10 +580,16 @@ NTSTATUS FspFsvolCreatePrepare(
|
|||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
ObReferenceObject(Process);
|
ObReferenceObject(Process);
|
||||||
|
|
||||||
|
/* get the originating process ID stored in the IRP */
|
||||||
|
OriginatingProcessId = IoGetRequestorProcessId(Irp);
|
||||||
|
|
||||||
/* send the user-mode handle to the user-mode file system */
|
/* send the user-mode handle to the user-mode file system */
|
||||||
FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken;
|
FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken;
|
||||||
FspIopRequestContext(Request, RequestProcess) = Process;
|
FspIopRequestContext(Request, RequestProcess) = Process;
|
||||||
Request->Req.Create.AccessToken = (UINT_PTR)UserModeAccessToken;
|
ASSERT((UINT64)(UINT_PTR)UserModeAccessToken <= 0xffffffffULL);
|
||||||
|
ASSERT((UINT64)(UINT_PTR)OriginatingProcessId <= 0xffffffffULL);
|
||||||
|
Request->Req.Create.AccessToken =
|
||||||
|
((UINT64)(UINT_PTR)OriginatingProcessId << 32) | (UINT64)(UINT_PTR)UserModeAccessToken;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/debug.c
|
* @file sys/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/devctl.c
|
* @file sys/devctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/device.c
|
* @file sys/device.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
679
src/sys/dirctl.c
679
src/sys/dirctl.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/dirctl.c
|
* @file sys/dirctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -17,15 +17,6 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE:
|
|
||||||
*
|
|
||||||
* FspIopCompleteIrpEx does some special processing for IRP_MJ_DIRECTORY_CONTROL /
|
|
||||||
* IRP_MN_QUERY_DIRECTORY IRP's that come from SRV2. If the processing of this IRP
|
|
||||||
* changes substantially (in particular if we eliminate our use of
|
|
||||||
* Irp->AssociatedIrp.SystemBuffer) we should also revisit FspIopCompleteIrpEx.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||||
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut,
|
||||||
@ -77,19 +68,17 @@ FSP_DRIVER_DISPATCH FspDirectoryControl;
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* QueryDirectory */
|
/* QueryDirectory */
|
||||||
RequestIrp = 0,
|
RequestFileNode = 0,
|
||||||
RequestCookie = 1,
|
RequestCookie = 1,
|
||||||
RequestMdl = 1,
|
|
||||||
RequestAddress = 2,
|
RequestAddress = 2,
|
||||||
RequestProcess = 3,
|
RequestProcess = 3,
|
||||||
|
|
||||||
/* QueryDirectoryRetry */
|
|
||||||
RequestSystemBufferLength = 0,
|
|
||||||
|
|
||||||
/* DirectoryControlComplete retry */
|
|
||||||
RequestDirInfoChangeNumber = 0,
|
|
||||||
};
|
};
|
||||||
FSP_FSCTL_STATIC_ASSERT(RequestCookie == RequestMdl, "");
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FspFsvolQueryDirectoryLengthMax =
|
||||||
|
FspFsvolDeviceDirInfoCacheItemSizeMax - FspMetaCacheItemHeaderSize,
|
||||||
|
};
|
||||||
|
|
||||||
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
static NTSTATUS FspFsvolQueryDirectoryCopy(
|
||||||
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive,
|
||||||
@ -362,7 +351,6 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
|||||||
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
PUNICODE_STRING DirectoryPattern = &FileDesc->DirectoryPattern;
|
||||||
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
UNICODE_STRING DirectoryMarker = FileDesc->DirectoryMarker;
|
||||||
|
|
||||||
ASSERT(DirInfo == DestBuf);
|
|
||||||
FSP_FSCTL_STATIC_ASSERT(
|
FSP_FSCTL_STATIC_ASSERT(
|
||||||
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >=
|
FIELD_OFFSET(FSP_FSCTL_DIR_INFO, FileNameBuf) >=
|
||||||
FIELD_OFFSET(FILE_ID_BOTH_DIR_INFORMATION, FileName),
|
FIELD_OFFSET(FILE_ID_BOTH_DIR_INFORMATION, FileName),
|
||||||
@ -389,77 +377,10 @@ static NTSTATUS FspFsvolQueryDirectoryCopyInPlace(
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline NTSTATUS FspFsvolQueryDirectoryBufferUserBuffer(
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension, PIRP Irp, PULONG PLength)
|
|
||||||
{
|
|
||||||
if (0 != Irp->AssociatedIrp.SystemBuffer)
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
ULONG Length = *PLength;
|
|
||||||
|
|
||||||
if (Length > FspFsvolDeviceDirInfoCacheItemSizeMax)
|
|
||||||
Length = FspFsvolDeviceDirInfoCacheItemSizeMax;
|
|
||||||
else if (Length < sizeof(FSP_FSCTL_DIR_INFO) +
|
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR))
|
|
||||||
Length = sizeof(FSP_FSCTL_DIR_INFO) +
|
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR);
|
|
||||||
|
|
||||||
Result = FspBufferUserBuffer(Irp, FSP_FSCTL_ALIGN_UP(Length, PAGE_SIZE), IoWriteAccess);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
*PLength = Length;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolQueryDirectoryRetry(
|
static NTSTATUS FspFsvolQueryDirectoryRetry(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||||
BOOLEAN CanWait)
|
BOOLEAN CanWait)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* The SystemBufferLength contains the length of the SystemBuffer that we
|
|
||||||
* are going to allocate (in FspFsvolQueryDirectoryBufferUserBuffer). This
|
|
||||||
* buffer is going to be used as the IRP SystemBuffer and it will also be
|
|
||||||
* mapped into the user mode file system process (in
|
|
||||||
* FspFsvolDirectoryControlPrepare) so that the file system can fill in the
|
|
||||||
* buffer.
|
|
||||||
*
|
|
||||||
* The SystemBufferLength is not the actual length that we are going to use
|
|
||||||
* when completing the IRP. This will be computed at IRP completion time
|
|
||||||
* (using FspFsvolQueryDirectoryCopy). Instead the SystemBufferLength is
|
|
||||||
* the size that we want the user mode file system to see and it may be
|
|
||||||
* different from the requested length for the following reasons:
|
|
||||||
*
|
|
||||||
* - If the FileInfoTimeout is non-zero, then the directory maintains a
|
|
||||||
* DirInfo meta cache that can be used to fulfill IRP requests without
|
|
||||||
* reaching out to user mode. In this case we want the SystemBufferLength
|
|
||||||
* to be FspFsvolDeviceDirInfoCacheItemSizeMax so that we read up to the
|
|
||||||
* cache size maximum.
|
|
||||||
*
|
|
||||||
* - If the requested DirectoryPattern (stored in FileDesc) is not the "*"
|
|
||||||
* (MatchAll) pattern, then we want to read as many entries as possible
|
|
||||||
* from the user mode file system to avoid multiple roundtrips to user
|
|
||||||
* mode when doing file name matching. In this case we set again the
|
|
||||||
* SystemBufferLength to be FspFsvolDeviceDirInfoCacheItemSizeMax. This
|
|
||||||
* is an important optimization and without it QueryDirectory is *very*
|
|
||||||
* slow without the DirInfo meta cache (i.e. when FileInfoTimeout is 0).
|
|
||||||
*
|
|
||||||
* - If the requsted DirectoryPattern is the MatchAll pattern then we set
|
|
||||||
* the SystemBufferLength to the requested (IRP) length as it is actually
|
|
||||||
* counter-productive to try to read more than we need.
|
|
||||||
*/
|
|
||||||
#define GetSystemBufferLengthMaybeCached()\
|
|
||||||
(0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && 0 == FileDesc->DirectoryMarker.Buffer) ||\
|
|
||||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?\
|
|
||||||
FspFsvolDeviceDirInfoCacheItemSizeMax : Length
|
|
||||||
#define GetSystemBufferLengthNonCached()\
|
|
||||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?\
|
|
||||||
FspFsvolDeviceDirInfoCacheItemSizeMax : Length
|
|
||||||
#define GetSystemBufferLengthBestGuess()\
|
|
||||||
FspFsvolDeviceDirInfoCacheItemSizeMax
|
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -471,193 +392,23 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
|||||||
BOOLEAN IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
|
BOOLEAN IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
|
||||||
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
|
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
||||||
|
ULONG BaseInfoLen;
|
||||||
PUNICODE_STRING FileName = IrpSp->Parameters.QueryDirectory.FileName;
|
PUNICODE_STRING FileName = IrpSp->Parameters.QueryDirectory.FileName;
|
||||||
//ULONG FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;
|
//ULONG FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;
|
||||||
PVOID Buffer = 0 != Irp->AssociatedIrp.SystemBuffer ?
|
PVOID Buffer = 0 == Irp->MdlAddress ?
|
||||||
Irp->AssociatedIrp.SystemBuffer : Irp->UserBuffer;
|
Irp->UserBuffer : MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||||
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
||||||
ULONG SystemBufferLength;
|
ULONG QueryDirectoryLength, QueryDirectoryLengthMin;
|
||||||
PVOID DirInfoBuffer;
|
PVOID DirInfoBuffer;
|
||||||
ULONG DirInfoSize;
|
ULONG DirInfoSize;
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
BOOLEAN PassQueryDirectoryPattern, PatternIsFileName;
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
|
|
||||||
ASSERT(FileNode == FileDesc->FileNode);
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
SystemBufferLength = 0 != Request ?
|
if (0 == Buffer)
|
||||||
(ULONG)(UINT_PTR)FspIopRequestContext(Request, RequestSystemBufferLength) : 0;
|
return 0 == Irp->MdlAddress ? STATUS_INVALID_PARAMETER : STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* try to acquire the FileNode exclusive; Full because we may need to send a Request */
|
|
||||||
Success = DEBUGTEST(90) &&
|
|
||||||
FspFileNodeTryAcquireExclusiveF(FileNode, FspFileNodeAcquireFull, CanWait);
|
|
||||||
if (!Success)
|
|
||||||
{
|
|
||||||
if (0 == SystemBufferLength)
|
|
||||||
SystemBufferLength = GetSystemBufferLengthBestGuess();
|
|
||||||
|
|
||||||
Result = FspFsvolQueryDirectoryBufferUserBuffer(
|
|
||||||
FsvolDeviceExtension, Irp, &SystemBufferLength);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
Result = FspWqCreateIrpWorkItem(Irp, FspFsvolQueryDirectoryRetry, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
Request = FspIrpRequest(Irp);
|
|
||||||
FspIopRequestContext(Request, RequestSystemBufferLength) =
|
|
||||||
(PVOID)(UINT_PTR)SystemBufferLength;
|
|
||||||
|
|
||||||
FspWqPostIrpWorkItem(Irp);
|
|
||||||
|
|
||||||
return STATUS_PENDING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we have been retried reset our work item now! */
|
|
||||||
if (0 != Request)
|
|
||||||
{
|
|
||||||
FspIrpDeleteRequest(Irp);
|
|
||||||
Request = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset the FileDesc */
|
|
||||||
Result = FspFileDescResetDirectory(FileDesc, FileName, RestartScan, IndexSpecified);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* see if the required information is still in the cache and valid! */
|
|
||||||
if (FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
|
||||||
{
|
|
||||||
if (0 == SystemBufferLength)
|
|
||||||
SystemBufferLength = GetSystemBufferLengthNonCached();
|
|
||||||
|
|
||||||
Result = FspFsvolQueryDirectoryCopyCache(FileDesc,
|
|
||||||
IndexSpecified || RestartScan,
|
|
||||||
FileInformationClass, ReturnSingleEntry,
|
|
||||||
DirInfoBuffer, DirInfoSize, Buffer, &Length);
|
|
||||||
|
|
||||||
FspFileNodeDereferenceDirInfo(DirInfoBuffer);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result) || 0 != Length)
|
|
||||||
{
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
|
||||||
Irp->IoStatus.Information = Length;
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 == SystemBufferLength)
|
|
||||||
SystemBufferLength = GetSystemBufferLengthMaybeCached();
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFileNodeConvertExclusiveToShared(FileNode, Full);
|
|
||||||
|
|
||||||
/* buffer the user buffer! */
|
|
||||||
Result = FspFsvolQueryDirectoryBufferUserBuffer(
|
|
||||||
FsvolDeviceExtension, Irp, &SystemBufferLength);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create request */
|
|
||||||
Result = FspIopCreateRequestEx(Irp, 0,
|
|
||||||
(FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern &&
|
|
||||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer ?
|
|
||||||
FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0) +
|
|
||||||
(FsvolDeviceExtension->VolumeParams.MaxComponentLength + 1) * sizeof(WCHAR),
|
|
||||||
FspFsvolQueryDirectoryRequestFini, &Request);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Request->Kind = FspFsctlTransactQueryDirectoryKind;
|
|
||||||
Request->Req.QueryDirectory.UserContext = FileNode->UserContext;
|
|
||||||
Request->Req.QueryDirectory.UserContext2 = FileDesc->UserContext2;
|
|
||||||
Request->Req.QueryDirectory.Length = SystemBufferLength;
|
|
||||||
Request->Req.QueryDirectory.CaseSensitive = FileDesc->CaseSensitive;
|
|
||||||
|
|
||||||
if (FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern &&
|
|
||||||
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer)
|
|
||||||
{
|
|
||||||
Request->Req.QueryDirectory.Pattern.Offset =
|
|
||||||
Request->FileName.Size;
|
|
||||||
Request->Req.QueryDirectory.Pattern.Size =
|
|
||||||
FileDesc->DirectoryPattern.Length + sizeof(WCHAR);
|
|
||||||
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset,
|
|
||||||
FileDesc->DirectoryPattern.Buffer, FileDesc->DirectoryPattern.Length);
|
|
||||||
*(PWSTR)(Request->Buffer +
|
|
||||||
Request->Req.QueryDirectory.Pattern.Offset +
|
|
||||||
FileDesc->DirectoryPattern.Length) = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
|
||||||
{
|
|
||||||
ASSERT(
|
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
|
||||||
FileDesc->DirectoryMarker.Length);
|
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Marker.Offset =
|
|
||||||
Request->FileName.Size + Request->Req.QueryDirectory.Pattern.Size;
|
|
||||||
Request->Req.QueryDirectory.Marker.Size =
|
|
||||||
FileDesc->DirectoryMarker.Length + sizeof(WCHAR);
|
|
||||||
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset,
|
|
||||||
FileDesc->DirectoryMarker.Buffer, FileDesc->DirectoryMarker.Length);
|
|
||||||
*(PWSTR)(Request->Buffer +
|
|
||||||
Request->Req.QueryDirectory.Marker.Offset +
|
|
||||||
FileDesc->DirectoryMarker.Length) = L'\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
|
||||||
|
|
||||||
return FSP_STATUS_IOQ_POST;
|
|
||||||
|
|
||||||
#undef GetSystemBufferLengthBestGuess
|
|
||||||
#undef GetSystemBufferLengthNonCached
|
|
||||||
#undef GetSystemBufferLengthMaybeCached
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspFsvolQueryDirectory(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* is this a valid FileObject? */
|
|
||||||
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
|
||||||
PUNICODE_STRING FileName = IrpSp->Parameters.QueryDirectory.FileName;
|
|
||||||
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
|
||||||
ULONG BaseInfoLen;
|
|
||||||
|
|
||||||
/* SystemBuffer must be NULL as we are going to be using it! */
|
|
||||||
if (0 != Irp->AssociatedIrp.SystemBuffer)
|
|
||||||
{
|
|
||||||
ASSERT(0);
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only directory files can be queried */
|
|
||||||
if (!FileNode->IsDirectory)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* check that FileName is valid (if supplied) */
|
|
||||||
if (0 != FileName &&
|
|
||||||
!FspFileNameIsValidPattern(FileName, FsvolDeviceExtension->VolumeParams.MaxComponentLength))
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* is this an allowed file information class? */
|
/* is this an allowed file information class? */
|
||||||
switch (FileInformationClass)
|
switch (FileInformationClass)
|
||||||
@ -683,12 +434,227 @@ static NTSTATUS FspFsvolQueryDirectory(
|
|||||||
default:
|
default:
|
||||||
return STATUS_INVALID_INFO_CLASS;
|
return STATUS_INVALID_INFO_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BaseInfoLen >= Length)
|
if (BaseInfoLen >= Length)
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
Result = FspFsvolQueryDirectoryRetry(FsvolDeviceObject, Irp, IrpSp, IoIsOperationSynchronous(Irp));
|
/* try to acquire the FileNode exclusive; Full because we may need to send a Request */
|
||||||
|
Success = DEBUGTEST(90) &&
|
||||||
|
FspFileNodeTryAcquireExclusiveF(FileNode, FspFileNodeAcquireFull, CanWait);
|
||||||
|
if (!Success)
|
||||||
|
return FspWqRepostIrpWorkItem(Irp, FspFsvolQueryDirectoryRetry, 0);
|
||||||
|
|
||||||
return Result;
|
/* if we have been retried reset our work item now! */
|
||||||
|
if (0 != Request)
|
||||||
|
{
|
||||||
|
FspIrpDeleteRequest(Irp);
|
||||||
|
Request = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset the FileDesc */
|
||||||
|
Result = FspFileDescResetDirectory(FileDesc, FileName, RestartScan, IndexSpecified);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if the required information is still in the cache and valid! */
|
||||||
|
if (FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
||||||
|
{
|
||||||
|
Result = FspFsvolQueryDirectoryCopyCache(FileDesc,
|
||||||
|
IndexSpecified || RestartScan,
|
||||||
|
FileInformationClass, ReturnSingleEntry,
|
||||||
|
DirInfoBuffer, DirInfoSize, Buffer, &Length);
|
||||||
|
|
||||||
|
FspFileNodeDereferenceDirInfo(DirInfoBuffer);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result) || 0 != Length)
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
Irp->IoStatus.Information = Length;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset Length! */
|
||||||
|
Length = IrpSp->Parameters.QueryDirectory.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFileNodeConvertExclusiveToShared(FileNode, Full);
|
||||||
|
|
||||||
|
/* special handling when pattern is filename */
|
||||||
|
PatternIsFileName = FsvolDeviceExtension->VolumeParams.PassQueryDirectoryFileName &&
|
||||||
|
!FsRtlDoesNameContainWildCards(&FileDesc->DirectoryPattern);
|
||||||
|
PassQueryDirectoryPattern = PatternIsFileName ||
|
||||||
|
(FsvolDeviceExtension->VolumeParams.PassQueryDirectoryPattern &&
|
||||||
|
FspFileDescDirectoryPatternMatchAll != FileDesc->DirectoryPattern.Buffer);
|
||||||
|
if (PatternIsFileName &&
|
||||||
|
0 != FileDesc->DirectoryMarker.Buffer &&
|
||||||
|
0 == FspFileNameCompare(&FileDesc->DirectoryPattern, &FileDesc->DirectoryMarker,
|
||||||
|
!FileDesc->CaseSensitive, 0))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return !FileDesc->DirectoryHasSuchFile ?
|
||||||
|
STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* probe and lock the user buffer */
|
||||||
|
Result = FspLockUserBuffer(Irp, Length, IoWriteAccess);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create request */
|
||||||
|
Result = FspIopCreateRequestEx(Irp, 0,
|
||||||
|
(PassQueryDirectoryPattern ? FileDesc->DirectoryPattern.Length + sizeof(WCHAR) : 0) +
|
||||||
|
(FsvolDeviceExtension->VolumeParams.MaxComponentLength + 1) * sizeof(WCHAR),
|
||||||
|
FspFsvolQueryDirectoryRequestFini, &Request);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFileNodeRelease(FileNode, Full);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute QueryDirectoryLength
|
||||||
|
*
|
||||||
|
* How much data to request from the file system varies according to the following matrix:
|
||||||
|
*
|
||||||
|
* Pattern | NoCache | Cache+1st | Cache+2nd
|
||||||
|
* -------------------------+---------+-----------+----------
|
||||||
|
* Full Wild | Ratio | Maximum | Ratio
|
||||||
|
* Partial Wild w/o PassQDP | Maximum | Maximum | Maximum
|
||||||
|
* Partial Wild w/ PassQDP | Ratio | Ratio | Ratio
|
||||||
|
* File Name w/o PassQDF | Maximum | Maximum | Maximum
|
||||||
|
* File Name w/ PassQDF | Minimum | Minimum | Minimum
|
||||||
|
*
|
||||||
|
* NoCache means DirInfo caching disabled. Cache+1st means DirInfo caching enabled, but
|
||||||
|
* cache not primed. Cache+2nd means DirInfo caching enabled, cache is primed, but missed.
|
||||||
|
* [If there is no cache miss, there is no need to send the request to the file system.]
|
||||||
|
*
|
||||||
|
* Maximum means to request the maximum size allowed by the FSD. Minimum means the size that
|
||||||
|
* is guaranteed to contain at least one entry. Ratio means to compute how many directory
|
||||||
|
* entries to request from the file system based on an estimate of how many entries the FSD
|
||||||
|
* is supposed to deliver.
|
||||||
|
*
|
||||||
|
* The Ratio computation is as follows: Assume that N is the size of the average file name,
|
||||||
|
* taken to be 24 * sizeof(WCHAR). Let M be the number of entries that can fit in the passed
|
||||||
|
* buffer:
|
||||||
|
*
|
||||||
|
* M := Length / (BaseInfoLen + N) = QueryDirectoryLength / (sizeof(FSP_FSCTL_DIR_INFO) + N)
|
||||||
|
* => QueryDirectoryLength = Length * (sizeof(FSP_FSCTL_DIR_INFO) + N) / (BaseInfoLen + N)
|
||||||
|
*/
|
||||||
|
|
||||||
|
QueryDirectoryLengthMin = sizeof(FSP_FSCTL_DIR_INFO) +
|
||||||
|
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR);
|
||||||
|
QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8);
|
||||||
|
ASSERT(QueryDirectoryLengthMin < FspFsvolQueryDirectoryLengthMax);
|
||||||
|
if (0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout &&
|
||||||
|
0 == FileDesc->DirectoryMarker.Buffer)
|
||||||
|
{
|
||||||
|
if (PatternIsFileName)
|
||||||
|
QueryDirectoryLength = QueryDirectoryLengthMin;
|
||||||
|
else if (PassQueryDirectoryPattern)
|
||||||
|
{
|
||||||
|
QueryDirectoryLength = Length *
|
||||||
|
(sizeof(FSP_FSCTL_DIR_INFO) + 24 * sizeof(WCHAR)) / (BaseInfoLen + 24 * sizeof(WCHAR));
|
||||||
|
QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8);
|
||||||
|
if (QueryDirectoryLength < QueryDirectoryLengthMin)
|
||||||
|
QueryDirectoryLength = QueryDirectoryLengthMin;
|
||||||
|
else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax)
|
||||||
|
QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PatternIsFileName)
|
||||||
|
QueryDirectoryLength = QueryDirectoryLengthMin;
|
||||||
|
else if (PassQueryDirectoryPattern ||
|
||||||
|
FspFileDescDirectoryPatternMatchAll == FileDesc->DirectoryPattern.Buffer)
|
||||||
|
{
|
||||||
|
QueryDirectoryLength = Length *
|
||||||
|
(sizeof(FSP_FSCTL_DIR_INFO) + 24 * sizeof(WCHAR)) / (BaseInfoLen + 24 * sizeof(WCHAR));
|
||||||
|
QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8);
|
||||||
|
if (QueryDirectoryLength < QueryDirectoryLengthMin)
|
||||||
|
QueryDirectoryLength = QueryDirectoryLengthMin;
|
||||||
|
else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax)
|
||||||
|
QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request->Kind = FspFsctlTransactQueryDirectoryKind;
|
||||||
|
Request->Req.QueryDirectory.UserContext = FileNode->UserContext;
|
||||||
|
Request->Req.QueryDirectory.UserContext2 = FileDesc->UserContext2;
|
||||||
|
Request->Req.QueryDirectory.Length = QueryDirectoryLength;
|
||||||
|
Request->Req.QueryDirectory.CaseSensitive = FileDesc->CaseSensitive;
|
||||||
|
|
||||||
|
if (PassQueryDirectoryPattern)
|
||||||
|
{
|
||||||
|
Request->Req.QueryDirectory.PatternIsFileName = PatternIsFileName;
|
||||||
|
Request->Req.QueryDirectory.Pattern.Offset =
|
||||||
|
Request->FileName.Size;
|
||||||
|
Request->Req.QueryDirectory.Pattern.Size =
|
||||||
|
FileDesc->DirectoryPattern.Length + sizeof(WCHAR);
|
||||||
|
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Pattern.Offset,
|
||||||
|
FileDesc->DirectoryPattern.Buffer, FileDesc->DirectoryPattern.Length);
|
||||||
|
*(PWSTR)(Request->Buffer +
|
||||||
|
Request->Req.QueryDirectory.Pattern.Offset +
|
||||||
|
FileDesc->DirectoryPattern.Length) = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||||
|
{
|
||||||
|
ASSERT(
|
||||||
|
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
|
||||||
|
FileDesc->DirectoryMarker.Length);
|
||||||
|
|
||||||
|
Request->Req.QueryDirectory.Marker.Offset =
|
||||||
|
Request->FileName.Size + Request->Req.QueryDirectory.Pattern.Size;
|
||||||
|
Request->Req.QueryDirectory.Marker.Size =
|
||||||
|
FileDesc->DirectoryMarker.Length + sizeof(WCHAR);
|
||||||
|
RtlCopyMemory(Request->Buffer + Request->Req.QueryDirectory.Marker.Offset,
|
||||||
|
FileDesc->DirectoryMarker.Buffer, FileDesc->DirectoryMarker.Length);
|
||||||
|
*(PWSTR)(Request->Buffer +
|
||||||
|
Request->Req.QueryDirectory.Marker.Offset +
|
||||||
|
FileDesc->DirectoryMarker.Length) = L'\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
|
|
||||||
|
return FSP_STATUS_IOQ_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolQueryDirectory(
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* is this a valid FileObject? */
|
||||||
|
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
PUNICODE_STRING FileName = IrpSp->Parameters.QueryDirectory.FileName;
|
||||||
|
|
||||||
|
/* only directory files can be queried */
|
||||||
|
if (!FileNode->IsDirectory)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* check that FileName is valid (if supplied) */
|
||||||
|
if (0 != FileName &&
|
||||||
|
!FspFileNameIsValidPattern(FileName, FsvolDeviceExtension->VolumeParams.MaxComponentLength))
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return FspFsvolQueryDirectoryRetry(FsvolDeviceObject, Irp, IrpSp, IoIsOperationSynchronous(Irp));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -835,67 +801,26 @@ NTSTATUS FspFsvolDirectoryControlPrepare(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
if (FspQueryDirectoryIrpShouldUseProcessBuffer(Irp, Request->Req.QueryDirectory.Length))
|
NTSTATUS Result;
|
||||||
{
|
PVOID Cookie;
|
||||||
NTSTATUS Result;
|
PVOID Address;
|
||||||
PVOID Cookie;
|
PEPROCESS Process;
|
||||||
PVOID Address;
|
|
||||||
PEPROCESS Process;
|
|
||||||
|
|
||||||
Result = FspProcessBufferAcquire(Request->Req.QueryDirectory.Length, &Cookie, &Address);
|
Result = FspProcessBufferAcquire(Request->Req.QueryDirectory.Length, &Cookie, &Address);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
/* get a pointer to the current process so that we can release the buffer later */
|
/* get a pointer to the current process so that we can release the buffer later */
|
||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
ObReferenceObject(Process);
|
ObReferenceObject(Process);
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Address = (UINT64)(UINT_PTR)Address;
|
Request->Req.QueryDirectory.Address = (UINT64)(UINT_PTR)Address;
|
||||||
|
|
||||||
FspIopRequestContext(Request, RequestCookie) = (PVOID)((UINT_PTR)Cookie | 1);
|
FspIopRequestContext(Request, RequestCookie) = (PVOID)((UINT_PTR)Cookie | 1);
|
||||||
FspIopRequestContext(Request, RequestAddress) = Address;
|
FspIopRequestContext(Request, RequestAddress) = Address;
|
||||||
FspIopRequestContext(Request, RequestProcess) = Process;
|
FspIopRequestContext(Request, RequestProcess) = Process;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NTSTATUS Result;
|
|
||||||
PMDL Mdl = 0;
|
|
||||||
PVOID Address;
|
|
||||||
PEPROCESS Process;
|
|
||||||
|
|
||||||
Mdl = IoAllocateMdl(
|
|
||||||
Irp->AssociatedIrp.SystemBuffer,
|
|
||||||
Request->Req.QueryDirectory.Length,
|
|
||||||
FALSE, FALSE, 0);
|
|
||||||
if (0 == Mdl)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
MmBuildMdlForNonPagedPool(Mdl);
|
|
||||||
|
|
||||||
/* map the MDL into user-mode */
|
|
||||||
Result = FspMapLockedPagesInUserMode(Mdl, &Address, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
if (0 != Mdl)
|
|
||||||
IoFreeMdl(Mdl);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get a pointer to the current process so that we can unmap the address later */
|
|
||||||
Process = PsGetCurrentProcess();
|
|
||||||
ObReferenceObject(Process);
|
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Address = (UINT64)(UINT_PTR)Address;
|
|
||||||
|
|
||||||
FspIopRequestContext(Request, RequestMdl) = Mdl;
|
|
||||||
FspIopRequestContext(Request, RequestAddress) = Address;
|
|
||||||
FspIopRequestContext(Request, RequestProcess) = Process;
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolDirectoryControlComplete(
|
NTSTATUS FspFsvolDirectoryControlComplete(
|
||||||
@ -920,9 +845,8 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
|
BOOLEAN ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
|
||||||
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
PVOID Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
||||||
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
ULONG Length = IrpSp->Parameters.QueryDirectory.Length;
|
||||||
ULONG DirInfoChangeNumber;
|
|
||||||
PVOID DirInfoBuffer;
|
PVOID DirInfoBuffer;
|
||||||
ULONG DirInfoSize;
|
ULONG DirInfoSize;
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
@ -936,33 +860,14 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
FSP_RETURN();
|
FSP_RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FspFsctlTransactQueryDirectoryKind == Request->Kind)
|
if (0 != FspIopRequestContext(Request, RequestFileNode))
|
||||||
{
|
{
|
||||||
if ((UINT_PTR)FspIopRequestContext(Request, RequestCookie) & 1)
|
FspIopRequestContext(Request, FspIopRequestExtraContext) = (PVOID)
|
||||||
{
|
FspFileNodeDirInfoChangeNumber(FileNode);
|
||||||
PVOID Address = FspIopRequestContext(Request, RequestAddress);
|
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||||
|
|
||||||
ASSERT(0 != Address);
|
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||||
try
|
|
||||||
{
|
|
||||||
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Address, Response->IoStatus.Information);
|
|
||||||
}
|
|
||||||
except (EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
Result = GetExceptionCode();
|
|
||||||
Result = FsRtlIsNtstatusExpected(Result) ? STATUS_INVALID_USER_BUFFER : Result;
|
|
||||||
FSP_RETURN();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DirInfoChangeNumber = FspFileNodeDirInfoChangeNumber(FileNode);
|
|
||||||
Request->Kind = FspFsctlTransactReservedKind;
|
|
||||||
FspIopResetRequest(Request, 0);
|
|
||||||
FspIopRequestContext(Request, RequestDirInfoChangeNumber) = (PVOID)DirInfoChangeNumber;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
DirInfoChangeNumber =
|
|
||||||
(ULONG)(UINT_PTR)FspIopRequestContext(Request, RequestDirInfoChangeNumber);
|
|
||||||
|
|
||||||
/* acquire FileNode exclusive Full (because we may need to go back to user-mode) */
|
/* acquire FileNode exclusive Full (because we may need to go back to user-mode) */
|
||||||
Success = DEBUGTEST(90) && FspFileNodeTryAcquireExclusive(FileNode, Full);
|
Success = DEBUGTEST(90) && FspFileNodeTryAcquireExclusive(FileNode, Full);
|
||||||
@ -975,9 +880,9 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
if (0 == Request->Req.QueryDirectory.Pattern.Size &&
|
if (0 == Request->Req.QueryDirectory.Pattern.Size &&
|
||||||
0 == Request->Req.QueryDirectory.Marker.Size &&
|
0 == Request->Req.QueryDirectory.Marker.Size &&
|
||||||
FspFileNodeTrySetDirInfo(FileNode,
|
FspFileNodeTrySetDirInfo(FileNode,
|
||||||
Irp->AssociatedIrp.SystemBuffer,
|
(PVOID)(UINT_PTR)Request->Req.QueryDirectory.Address,
|
||||||
(ULONG)Response->IoStatus.Information,
|
(ULONG)Response->IoStatus.Information,
|
||||||
DirInfoChangeNumber) &&
|
(ULONG)(UINT_PTR)FspIopRequestContext(Request, FspIopRequestExtraContext)) &&
|
||||||
FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
FspFileNodeReferenceDirInfo(FileNode, &DirInfoBuffer, &DirInfoSize))
|
||||||
{
|
{
|
||||||
Result = FspFsvolQueryDirectoryCopyCache(FileDesc,
|
Result = FspFsvolQueryDirectoryCopyCache(FileDesc,
|
||||||
@ -989,7 +894,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DirInfoBuffer = Irp->AssociatedIrp.SystemBuffer;
|
DirInfoBuffer = (PVOID)(UINT_PTR)Request->Req.QueryDirectory.Address;
|
||||||
DirInfoSize = (ULONG)Response->IoStatus.Information;
|
DirInfoSize = (ULONG)Response->IoStatus.Information;
|
||||||
Result = FspFsvolQueryDirectoryCopyInPlace(FileDesc,
|
Result = FspFsvolQueryDirectoryCopyInPlace(FileDesc,
|
||||||
FileInformationClass, ReturnSingleEntry,
|
FileInformationClass, ReturnSingleEntry,
|
||||||
@ -1008,7 +913,6 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
|
|
||||||
FspFileNodeConvertExclusiveToShared(FileNode, Full);
|
FspFileNodeConvertExclusiveToShared(FileNode, Full);
|
||||||
|
|
||||||
Request->Kind = FspFsctlTransactQueryDirectoryKind;
|
|
||||||
FspIopResetRequest(Request, FspFsvolQueryDirectoryRequestFini);
|
FspIopResetRequest(Request, FspFsvolQueryDirectoryRequestFini);
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Address = 0;
|
Request->Req.QueryDirectory.Address = 0;
|
||||||
@ -1017,7 +921,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||||
{
|
{
|
||||||
ASSERT(
|
ASSERT(
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
|
||||||
FileDesc->DirectoryMarker.Length);
|
FileDesc->DirectoryMarker.Length);
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Marker.Offset =
|
Request->Req.QueryDirectory.Marker.Offset =
|
||||||
@ -1032,7 +936,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
}
|
}
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||||
|
|
||||||
FspIoqPostIrp(FsvolDeviceExtension->Ioq, Irp, &Result);
|
FspIoqPostIrp(FsvolDeviceExtension->Ioq, Irp, &Result);
|
||||||
}
|
}
|
||||||
@ -1054,65 +958,30 @@ static VOID FspFsvolQueryDirectoryRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, P
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
PIRP Irp = Context[RequestIrp];
|
FSP_FILE_NODE *FileNode = Context[RequestFileNode];
|
||||||
|
PVOID Cookie = (PVOID)((UINT_PTR)Context[RequestCookie] & ~1);
|
||||||
|
PVOID Address = Context[RequestAddress];
|
||||||
|
PEPROCESS Process = Context[RequestProcess];
|
||||||
|
|
||||||
if ((UINT_PTR)Context[RequestCookie] & 1)
|
if (0 != Address)
|
||||||
{
|
{
|
||||||
PVOID Cookie = (PVOID)((UINT_PTR)Context[RequestCookie] & ~1);
|
KAPC_STATE ApcState;
|
||||||
PVOID Address = Context[RequestAddress];
|
BOOLEAN Attach;
|
||||||
PEPROCESS Process = Context[RequestProcess];
|
|
||||||
|
|
||||||
if (0 != Address)
|
ASSERT(0 != Process);
|
||||||
{
|
Attach = Process != PsGetCurrentProcess();
|
||||||
KAPC_STATE ApcState;
|
|
||||||
BOOLEAN Attach;
|
|
||||||
|
|
||||||
ASSERT(0 != Process);
|
if (Attach)
|
||||||
Attach = Process != PsGetCurrentProcess();
|
KeStackAttachProcess(Process, &ApcState);
|
||||||
|
FspProcessBufferRelease(Cookie, Address);
|
||||||
|
if (Attach)
|
||||||
|
KeUnstackDetachProcess(&ApcState);
|
||||||
|
|
||||||
if (Attach)
|
ObDereferenceObject(Process);
|
||||||
KeStackAttachProcess(Process, &ApcState);
|
|
||||||
FspProcessBufferRelease(Cookie, Address);
|
|
||||||
if (Attach)
|
|
||||||
KeUnstackDetachProcess(&ApcState);
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PMDL Mdl = Context[RequestMdl];
|
|
||||||
PVOID Address = Context[RequestAddress];
|
|
||||||
PEPROCESS Process = Context[RequestProcess];
|
|
||||||
|
|
||||||
if (0 != Address)
|
|
||||||
{
|
|
||||||
KAPC_STATE ApcState;
|
|
||||||
BOOLEAN Attach;
|
|
||||||
|
|
||||||
ASSERT(0 != Process);
|
|
||||||
Attach = Process != PsGetCurrentProcess();
|
|
||||||
|
|
||||||
if (Attach)
|
|
||||||
KeStackAttachProcess(Process, &ApcState);
|
|
||||||
MmUnmapLockedPages(Address, Mdl);
|
|
||||||
if (Attach)
|
|
||||||
KeUnstackDetachProcess(&ApcState);
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != Mdl)
|
|
||||||
IoFreeMdl(Mdl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != Irp)
|
if (0 != FileNode)
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
FSP_FILE_NODE *FileNode = IrpSp->FileObject->FsContext;
|
|
||||||
|
|
||||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspDirectoryControl(
|
NTSTATUS FspDirectoryControl(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.c
|
* @file sys/driver.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.h
|
* @file sys/driver.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -837,6 +837,10 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp);
|
|||||||
ULONG FspIoqRetriedIrpCount(FSP_IOQ *Ioq);
|
ULONG FspIoqRetriedIrpCount(FSP_IOQ *Ioq);
|
||||||
|
|
||||||
/* meta cache */
|
/* meta cache */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FspMetaCacheItemHeaderSize = MEMORY_ALLOCATION_ALIGNMENT,
|
||||||
|
};
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock;
|
||||||
@ -1144,11 +1148,13 @@ BOOLEAN FspWriteIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
|
|||||||
return FspProcessBufferSizeMax >= BufferSize;
|
return FspProcessBufferSizeMax >= BufferSize;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
static inline
|
static inline
|
||||||
BOOLEAN FspQueryDirectoryIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
|
BOOLEAN FspQueryDirectoryIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
|
||||||
{
|
{
|
||||||
return FspReadIrpShouldUseProcessBuffer(Irp, BufferSize);
|
return FspReadIrpShouldUseProcessBuffer(Irp, BufferSize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* volume management */
|
/* volume management */
|
||||||
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
|
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/ea.c
|
* @file sys/ea.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/file.c
|
* @file sys/file.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -2166,7 +2166,7 @@ NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
|
|||||||
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
|
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
|
||||||
UNICODE_STRING DirectoryMarker;
|
UNICODE_STRING DirectoryMarker;
|
||||||
|
|
||||||
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength < FileName->Length)
|
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) < FileName->Length)
|
||||||
return STATUS_OBJECT_NAME_INVALID;
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;
|
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/fileinfo.c
|
* @file sys/fileinfo.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1573,6 +1573,7 @@ NTSTATUS FspFsvolSetInformationPrepare(
|
|||||||
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
SECURITY_CLIENT_CONTEXT SecurityClientContext;
|
||||||
HANDLE UserModeAccessToken;
|
HANDLE UserModeAccessToken;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
|
ULONG OriginatingProcessId;
|
||||||
|
|
||||||
SecuritySubjectContext = FspIopRequestContext(Request, RequestSubjectContextOrAccessToken);
|
SecuritySubjectContext = FspIopRequestContext(Request, RequestSubjectContextOrAccessToken);
|
||||||
|
|
||||||
@ -1605,10 +1606,16 @@ NTSTATUS FspFsvolSetInformationPrepare(
|
|||||||
Process = PsGetCurrentProcess();
|
Process = PsGetCurrentProcess();
|
||||||
ObReferenceObject(Process);
|
ObReferenceObject(Process);
|
||||||
|
|
||||||
|
/* get the originating process ID stored in the IRP */
|
||||||
|
OriginatingProcessId = IoGetRequestorProcessId(Irp);
|
||||||
|
|
||||||
/* send the user-mode handle to the user-mode file system */
|
/* send the user-mode handle to the user-mode file system */
|
||||||
FspIopRequestContext(Request, RequestSubjectContextOrAccessToken) = UserModeAccessToken;
|
FspIopRequestContext(Request, RequestSubjectContextOrAccessToken) = UserModeAccessToken;
|
||||||
FspIopRequestContext(Request, RequestProcess) = Process;
|
FspIopRequestContext(Request, RequestProcess) = Process;
|
||||||
Request->Req.SetInformation.Info.Rename.AccessToken = (UINT_PTR)UserModeAccessToken;
|
ASSERT((UINT64)(UINT_PTR)UserModeAccessToken <= 0xffffffffULL);
|
||||||
|
ASSERT((UINT64)(UINT_PTR)OriginatingProcessId <= 0xffffffffULL);
|
||||||
|
Request->Req.SetInformation.Info.Rename.AccessToken =
|
||||||
|
((UINT64)(UINT_PTR)OriginatingProcessId << 32) | (UINT64)(UINT_PTR)UserModeAccessToken;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/flush.c
|
* @file sys/flush.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/fsctl.c
|
* @file sys/fsctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/iop.c
|
* @file sys/iop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2017 Bill Zissimopoulos
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -306,47 +306,6 @@ VOID FspIopCompleteIrpEx(PIRP Irp, NTSTATUS Result, BOOLEAN DeviceDereference)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/*
|
|
||||||
* HACK:
|
|
||||||
*
|
|
||||||
* Turns out that SRV2 sends an undocumented flavor of IRP_MJ_DIRECTORY_CONTROL /
|
|
||||||
* IRP_MN_QUERY_DIRECTORY. These IRP's have a non-NULL Irp->MdlAddress. They expect
|
|
||||||
* the FSD to fill the buffer pointed by Irp->MdlAddress and they cannot handle
|
|
||||||
* completed IRP's with a non-NULL Irp->AssociatedIrp.SystemBuffer. So we have to
|
|
||||||
* provide special support for these IRPs.
|
|
||||||
*
|
|
||||||
* While this processing is IRP_MJ_DIRECTORY_CONTROL specific, we do this here for
|
|
||||||
* these reasons:
|
|
||||||
*
|
|
||||||
* 1. There may be other IRP's that have similar completion requirements under SRV2.
|
|
||||||
* If/when such IRP's are discovered the completion processing can be centralized
|
|
||||||
* here.
|
|
||||||
* 2. IRP_MJ_DIRECTORY_CONTROL has a few different ways that it can complete IRP's.
|
|
||||||
* It is far simpler to do this processing here, even if not academically correct.
|
|
||||||
*
|
|
||||||
* This will have to be revisited if IRP_MJ_DIRECTORY_CONTROL processing changes
|
|
||||||
* substantially (e.g. to no longer use Irp->AssociatedIrp.SystemBuffer).
|
|
||||||
*/
|
|
||||||
if (IRP_MJ_DIRECTORY_CONTROL == IrpSp->MajorFunction &&
|
|
||||||
IRP_MN_QUERY_DIRECTORY == IrpSp->MinorFunction &&
|
|
||||||
0 != Irp->MdlAddress && /* SRV2 queries have this set */
|
|
||||||
0 != Irp->AssociatedIrp.SystemBuffer &&
|
|
||||||
FlagOn(Irp->Flags, IRP_BUFFERED_IO))
|
|
||||||
{
|
|
||||||
if (STATUS_SUCCESS == Result)
|
|
||||||
{
|
|
||||||
PVOID Address = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
|
|
||||||
if (0 != Address)
|
|
||||||
RtlCopyMemory(Address, Irp->AssociatedIrp.SystemBuffer, Irp->IoStatus.Information);
|
|
||||||
else
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
FspFreeExternal(Irp->AssociatedIrp.SystemBuffer);
|
|
||||||
Irp->AssociatedIrp.SystemBuffer = 0;
|
|
||||||
ClearFlag(Irp->Flags, IRP_INPUT_OPERATION | IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (STATUS_SUCCESS != Result &&
|
if (STATUS_SUCCESS != Result &&
|
||||||
STATUS_REPARSE != Result &&
|
STATUS_REPARSE != Result &&
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user