mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
Compare commits
124 Commits
v1.12.2233
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
4fdec4d37f | ||
|
2da97d48f5 | ||
|
7c5dc48414 | ||
|
93c057571a | ||
|
da16d0e6ea | ||
|
dbaee25ed2 | ||
|
2bf9a6c16e | ||
|
b058925692 | ||
|
507c794470 | ||
|
9a6571809e | ||
|
e452f75c9c | ||
|
7551193ad7 | ||
|
65bf8c5319 | ||
|
be5faf34bc | ||
|
0e1c8ae1dc | ||
|
9aa67bdad4 | ||
|
de321620fd | ||
|
a482183149 | ||
|
6fb72555d3 | ||
|
9accf72d39 | ||
|
5c03dd11ee | ||
|
1f37e5a81a | ||
|
db319bc3c1 | ||
|
c04e3d9534 | ||
|
1912814d79 | ||
|
97c075e744 | ||
|
874a223bcc | ||
|
901a98e118 | ||
|
0ab4300738 | ||
|
52e6aa97b5 | ||
|
a7d82d5f8d | ||
|
3aadaee511 | ||
|
da3a8aa229 | ||
|
1f0fd4c280 | ||
|
6da92f0b54 | ||
|
4f5f1dd350 | ||
|
ba5d52e9a5 | ||
|
d626fb9563 | ||
|
69cc1820e1 | ||
|
c06141c8c8 | ||
|
760c2acded | ||
|
671efe625a | ||
|
a59b32b1ee | ||
|
22d81846df | ||
|
8c9b8362b4 | ||
|
e92eb023fe | ||
|
e550e261f0 | ||
|
46054c03fe | ||
|
db07b24342 | ||
|
cb81e81985 | ||
|
b62e1e920b | ||
|
01d9fa1719 | ||
|
6846508631 | ||
|
0488451c3d | ||
|
7c3292af81 | ||
|
3d2ba637e5 | ||
|
db72b57ca4 | ||
|
020157a9ae | ||
|
d99cb2d7d1 | ||
|
298261c4af | ||
|
3c674a556d | ||
|
f85fb49f49 | ||
|
92084a56c6 | ||
|
53f97c9841 | ||
|
2770eca1bf | ||
|
2945971ba9 | ||
|
0a39ef60bd | ||
|
e1faf1351e | ||
|
7333451eac | ||
|
c178db127c | ||
|
9747af22e8 | ||
|
ef9b7e22c6 | ||
|
fd27c470b0 | ||
|
c187209159 | ||
|
a2e92207c5 | ||
|
4f5ad93f00 | ||
|
b47c42877a | ||
|
d1fc5e5d0f | ||
|
c4ecd15c0a | ||
|
91d7f3b673 | ||
|
63e23c2039 | ||
|
4d1594b1cf | ||
|
0eb6912296 | ||
|
c237a55951 | ||
|
98d68c4007 | ||
|
e8cec5dfc1 | ||
|
9a27a3225b | ||
|
d44cb54bd5 | ||
|
d1f863e9ac | ||
|
ccdbc9daf9 | ||
|
1723179430 | ||
|
8e0f5b457c | ||
|
2fc2c237d3 | ||
|
b99fb9a5cb | ||
|
538fee8e54 | ||
|
925fa4b6e4 | ||
|
b179c7a933 | ||
|
b25e116f08 | ||
|
422c369b15 | ||
|
d450683e2e | ||
|
ad1aa156dc | ||
|
aa012db099 | ||
|
b08f60bfbd | ||
|
a9b3cef253 | ||
|
b43d1f5502 | ||
|
de9112f6e6 | ||
|
329b14d838 | ||
|
7009324e7f | ||
|
f4ae097722 | ||
|
50be07e8ac | ||
|
2dd054087c | ||
|
7f6608cf7d | ||
|
39e9d8156b | ||
|
90acd19014 | ||
|
9154ec784d | ||
|
0b3ce52958 | ||
|
adeed2b79d | ||
|
5dda5903a8 | ||
|
a7bc306b2d | ||
|
7e59c2e5a6 | ||
|
9670caa3fe | ||
|
005d3e4fb0 | ||
|
62a6bbab66 | ||
|
40ba537dc2 |
8
.github/workflows/avm.yml
vendored
8
.github/workflows/avm.yml
vendored
@ -11,8 +11,8 @@ jobs:
|
|||||||
- uses: billziss-gh/avm@v1
|
- uses: billziss-gh/avm@v1
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
https://github.com/winfsp/winfsp/releases/download/v1.6/winfsp-1.6.20027.msi
|
|
||||||
https://github.com/winfsp/winfsp/releases/download/v1.7/winfsp-1.7.20172.msi
|
|
||||||
https://github.com/winfsp/winfsp/releases/download/v1.8/winfsp-1.8.20304.msi
|
|
||||||
https://github.com/winfsp/winfsp/releases/download/v1.9/winfsp-1.9.21096.msi
|
|
||||||
https://github.com/winfsp/winfsp/releases/download/v1.10/winfsp-1.10.22006.msi
|
https://github.com/winfsp/winfsp/releases/download/v1.10/winfsp-1.10.22006.msi
|
||||||
|
https://github.com/winfsp/winfsp/releases/download/v1.11/winfsp-1.11.22176.msi
|
||||||
|
https://github.com/winfsp/winfsp/releases/download/v1.12/winfsp-1.12.22301.msi
|
||||||
|
https://github.com/winfsp/winfsp/releases/download/v1.12.22339/winfsp-1.12.22339.msi
|
||||||
|
https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi
|
||||||
|
128
Changelog.md
128
Changelog.md
@ -1,6 +1,134 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
|
||||||
|
## v2.1B2 (2024 Beta2)
|
||||||
|
|
||||||
|
- [FIX] Fixes a rare BSOD on recent versions of Windows. See commit a482183 for details.
|
||||||
|
|
||||||
|
- [FIX] Fixes a rare problem when using `NtCreateFile` to perform "relative" opens on a network drive (see GitHub issue #561).
|
||||||
|
|
||||||
|
- [FIX] Fixes a racing issue with two processes competing to start the FSD discovered during testing.
|
||||||
|
|
||||||
|
|
||||||
|
## v2.1B1 (2024 Beta1)
|
||||||
|
|
||||||
|
- [FIX] Fixes a rare BSOD on recent versions of Windows. See commit a482183 for details.
|
||||||
|
|
||||||
|
- [FIX] Fixes a racing issue with two processes competing to start the FSD discovered during testing.
|
||||||
|
|
||||||
|
|
||||||
|
## v2.0 (2023)
|
||||||
|
|
||||||
|
This release is a major version change for WinFsp (from 1.x to 2.x). There are no backwards incompatible API changes in this release, but nevertheless enough things change that warrant a version change.
|
||||||
|
|
||||||
|
The major new feature of this release is that it allows uninstallation and reinstallation of WinFsp **without reboot**. Going forward installers named `winfsp-2.x.y.msi` can be uninstalled and reinstalled without reboot. Furthermore a later version `winfsp-2.x.y.msi` installer can be used to upgrade over an earlier version `winfsp-2.x.y.msi` installer. However note that a `winfsp-2.x.y.msi` installer cannot be used to upgrade over a legacy `winfsp-1.x.y.msi` installer; you will still need to uninstall the old `winfsp-1.x.y.msi` installer, potentially reboot and then install the new `winfsp-2.x.y.msi` installer.
|
||||||
|
|
||||||
|
Changes visible to file system developers are listed below:
|
||||||
|
|
||||||
|
- WinFsp executable files are now installed by default in the directory `C:\Program Files (x86)\WinFsp\SxS\sxs.<InstanceID>\bin`. The previous directory `C:\Program Files (x86)\WinFsp\bin` is now a junction that points to the above directory.
|
||||||
|
|
||||||
|
- The WinFsp driver name is no longer `winfsp`, but rather a name such as `winfsp+<InstanceID>`. This means that managing the driver using the `sc.exe` utility is no longer as easy.
|
||||||
|
|
||||||
|
- The `fsptool` utility has been updated with new commands `lsdrv`, `load`, `unload` and `ver`. The `lsdrv`, `load` and `unload` commands can be used to manage the driver from the command line. This is rarely necessary, but may be useful for troubleshooting purposes.
|
||||||
|
|
||||||
|
- Prior to this release the WinFsp driver would never unmount a file system volume unless the user mode file system requested the unmount. From this release onward it is possible for the WinFsp driver to unmount a file system volume, without a user mode file system request. This is to allow for the driver to be unloaded.
|
||||||
|
|
||||||
|
A new operation `DispatcherStopped` has been added to `FSP_FILE_SYSTEM_INTERFACE`, which is sent after the file system volume has been unmounted and the file system dispatcher has been stopped. This can happen because of a user mode file system request via `FspFileSystemStopDispatcher` or because of driver unload. The `DispatcherStopped` operation includes a `Normally` parameter, which is `TRUE` for normal file system shutdown via `FspFileSystemStopDispatcher` and `FALSE` otherwise.
|
||||||
|
|
||||||
|
Native file systems that use the `FspService` infrastructure can use the `FspFileSystemStopServiceIfNecessary` API to handle the `DispatcherStopped` operation (see the MEMFS and NTPTFS samples). FUSE file systems get this functionality for free. .NET file systems that use the `Service` class infrastructure also get this functionality for free.
|
||||||
|
|
||||||
|
- WinFsp now offers a .NET library that targets .NET Framework 3.5 (as before) and one that targets .NET Standard 2.0. This is due to work by @Noire001 in PR #451.
|
||||||
|
|
||||||
|
- There is now a winfsp.net nuget package at https://www.nuget.org/packages/winfsp.net
|
||||||
|
|
||||||
|
- FUSE now supports path components up to 255 characters long (previously it was 255 bytes). This is due to work by @zeho11 in PR #474.
|
||||||
|
|
||||||
|
- The FUSE passthrough file systems have been updated to support long paths. This is also due to work by @zeho11.
|
||||||
|
|
||||||
|
- In some rare circumstances WinFsp file systems could report duplicate directory entries. This problem has been fixed. (GitHub issue #475.)
|
||||||
|
|
||||||
|
- The WinFsp symbols directory has been removed. If you are looking for WinFsp symbols you can find them at https://github.com/winfsp/winfsp.sym
|
||||||
|
|
||||||
|
|
||||||
|
## v2.0RC1 (2023 RC1)
|
||||||
|
|
||||||
|
This release is a major version change for WinFsp (from 1.x to 2.x). There are no backwards incompatible API changes in this release, but nevertheless enough things change that warrant a version change.
|
||||||
|
|
||||||
|
The major new feature of this release is that it allows uninstallation and reinstallation of WinFsp **without reboot**. Going forward installers named `winfsp-2.x.y.msi` can be uninstalled and reinstalled without reboot. Furthermore a later version `winfsp-2.x.y.msi` installer can be used to upgrade over an earlier version `winfsp-2.x.y.msi` installer. However note that a `winfsp-2.x.y.msi` installer cannot be used to upgrade over a legacy `winfsp-1.x.y.msi` installer; you will still need to uninstall the old `winfsp-1.x.y.msi` installer, potentially reboot and then install the new `winfsp-2.x.y.msi` installer.
|
||||||
|
|
||||||
|
Changes visible to file system developers are listed below:
|
||||||
|
|
||||||
|
- WinFsp executable files are now installed by default in the directory `C:\Program Files (x86)\WinFsp\SxS\sxs.<InstanceID>\bin`. The previous directory `C:\Program Files (x86)\WinFsp\bin` is now a junction that points to the above directory.
|
||||||
|
|
||||||
|
- The WinFsp driver name is no longer `winfsp`, but rather a name such as `winfsp+<InstanceID>`. This means that managing the driver using the `sc.exe` utility is no longer as easy.
|
||||||
|
|
||||||
|
- The `fsptool` utility has been updated with new commands `lsdrv`, `load`, `unload` and `ver`. The `lsdrv`, `load` and `unload` commands can be used to manage the driver from the command line. This is rarely necessary, but may be useful for troubleshooting purposes.
|
||||||
|
|
||||||
|
- Prior to this release the WinFsp driver would never unmount a file system volume unless the user mode file system requested the unmount. From this release onward it is possible for the WinFsp driver to unmount a file system volume, without a user mode file system request. This is to allow for the driver to be unloaded.
|
||||||
|
|
||||||
|
A new operation `DispatcherStopped` has been added to `FSP_FILE_SYSTEM_INTERFACE`, which is sent after the file system volume has been unmounted and the file system dispatcher has been stopped. This can happen because of a user mode file system request via `FspFileSystemStopDispatcher` or because of driver unload. The `DispatcherStopped` operation includes a `Normally` parameter, which is `TRUE` for normal file system shutdown via `FspFileSystemStopDispatcher` and `FALSE` otherwise.
|
||||||
|
|
||||||
|
Native file systems that use the `FspService` infrastructure can use the `FspFileSystemStopServiceIfNecessary` API to handle the `DispatcherStopped` operation (see the MEMFS and NTPTFS samples). FUSE file systems get this functionality for free. .NET file systems that use the `Service` class infrastructure also get this functionality for free.
|
||||||
|
|
||||||
|
- WinFsp now offers a .NET library that targets .NET Framework 3.5 (as before) and one that targets .NET Standard 2.0. This is due to work by @Noire001 in PR #451.
|
||||||
|
|
||||||
|
- There is now a winfsp.net nuget package at https://www.nuget.org/packages/winfsp.net
|
||||||
|
|
||||||
|
- FUSE now supports path components up to 255 characters long (previously it was 255 bytes). This is due to work by @zeho11 in PR #474.
|
||||||
|
|
||||||
|
- The FUSE passthrough file systems have been updated to support long paths. This is also due to work by @zeho11.
|
||||||
|
|
||||||
|
- In some rare circumstances WinFsp file systems could report duplicate directory entries. This problem has been fixed. (GitHub issue #475.)
|
||||||
|
|
||||||
|
- The WinFsp symbols directory has been removed. If you are looking for WinFsp symbols you can find them at https://github.com/winfsp/winfsp.sym
|
||||||
|
|
||||||
|
|
||||||
|
## v2.0B2 (2023 Beta2)
|
||||||
|
|
||||||
|
This release is a major version change for WinFsp (from 1.x to 2.x). There are no backwards incompatible API changes in this release, but nevertheless enough things change that warrant a version change.
|
||||||
|
|
||||||
|
The major new feature of this release is that it allows uninstallation and reinstallation of WinFsp **without reboot**. Going forward installers named `winfsp-2.x.y.msi` can be uninstalled and reinstalled without reboot. Furthermore a later version `winfsp-2.x.y.msi` installer can be used to upgrade over an earlier version `winfsp-2.x.y.msi` installer. However note that a `winfsp-2.x.y.msi` installer cannot be used to upgrade over a "legacy" `winfsp-1.x.y.msi` installer; you will still need to uninstall the "old" `winfsp-1.x.y.msi` installer, potentially reboot and then install the "new" `winfsp-2.x.y.msi` installer.
|
||||||
|
|
||||||
|
Changes visible to file system developers are listed below:
|
||||||
|
|
||||||
|
- WinFsp executable files are now installed by default in the directory `C:\Program Files (x86)\WinFsp\SxS\sxs.<InstanceID>\bin`. The previous directory `C:\Program Files (x86)\WinFsp\bin` is now a junction that points to the above directory.
|
||||||
|
|
||||||
|
- The WinFsp driver name is no longer `winfsp`, but rather a name such as `winfsp+<InstanceID>`. This means that managing the driver using the `sc.exe` utility is no longer as easy.
|
||||||
|
|
||||||
|
- The `fsptool` utility has been updated with new commands `lsdrv`, `load`, `unload` and `ver`. The `lsdrv`, `load` and `unload` commands can be used to manage the driver from the command line. This is rarely necessary, but may be useful for troubleshooting purposes.
|
||||||
|
|
||||||
|
- Prior to this release the WinFsp driver would never unmount a file system volume unless the user mode file system requested the unmount. From this release onward it is possible for the WinFsp driver to unmount a file system volume, without a user mode file system request. This is to allow for the driver to be unloaded.
|
||||||
|
|
||||||
|
A new operation `DispatcherStopped` has been added to `FSP_FILE_SYSTEM_INTERFACE`, which is sent after the file system volume has been unmounted and the file system dispatcher has been stopped. This can happen because of a user mode file system request via `FspFileSystemStopDispatcher` or because of driver unload. The `DispatcherStopped` operation includes a `Normally` parameter, which is `TRUE` for normal file system shutdown via `FspFileSystemStopDispatcher` and `FALSE` otherwise.
|
||||||
|
|
||||||
|
Native file systems that use the `FspService` infrastructure can use the `FspFileSystemStopServiceIfNecessary` API to handle the `DispatcherStopped` operation (see the MEMFS and NTPTFS samples). FUSE file systems get this functionality for free. .NET file systems that use the `Service` class infrastructure also get this functionality for free.
|
||||||
|
|
||||||
|
- WinFsp now offers a .NET library that targets .NET Framework 3.5 (as before) and one that targets .NET Standard 2.0. This is due to work by @Noire001 in PR #451.
|
||||||
|
|
||||||
|
- FUSE now supports path components up to 255 characters long (previously it was 255 bytes). This is due to work by @zeho11 in PR #474.
|
||||||
|
|
||||||
|
- The FUSE passthrough file systems have been updated to support long paths. This is also due to work by @zeho11.
|
||||||
|
|
||||||
|
- The WinFsp symbols directory has been removed. If you are looking for WinFsp symbols you can find them at https://github.com/winfsp/winfsp.sym
|
||||||
|
|
||||||
|
|
||||||
|
## v2.0B1 (2023 Beta1)
|
||||||
|
|
||||||
|
This release is a major version change for WinFsp (from 1.x to 2.x). There are no backwards incompatible API changes in this release, but nevertheless enough things change that warrant a version change.
|
||||||
|
|
||||||
|
The major new feature of this release is that it allows uninstallation and reinstallation of WinFsp **without reboot**. Going forward installers named `winfsp-2.x.y.msi` can be uninstalled and reinstalled without reboot. Furthermore a later version `winfsp-2.x.y.msi` installer can be used to upgrade over an earlier version `winfsp-2.x.y.msi` installer. However note that a `winfsp-2.x.y.msi` installer cannot be used to upgrade over a "legacy" `winfsp-1.x.y.msi` installer; you will still need to uninstall the "old" `winfsp-1.x.y.msi` installer, potentially reboot and then install the "new" `winfsp-2.x.y.msi` installer.
|
||||||
|
|
||||||
|
Some changes that may be visible to file system developers are listed below:
|
||||||
|
|
||||||
|
- WinFsp executable files are now installed by default in the directory `C:\Program Files (x86)\WinFsp\SxS\sxs.<InstanceID>\bin`. The previous directory `C:\Program Files (x86)\WinFsp\bin` is now a junction that points to the above directory.
|
||||||
|
|
||||||
|
- The WinFsp driver name is no longer `winfsp`, but rather a name such as `winfsp+<InstanceID>`. This means that managing the driver using the `sc.exe` utility is no longer as easy.
|
||||||
|
|
||||||
|
- The `fsptool` utility has been updated with new commands `lsdrv`, `load`, `unload` and `ver`. The `lsdrv`, `load` and `unload` commands can be used to manage the driver from the command line. This is rarely necessary, but may be useful for troubleshooting purposes.
|
||||||
|
|
||||||
|
- The WinFsp symbols directory has been removed. If you are looking for WinFsp symbols you can find them at https://github.com/winfsp/winfsp.sym
|
||||||
|
|
||||||
|
|
||||||
## v1.12.22339 (2022.2 Update1)
|
## v1.12.22339 (2022.2 Update1)
|
||||||
|
|
||||||
*Note: This release (`v1.12.22339`) is the same as the previous release (`v1.12`) except that: (1) the kernel-mode drivers are now digitally signed only with the Microsoft Attestation signature, and that: (2) no release assets are digitally signed with SHA-1. (This change was necessary to fix a problem in older versions of Windows such as Windows 7.)*
|
*Note: This release (`v1.12.22339`) is the same as the previous release (`v1.12`) except that: (1) the kernel-mode drivers are now digitally signed only with the Microsoft Attestation signature, and that: (2) no release assets are digitally signed with SHA-1. (This change was necessary to fix a problem in older versions of Windows such as Windows 7.)*
|
||||||
|
@ -66,6 +66,8 @@ CONTRIBUTOR LIST
|
|||||||
|Gal Hammer (Red Hat, https://www.redhat.com) |ghammer at redhat.com
|
|Gal Hammer (Red Hat, https://www.redhat.com) |ghammer at redhat.com
|
||||||
|John Oberschelp |john at oberschelp.net
|
|John Oberschelp |john at oberschelp.net
|
||||||
|John Tyner |jtyner at gmail.com
|
|John Tyner |jtyner at gmail.com
|
||||||
|
|Konstantinos Karakostas |noiredev at protonmail.com
|
||||||
|
|Naoki Ikeguchi |me at s6n.jp
|
||||||
|Paweł Wegner (Google LLC, https://google.com) |lemourin at google.com
|
|Paweł Wegner (Google LLC, https://google.com) |lemourin at google.com
|
||||||
|Pedro Frejo (Arpa System, https://arpasystem.com) |pedro.frejo at arpasystem.com
|
|Pedro Frejo (Arpa System, https://arpasystem.com) |pedro.frejo at arpasystem.com
|
||||||
|Ronny Chan |ronny at ronnychan.ca
|
|Ronny Chan |ronny at ronnychan.ca
|
||||||
@ -73,4 +75,5 @@ CONTRIBUTOR LIST
|
|||||||
|Santiago Ganis |sganis at gmail.com
|
|Santiago Ganis |sganis at gmail.com
|
||||||
|Tobias Urlaub |saibotu at outlook.de
|
|Tobias Urlaub |saibotu at outlook.de
|
||||||
|Victor Gao |victgm at outlook.com
|
|Victor Gao |victgm at outlook.com
|
||||||
|
|Zeho Huang |zeho11 at protonmail.com
|
||||||
|===
|
|===
|
||||||
|
@ -51,6 +51,11 @@ install:
|
|||||||
$targets.Save("C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets")
|
$targets.Save("C:\Program Files (x86)\Windows Kits\10\build\WindowsDriver.Common.targets")
|
||||||
Add-AppveyorMessage "Hack to make WDK 1903 work on VS2015"
|
Add-AppveyorMessage "Hack to make WDK 1903 work on VS2015"
|
||||||
}
|
}
|
||||||
|
# Install .NET SDK on VS2015 image
|
||||||
|
- ps: |
|
||||||
|
if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") {
|
||||||
|
& ([scriptblock]::Create((New-Object System.Net.WebClient).DownloadString('https://dot.net/v1/dotnet-install.ps1'))) -InstallDir "C:\dotnet"
|
||||||
|
}
|
||||||
# Submodules
|
# Submodules
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
# Kernel and user mode dumps
|
# Kernel and user mode dumps
|
||||||
@ -76,6 +81,9 @@ build_script:
|
|||||||
# remove ARM64 project configurations to build in VS2015/VS2017
|
# remove ARM64 project configurations to build in VS2015/VS2017
|
||||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" tools\gensrc\remove-build-arm64.bat
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" tools\gensrc\remove-build-arm64.bat
|
||||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" tools\gensrc\remove-build-arm64.bat
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" tools\gensrc\remove-build-arm64.bat
|
||||||
|
# remove .NET library from solution for VS2015 and use the .NET SDK instead
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" tools\gensrc\remove-build-dotnet.bat build\VStudio
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set PATH=C:\dotnet;%PATH%
|
||||||
# build winfsp
|
# build winfsp
|
||||||
- tools\build.bat %CONFIGURATION%
|
- tools\build.bat %CONFIGURATION%
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
<MyCompanyName>Navimatics LLC</MyCompanyName>
|
<MyCompanyName>Navimatics LLC</MyCompanyName>
|
||||||
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
|
<MyCopyright>2015-$([System.DateTime]::Now.ToString(`yyyy`)) Bill Zissimopoulos</MyCopyright>
|
||||||
|
|
||||||
<MyCanonicalVersion>1.12</MyCanonicalVersion>
|
<MyCanonicalVersion>2.1</MyCanonicalVersion>
|
||||||
|
|
||||||
<MyProductVersion>2022.2</MyProductVersion>
|
<MyProductVersion>2024 Beta2</MyProductVersion>
|
||||||
<MyProductStage>Gold</MyProductStage>
|
<MyProductStage>Beta</MyProductStage>
|
||||||
|
|
||||||
<MyCrossCert>DigiCertGlobalG3CodeSigningECCSHA3842021CA1.cer</MyCrossCert>
|
<MyCrossCert>DigiCertGlobalG3CodeSigningECCSHA3842021CA1.cer</MyCrossCert>
|
||||||
<MyCertIssuer>DigiCert</MyCertIssuer>
|
<MyCertIssuer>DigiCert</MyCertIssuer>
|
||||||
|
@ -1,25 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<Project>
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<PropertyGroup>
|
||||||
|
<BaseIntermediateOutputPath>$(SolutionDir)build\$(MSBuildProjectName).build\</BaseIntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.common.props))/build.common.props" />
|
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.common.props))/build.common.props" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{94580219-CC8D-4FE5-A3BE-437B0B3481E1}</ProjectGuid>
|
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<ProjectName>winfsp.net</ProjectName>
|
<ProjectName>winfsp.net</ProjectName>
|
||||||
<RootNamespace>Fsp</RootNamespace>
|
<RootNamespace>Fsp</RootNamespace>
|
||||||
<AssemblyName>$(MyProductFileName)-msil</AssemblyName>
|
<AssemblyName>$(MyProductFileName)-msil</AssemblyName>
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
<TargetFrameworks>netstandard2.0;net35</TargetFrameworks>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<TargetFrameworkProfile />
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
|
||||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
@ -32,7 +36,6 @@
|
|||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
|
||||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
@ -47,9 +50,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AssemblyOriginatorKeyFile>winfsp.net.snk</AssemblyOriginatorKeyFile>
|
<AssemblyOriginatorKeyFile>winfsp.net.snk</AssemblyOriginatorKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\..\..\src\dotnet\FileSystemBase+Const.cs">
|
<Compile Include="..\..\..\src\dotnet\FileSystemBase+Const.cs">
|
||||||
<Link>FileSystemBase+Const.cs</Link>
|
<Link>FileSystemBase+Const.cs</Link>
|
||||||
@ -70,29 +70,28 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="winfsp.net.snk" />
|
<None Include="winfsp.net.snk" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<PackageReference Include="Microsoft.Win32.Registry">
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
<Version>5.0.0</Version>
|
||||||
<Target Name="AfterBuild">
|
</PackageReference>
|
||||||
</Target>
|
<PackageReference Include="System.IO.FileSystem.AccessControl">
|
||||||
-->
|
<Version>5.0.0</Version>
|
||||||
<Target Name="BeforeBuild">
|
</PackageReference>
|
||||||
<ItemGroup>
|
|
||||||
<AssemblyInfo Include="using System.Reflection%3b" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyProduct("$(MyProductName)")]" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyTitle("$(MyDescription)")]" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyCompany("$(MyCompanyName)")]" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyCopyright("$(MyCopyright)")]" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyVersion("$(MyAssemblyVersion)")]" />
|
|
||||||
<AssemblyInfo Include="[assembly: AssemblyFileVersion("$(MyVersion)")]" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<MakeDir Directories="$(IntermediateOutputPath)" />
|
<PropertyGroup>
|
||||||
<WriteLinesToFile File="$(IntermediateOutputPath)AssemblyInfo.cs" Lines="@(AssemblyInfo)" Overwrite="true" />
|
<AssemblyName>$(MyProductFileName)-msil</AssemblyName>
|
||||||
<ItemGroup>
|
<AssemblyTitle>$(MyDescription)</AssemblyTitle>
|
||||||
<Compile Include="$(IntermediateOutputPath)AssemblyInfo.cs" />
|
<Product>$(MyProductName)</Product>
|
||||||
<FileWrites Include="$(IntermediateOutputPath)AssemblyInfo.cs" />
|
<Copyright>$(MyCopyright)</Copyright>
|
||||||
</ItemGroup>
|
<AssemblyVersion>$(MyAssemblyVersion)</AssemblyVersion>
|
||||||
</Target>
|
<FileVersion>$(MyVersion)</FileVersion>
|
||||||
|
<!-- NuGet metadata -->
|
||||||
|
<PackageId>$(MyProductFileName).net</PackageId>
|
||||||
|
<Version>$(MyVersion)</Version>
|
||||||
|
<Description>$(MyDescription)</Description>
|
||||||
|
<Authors>$(MyCopyright)</Authors>
|
||||||
|
<Company>$(MyCompanyName)</Company>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>exit /b 0
|
<PostBuildEvent>exit /b 0
|
||||||
|
|
||||||
@ -110,4 +109,5 @@ for /f "delims=" %25%25l in ($(ProjectDir)winfsp.net.policy.config) do (
|
|||||||
"$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.0A\Bin\al.exe" /product:"$(MyProductName)" /title:"$(MyDescription)" /company:"$(MyCompanyName)" /copyright:"$(MyCopyright)" /version:"$(MyAssemblyPolicyVersion)" /fileversion:"$(MyVersion)" /link:$(OutDir)policy.$(MyAssemblyPolicyVersion).$(TargetName).config /out:$(OutDir)policy.$(MyAssemblyPolicyVersion).$(TargetName).dll /keyfile:$(ProjectDir)$(ProjectName).snk
|
"$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.0A\Bin\al.exe" /product:"$(MyProductName)" /title:"$(MyDescription)" /company:"$(MyCompanyName)" /copyright:"$(MyCopyright)" /version:"$(MyAssemblyPolicyVersion)" /fileversion:"$(MyVersion)" /link:$(OutDir)policy.$(MyAssemblyPolicyVersion).$(TargetName).config /out:$(OutDir)policy.$(MyAssemblyPolicyVersion).$(TargetName).dll /keyfile:$(ProjectDir)$(ProjectName).snk
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||||
</Project>
|
</Project>
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file CustomActions.cpp
|
* @file CustomActions.cpp
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -21,10 +21,55 @@
|
|||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
#include <msiquery.h>
|
#include <msiquery.h>
|
||||||
#include <wcautil.h>
|
#include <wcautil.h>
|
||||||
#include <strutil.h>
|
#include <strutil.h>
|
||||||
|
|
||||||
|
static HINSTANCE DllInstance;
|
||||||
|
|
||||||
|
UINT __stdcall InstanceID(MSIHANDLE MsiHandle)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
WCHAR MessageBuf[64];
|
||||||
|
wsprintfW(MessageBuf, L"PID=%ld", GetCurrentProcessId());
|
||||||
|
MessageBoxW(0, MessageBuf, L"" __FUNCTION__ " Break", MB_OK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
UINT err = ERROR_SUCCESS;
|
||||||
|
SYSTEMTIME SystemTime;
|
||||||
|
WCHAR Result[32+1];
|
||||||
|
|
||||||
|
hr = WcaInitialize(MsiHandle, __FUNCTION__);
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Initialized");
|
||||||
|
|
||||||
|
GetSystemTime(&SystemTime);
|
||||||
|
wsprintfW(Result, L"%04u%02u%02uT%02u%02u%02uZ",
|
||||||
|
SystemTime.wYear,
|
||||||
|
SystemTime.wMonth,
|
||||||
|
SystemTime.wDay,
|
||||||
|
SystemTime.wHour,
|
||||||
|
SystemTime.wMinute,
|
||||||
|
SystemTime.wSecond);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sleep 1 second to ensure timestamp uniqueness.
|
||||||
|
*
|
||||||
|
* Note that this assumes that time is monotonic and users do not change time.
|
||||||
|
* Disable for now as it is assumed that the installation takes more than 1 second to complete.
|
||||||
|
*/
|
||||||
|
//Sleep(1000);
|
||||||
|
|
||||||
|
WcaSetProperty(L"" __FUNCTION__, Result);
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
err = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(err);
|
||||||
|
}
|
||||||
|
|
||||||
UINT __stdcall ServiceRunning(MSIHANDLE MsiHandle)
|
UINT __stdcall ServiceRunning(MSIHANDLE MsiHandle)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
@ -44,7 +89,7 @@ UINT __stdcall ServiceRunning(MSIHANDLE MsiHandle)
|
|||||||
hr = WcaInitialize(MsiHandle, __FUNCTION__);
|
hr = WcaInitialize(MsiHandle, __FUNCTION__);
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
WcaGetProperty(L"" __FUNCTION__, &ServiceName);
|
hr = WcaGetProperty(L"" __FUNCTION__, &ServiceName);
|
||||||
ExitOnFailure(hr, "Failed to get ServiceName");
|
ExitOnFailure(hr, "Failed to get ServiceName");
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Initialized: \"%S\"", ServiceName);
|
WcaLog(LOGMSG_STANDARD, "Initialized: \"%S\"", ServiceName);
|
||||||
@ -70,12 +115,390 @@ LExit:
|
|||||||
return WcaFinalize(err);
|
return WcaFinalize(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT __stdcall DeferredAction(MSIHANDLE MsiHandle)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
WCHAR MessageBuf[64];
|
||||||
|
wsprintfW(MessageBuf, L"PID=%ld", GetCurrentProcessId());
|
||||||
|
MessageBoxW(0, MessageBuf, L"" __FUNCTION__ " Break", MB_OK);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
UINT err = ERROR_SUCCESS;
|
||||||
|
PWSTR CommandLine = 0;
|
||||||
|
PWSTR *Argv;
|
||||||
|
int Argc;
|
||||||
|
CHAR ProcName[64];
|
||||||
|
FARPROC Proc;
|
||||||
|
|
||||||
|
hr = WcaInitialize(MsiHandle, __FUNCTION__);
|
||||||
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
|
hr = WcaGetProperty(L"CustomActionData", &CommandLine);
|
||||||
|
ExitOnFailure(hr, "Failed to get CommandLine");
|
||||||
|
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Initialized: \"%S\"", CommandLine);
|
||||||
|
|
||||||
|
Argv = CommandLineToArgvW(CommandLine, &Argc);
|
||||||
|
ExitOnNullWithLastError(Argv, hr, "Failed to CommandLineToArgvW");
|
||||||
|
|
||||||
|
if (0 < Argc)
|
||||||
|
{
|
||||||
|
if (0 == WideCharToMultiByte(CP_UTF8, 0, Argv[0], -1, ProcName, sizeof ProcName, 0, 0))
|
||||||
|
ExitWithLastError(hr, "Failed to WideCharToMultiByte");
|
||||||
|
|
||||||
|
Proc = GetProcAddress(DllInstance, ProcName);
|
||||||
|
ExitOnNullWithLastError(Proc, hr, "Failed to GetProcAddress");
|
||||||
|
|
||||||
|
err = ((HRESULT (*)(int, PWSTR *))Proc)(Argc, Argv);
|
||||||
|
ExitOnWin32Error(err, hr, "Failed to %s", ProcName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
ExitOnFailure(hr, "Failed to get arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
LExit:
|
||||||
|
LocalFree(Argv);
|
||||||
|
ReleaseStr(CommandLine);
|
||||||
|
|
||||||
|
err = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
|
return WcaFinalize(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD MakeSymlink(PWSTR Symlink, PWSTR Target);
|
||||||
|
static DWORD MakeJunction(PWSTR Junction, PWSTR Target);
|
||||||
|
static DWORD CreateJunction(PWSTR Junction, PWSTR Target);
|
||||||
|
static DWORD RemoveFile(PWSTR FileName);
|
||||||
|
|
||||||
|
DWORD InstallSymlinks(int Argc, PWSTR *Argv)
|
||||||
|
{
|
||||||
|
/* usage: InstallSymlinks/InstallJunctions SourceDir TargetDir Name... */
|
||||||
|
|
||||||
|
DWORD Result;
|
||||||
|
BOOL Junctions;
|
||||||
|
PWSTR SourceDir, TargetDir;
|
||||||
|
WCHAR SourcePath[MAX_PATH], TargetPath[MAX_PATH];
|
||||||
|
int SourceDirLen, TargetDirLen, Len;
|
||||||
|
|
||||||
|
if (4 > Argc)
|
||||||
|
{
|
||||||
|
Result = ERROR_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Junctions = 0 == lstrcmpW(L"InstallJunctions", Argv[0]);
|
||||||
|
SourceDir = Argv[1];
|
||||||
|
TargetDir = Argv[2];
|
||||||
|
SourceDirLen = lstrlenW(SourceDir);
|
||||||
|
TargetDirLen = lstrlenW(TargetDir);
|
||||||
|
|
||||||
|
for (int Argi = 3; Argc > Argi; Argi++)
|
||||||
|
{
|
||||||
|
Len = lstrlenW(Argv[Argi]);
|
||||||
|
if (MAX_PATH < SourceDirLen + Len + 1 || MAX_PATH < TargetDirLen + Len + 1)
|
||||||
|
{
|
||||||
|
Result = ERROR_FILENAME_EXCED_RANGE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(SourcePath, SourceDir, SourceDirLen * sizeof(WCHAR));
|
||||||
|
memcpy(SourcePath + SourceDirLen, Argv[Argi], Len * sizeof(WCHAR));
|
||||||
|
SourcePath[SourceDirLen + Len] = L'\0';
|
||||||
|
|
||||||
|
memcpy(TargetPath, TargetDir, TargetDirLen * sizeof(WCHAR));
|
||||||
|
memcpy(TargetPath + TargetDirLen, Argv[Argi], Len * sizeof(WCHAR));
|
||||||
|
TargetPath[TargetDirLen + Len] = L'\0';
|
||||||
|
|
||||||
|
if (!Junctions)
|
||||||
|
Result = MakeSymlink(SourcePath, TargetPath);
|
||||||
|
else
|
||||||
|
Result = MakeJunction(SourcePath, TargetPath);
|
||||||
|
#if 0
|
||||||
|
WCHAR MessageBuf[1024];
|
||||||
|
wsprintfW(MessageBuf, L"MakeSymlink(\"%s\", \"%s\") = %lu", SourcePath, TargetPath, Result);
|
||||||
|
MessageBoxW(0, MessageBuf, L"TRACE", MB_OK);
|
||||||
|
#endif
|
||||||
|
if (ERROR_SUCCESS != Result)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD InstallJunctions(int Argc, PWSTR *Argv)
|
||||||
|
{
|
||||||
|
return InstallSymlinks(Argc, Argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD RemoveFiles(int Argc, PWSTR *Argv)
|
||||||
|
{
|
||||||
|
/* usage: RemoveFiles Dir Name... */
|
||||||
|
|
||||||
|
DWORD Result;
|
||||||
|
PWSTR Dir;
|
||||||
|
WCHAR Path[MAX_PATH];
|
||||||
|
int DirLen, Len;
|
||||||
|
|
||||||
|
if (3 > Argc)
|
||||||
|
{
|
||||||
|
Result = ERROR_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dir = Argv[1];
|
||||||
|
DirLen = lstrlenW(Dir);
|
||||||
|
|
||||||
|
for (int Argi = 2; Argc > Argi; Argi++)
|
||||||
|
{
|
||||||
|
Len = lstrlenW(Argv[Argi]);
|
||||||
|
if (MAX_PATH < DirLen + Len + 1)
|
||||||
|
{
|
||||||
|
Result = ERROR_FILENAME_EXCED_RANGE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(Path, Dir, DirLen * sizeof(WCHAR));
|
||||||
|
memcpy(Path + DirLen, Argv[Argi], Len * sizeof(WCHAR));
|
||||||
|
Path[DirLen + Len] = L'\0';
|
||||||
|
|
||||||
|
Result = RemoveFile(Path);
|
||||||
|
#if 0
|
||||||
|
WCHAR MessageBuf[1024];
|
||||||
|
wsprintfW(MessageBuf, L"RemoveFile(\"%s\") = %lu", Path, Result);
|
||||||
|
MessageBoxW(0, MessageBuf, L"TRACE", MB_OK);
|
||||||
|
#endif
|
||||||
|
if (ERROR_SUCCESS != Result)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD MakeSymlink(PWSTR Symlink, PWSTR Target)
|
||||||
|
{
|
||||||
|
DWORD Result;
|
||||||
|
DWORD FileAttributes, Flags;
|
||||||
|
|
||||||
|
RemoveFile(Symlink);
|
||||||
|
|
||||||
|
FileAttributes = GetFileAttributesW(Target);
|
||||||
|
if (INVALID_FILE_ATTRIBUTES == FileAttributes)
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
Flags = 0 != (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
|
||||||
|
|
||||||
|
if (!CreateSymbolicLinkW(Symlink, Target, Flags))
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
RemoveFile(Symlink);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD MakeJunction(PWSTR Junction, PWSTR Target)
|
||||||
|
{
|
||||||
|
DWORD Result;
|
||||||
|
DWORD FileAttributes;
|
||||||
|
|
||||||
|
RemoveFile(Junction);
|
||||||
|
|
||||||
|
FileAttributes = GetFileAttributesW(Target);
|
||||||
|
if (INVALID_FILE_ATTRIBUTES == FileAttributes)
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (0 == (FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
|
Result = ERROR_DIRECTORY;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = CreateJunction(Junction, Target);
|
||||||
|
if (ERROR_SUCCESS != Result)
|
||||||
|
{
|
||||||
|
RemoveFile(Junction);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD CreateJunction(PWSTR Junction, PWSTR Target)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The REPARSE_DATA_BUFFER definitions appear to be missing from the user mode headers.
|
||||||
|
*/
|
||||||
|
typedef struct _REPARSE_DATA_BUFFER
|
||||||
|
{
|
||||||
|
ULONG ReparseTag;
|
||||||
|
USHORT ReparseDataLength;
|
||||||
|
USHORT Reserved;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
USHORT SubstituteNameOffset;
|
||||||
|
USHORT SubstituteNameLength;
|
||||||
|
USHORT PrintNameOffset;
|
||||||
|
USHORT PrintNameLength;
|
||||||
|
ULONG Flags;
|
||||||
|
WCHAR PathBuffer[1];
|
||||||
|
} SymbolicLinkReparseBuffer;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
USHORT SubstituteNameOffset;
|
||||||
|
USHORT SubstituteNameLength;
|
||||||
|
USHORT PrintNameOffset;
|
||||||
|
USHORT PrintNameLength;
|
||||||
|
WCHAR PathBuffer[1];
|
||||||
|
} MountPointReparseBuffer;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR DataBuffer[1];
|
||||||
|
} GenericReparseBuffer;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||||
|
const LONG REPARSE_DATA_BUFFER_HEADER_SIZE =
|
||||||
|
FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer);
|
||||||
|
const DWORD FSCTL_SET_REPARSE_POINT = 0x000900a4;
|
||||||
|
|
||||||
|
DWORD Result;
|
||||||
|
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||||
|
USHORT TargetLength, ReparseDataLength;
|
||||||
|
PREPARSE_DATA_BUFFER ReparseData = 0;
|
||||||
|
PWSTR PathBuffer;
|
||||||
|
DWORD Bytes;
|
||||||
|
|
||||||
|
if (!(
|
||||||
|
((L'A' <= Target[0] && Target[0] <= L'Z') || (L'a' <= Target[0] && Target[0] <= L'z')) &&
|
||||||
|
L':' == Target[1]
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Result = ERROR_INVALID_NAME;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle = CreateFileW(Junction,
|
||||||
|
FILE_WRITE_ATTRIBUTES,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
0,
|
||||||
|
CREATE_NEW,
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY |
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == Handle)
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetLength = (USHORT)lstrlenW(Target) * sizeof(WCHAR);
|
||||||
|
ReparseDataLength = (USHORT)(
|
||||||
|
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) -
|
||||||
|
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer)) +
|
||||||
|
4 * sizeof(WCHAR) + 2 * (TargetLength + sizeof(WCHAR));
|
||||||
|
ReparseData = (PREPARSE_DATA_BUFFER)
|
||||||
|
HeapAlloc(GetProcessHeap(), 0, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseDataLength);
|
||||||
|
if (0 == ReparseData)
|
||||||
|
{
|
||||||
|
Result = ERROR_NO_SYSTEM_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||||
|
ReparseData->ReparseDataLength = ReparseDataLength;
|
||||||
|
ReparseData->Reserved = 0;
|
||||||
|
ReparseData->MountPointReparseBuffer.SubstituteNameOffset = 0;
|
||||||
|
ReparseData->MountPointReparseBuffer.SubstituteNameLength =
|
||||||
|
4 * sizeof(WCHAR) + TargetLength;
|
||||||
|
ReparseData->MountPointReparseBuffer.PrintNameOffset =
|
||||||
|
ReparseData->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR);
|
||||||
|
ReparseData->MountPointReparseBuffer.PrintNameLength =
|
||||||
|
TargetLength;
|
||||||
|
|
||||||
|
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer;
|
||||||
|
PathBuffer[0] = L'\\';
|
||||||
|
PathBuffer[1] = L'?';
|
||||||
|
PathBuffer[2] = L'?';
|
||||||
|
PathBuffer[3] = L'\\';
|
||||||
|
memcpy(PathBuffer + 4, Target, TargetLength);
|
||||||
|
PathBuffer[4 + TargetLength / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
|
PathBuffer = ReparseData->MountPointReparseBuffer.PathBuffer +
|
||||||
|
(ReparseData->MountPointReparseBuffer.PrintNameOffset) / sizeof(WCHAR);
|
||||||
|
memcpy(PathBuffer, Target, TargetLength);
|
||||||
|
PathBuffer[TargetLength / sizeof(WCHAR)] = L'\0';
|
||||||
|
|
||||||
|
if (!DeviceIoControl(Handle, FSCTL_SET_REPARSE_POINT,
|
||||||
|
ReparseData, REPARSE_DATA_BUFFER_HEADER_SIZE + ReparseData->ReparseDataLength,
|
||||||
|
0, 0,
|
||||||
|
&Bytes, 0))
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle)
|
||||||
|
CloseHandle(Handle);
|
||||||
|
|
||||||
|
if (0 != ReparseData)
|
||||||
|
HeapFree(GetProcessHeap(), 0, ReparseData);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD RemoveFile(PWSTR FileName)
|
||||||
|
{
|
||||||
|
DWORD Result;
|
||||||
|
|
||||||
|
if (!RemoveDirectoryW(FileName))
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
if (ERROR_DIRECTORY != Result)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (!DeleteFileW(FileName))
|
||||||
|
{
|
||||||
|
Result = GetLastError();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
||||||
{
|
{
|
||||||
switch(Reason)
|
switch(Reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
DllInstance = Instance;
|
||||||
WcaGlobalInitialize(Instance);
|
WcaGlobalInitialize(Instance);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
|
@ -1,2 +1,7 @@
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
|
InstanceID
|
||||||
ServiceRunning
|
ServiceRunning
|
||||||
|
DeferredAction
|
||||||
|
InstallSymlinks
|
||||||
|
InstallJunctions
|
||||||
|
RemoveFiles
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- The UpgradeCode of the old WinFsp installer that did not support upgrades. -->
|
||||||
|
<?define OldVersionUpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B"?>
|
||||||
|
|
||||||
<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">
|
xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension">
|
||||||
<Product
|
<Product
|
||||||
@ -7,7 +11,7 @@
|
|||||||
Manufacturer="$(var.MyCompanyName)"
|
Manufacturer="$(var.MyCompanyName)"
|
||||||
Version="$(var.MyVersion)"
|
Version="$(var.MyVersion)"
|
||||||
Language="1033"
|
Language="1033"
|
||||||
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B">
|
UpgradeCode="5466A3D8-3AA1-4240-B6A0-3A051940A3EC">
|
||||||
|
|
||||||
<Package
|
<Package
|
||||||
Description="$(var.MyProductName) - $(var.MyDescription)"
|
Description="$(var.MyProductName) - $(var.MyDescription)"
|
||||||
@ -15,13 +19,26 @@
|
|||||||
Compressed="yes"
|
Compressed="yes"
|
||||||
InstallScope="perMachine" />
|
InstallScope="perMachine" />
|
||||||
<MajorUpgrade
|
<MajorUpgrade
|
||||||
Disallow="yes"
|
Disallow="no"
|
||||||
AllowDowngrades="no"
|
AllowDowngrades="no"
|
||||||
AllowSameVersionUpgrades="no"
|
AllowSameVersionUpgrades="yes"
|
||||||
DisallowUpgradeErrorMessage="An older version of $(var.MyProductName) is already installed. You must uninstall it before you can install this version."
|
|
||||||
DowngradeErrorMessage="A newer version of $(var.MyProductName) is already installed." />
|
DowngradeErrorMessage="A newer version of $(var.MyProductName) is already installed." />
|
||||||
<Media Id="1" Cabinet="$(var.MyProductName).cab" EmbedCab="yes" />
|
<Media Id="1" Cabinet="$(var.MyProductName).cab" EmbedCab="yes" />
|
||||||
|
|
||||||
|
<!-- Determine if we are on Win7 or above. -->
|
||||||
|
<Condition Message="$(var.MyProductName) requires Windows version 7 or higher in order to be installed.">
|
||||||
|
<![CDATA[Installed OR (VersionNT >= 601)]]>
|
||||||
|
</Condition>
|
||||||
|
|
||||||
|
<!-- Determine if the old WinFsp installer that did not support upgrades is installed. -->
|
||||||
|
<Property Id="OLDVERSIONINSTALLED">
|
||||||
|
<ProductSearch UpgradeCode="$(var.OldVersionUpgradeCode)" Minimum="0.0.0.0" />
|
||||||
|
</Property>
|
||||||
|
<Condition Message="An older version of $(var.MyProductName) that cannot be upgraded is already installed. You must uninstall it before you can install this version.">
|
||||||
|
NOT OLDVERSIONINSTALLED
|
||||||
|
</Condition>
|
||||||
|
|
||||||
|
<!-- Determine OS architecture. -->
|
||||||
<Property Id="OSARCH" Secure="yes" Value="AMD64">
|
<Property Id="OSARCH" Secure="yes" Value="AMD64">
|
||||||
<RegistrySearch
|
<RegistrySearch
|
||||||
Id="R.OSARCH"
|
Id="R.OSARCH"
|
||||||
@ -31,10 +48,10 @@
|
|||||||
Type="raw" />
|
Type="raw" />
|
||||||
</Property>
|
</Property>
|
||||||
|
|
||||||
<Property Id="P.LauncherName">$(var.MyProductName).Launcher</Property>
|
<!-- Setup INSTALLDIR and SXSDIR from the registry or defaults. -->
|
||||||
<Property Id="P.LauncherRegistryKey">Software\$(var.MyProductName)\Services</Property>
|
|
||||||
<Property Id="P.RegistryKey">Software\$(var.MyProductName)</Property>
|
<Property Id="P.RegistryKey">Software\$(var.MyProductName)</Property>
|
||||||
<Property Id="INSTALLDIR">
|
<Property Id="P.LauncherRegistryKey">Software\$(var.MyProductName)\Services</Property>
|
||||||
|
<Property Id="INSTALLDIR" Secure="yes">
|
||||||
<RegistrySearch
|
<RegistrySearch
|
||||||
Id="R.INSTALLDIR"
|
Id="R.INSTALLDIR"
|
||||||
Root="HKLM"
|
Root="HKLM"
|
||||||
@ -42,22 +59,40 @@
|
|||||||
Name="InstallDir"
|
Name="InstallDir"
|
||||||
Type="raw" />
|
Type="raw" />
|
||||||
</Property>
|
</Property>
|
||||||
|
<Property Id="SXSDIR" Secure="yes">
|
||||||
|
<RegistrySearch
|
||||||
|
Id="R.SXSDIR"
|
||||||
|
Root="HKLM"
|
||||||
|
Key="[P.RegistryKey]"
|
||||||
|
Name="SxsDir"
|
||||||
|
Type="raw" />
|
||||||
|
</Property>
|
||||||
|
<SetProperty Id="INSTALLDIR" Value="[ProgramFilesFolder]$(var.MyProductName)\" After="CostInitialize">
|
||||||
|
NOT INSTALLDIR
|
||||||
|
</SetProperty>
|
||||||
|
<SetProperty Id="SXSDIR" Value="[INSTALLDIR]SxS\sxs.[InstanceID]\" After="SetINSTALLDIR">
|
||||||
|
((NOT SXSDIR) OR WIX_UPGRADE_DETECTED) AND InstanceID
|
||||||
|
</SetProperty>
|
||||||
|
|
||||||
|
<!-- Setup directory structure. -->
|
||||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||||
<Directory Id="ProgramFilesFolder">
|
<Directory Id="ProgramFilesFolder">
|
||||||
<Directory Id="INSTALLDIR" Name="$(var.MyProductName)">
|
<Directory Id="INSTALLDIR" Name="DYNAMIC">
|
||||||
|
<Directory Id="SXSBASEDIR" Name="SxS">
|
||||||
|
<Directory Id="SXSDIR" Name="DYNAMIC">
|
||||||
<Directory Id="BINDIR" Name="bin" />
|
<Directory Id="BINDIR" Name="bin" />
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
<Directory Id="INCDIR" Name="inc" />
|
<Directory Id="INCDIR" Name="inc" />
|
||||||
<Directory Id="LIBDIR" Name="lib" />
|
<Directory Id="LIBDIR" Name="lib" />
|
||||||
<Directory Id="OPTDIR" Name="opt" />
|
<Directory Id="OPTDIR" Name="opt" />
|
||||||
<Directory Id="SMPDIR" Name="samples" />
|
<Directory Id="SMPDIR" Name="samples" />
|
||||||
<Directory Id="SYMDIR" Name="sym" />
|
|
||||||
</Directory>
|
</Directory>
|
||||||
</Directory>
|
</Directory>
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
<DirectoryRef Id="INSTALLDIR">
|
<DirectoryRef Id="INSTALLDIR">
|
||||||
<Component Id="C.INSTALLDIR" Guid="{F876F26E-5016-4AC6-93B3-653C0312A6CE}">
|
<Component Id="C.INSTALLDIR" Guid="C086521F-8552-43D1-AAE2-CDD579F66FDD">
|
||||||
<RegistryValue
|
<RegistryValue
|
||||||
Root="HKLM"
|
Root="HKLM"
|
||||||
Key="[P.RegistryKey]"
|
Key="[P.RegistryKey]"
|
||||||
@ -70,6 +105,17 @@
|
|||||||
<File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" />
|
<File Name="License.txt" Source="..\..\..\License.txt" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</DirectoryRef>
|
</DirectoryRef>
|
||||||
|
<DirectoryRef Id="SXSDIR">
|
||||||
|
<Component Id="C.SXSDIR" Guid="0F09CD39-1137-4DB8-A783-27B1F51353D1">
|
||||||
|
<RegistryValue
|
||||||
|
Root="HKLM"
|
||||||
|
Key="[P.RegistryKey]"
|
||||||
|
Name="SxsDir"
|
||||||
|
Type="string"
|
||||||
|
Value="[SXSDIR]"
|
||||||
|
KeyPath="yes" />
|
||||||
|
</Component>
|
||||||
|
</DirectoryRef>
|
||||||
<DirectoryRef Id="BINDIR" FileSource="..\build\$(var.Configuration)">
|
<DirectoryRef Id="BINDIR" FileSource="..\build\$(var.Configuration)">
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.sys">
|
<Component Id="C.$(var.MyProductFileName)_a64.sys">
|
||||||
<File Name="$(var.MyProductFileName)-a64.sys" KeyPath="yes" />
|
<File Name="$(var.MyProductFileName)-a64.sys" KeyPath="yes" />
|
||||||
@ -82,56 +128,56 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On WinArm64 register $(var.MyProductFileName)-a64.dll -->
|
<!-- On WinArm64 register $(var.MyProductFileName)-a64.dll -->
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.dll.a64" Guid="86FB483B-0910-458E-93B4-3CCB66D27AF0">
|
<Component Id="C.$(var.MyProductFileName)_a64.dll.a64" Guid="2A7E68EB-D05F-4DD8-ABF2-EB8CB09697F0">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_a64.dll.a64" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" SelfRegCost="1" />
|
<File Id="FILE.$(var.MyProductFileName)_a64.dll.a64" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" SelfRegCost="1" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x64.dll.a64" Guid="941FAE3E-A650-4BAC-97F5-F8C6E98DB5D2">
|
<Component Id="C.$(var.MyProductFileName)_x64.dll.a64" Guid="EA5ED4FB-FC72-4D27-9802-88D84DAE61B4">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x64.dll.a64" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_x64.dll.a64" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x86.dll.a64" Guid="C312214D-F9A3-40EB-B2C3-4FAF5BF3F938">
|
<Component Id="C.$(var.MyProductFileName)_x86.dll.a64" Guid="2A9BD712-2F96-4794-8A58-929E39F3F3CC">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x86.dll.a64" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_x86.dll.a64" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win64 register $(var.MyProductFileName)-x64.dll -->
|
<!-- On Win64 register $(var.MyProductFileName)-x64.dll -->
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.dll.x64" Guid="4ABB46C2-A8E3-49E8-B051-05DBF2B351AE">
|
<Component Id="C.$(var.MyProductFileName)_a64.dll.x64" Guid="026DA201-43E1-450C-9687-8A684FBF2D2D">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_a64.dll.x64" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_a64.dll.x64" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x64.dll.x64" Guid="F0A67746-1A9C-4976-8EC0-882E9407FA6D">
|
<Component Id="C.$(var.MyProductFileName)_x64.dll.x64" Guid="89201BAF-5812-4ECE-91CD-12EDFFF11CB1">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x64.dll.x64" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" SelfRegCost="1" />
|
<File Id="FILE.$(var.MyProductFileName)_x64.dll.x64" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" SelfRegCost="1" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x86.dll.x64" Guid="950492FB-12F7-4E27-9124-8325A2BC9927">
|
<Component Id="C.$(var.MyProductFileName)_x86.dll.x64" Guid="E6EE48A4-6BC7-4135-9A2F-FBBA30DE80BE">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x86.dll.x64" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_x86.dll.x64" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win32 register $(var.MyProductFileName)-x86.dll -->
|
<!-- On Win32 register $(var.MyProductFileName)-x86.dll -->
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.dll.x86" Guid="071C0EB2-A0EB-46A1-B5B0-124F60ECD6B3">
|
<Component Id="C.$(var.MyProductFileName)_a64.dll.x86" Guid="2B264958-DECC-4B32-9BB2-DE32D6B6BE77">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_a64.dll.x86" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_a64.dll.x86" Name="$(var.MyProductFileName)-a64.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x64.dll.x86" Guid="4D6E7A8E-0CA6-49BE-B312-1EDADE725756">
|
<Component Id="C.$(var.MyProductFileName)_x64.dll.x86" Guid="29FB908F-1D36-4789-9778-4CE2E9C19CEA">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x64.dll.x86" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_x64.dll.x86" Name="$(var.MyProductFileName)-x64.dll" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_x86.dll.x86" Guid="F0DEF7A6-AF55-419F-A58A-DF4018C6FA73">
|
<Component Id="C.$(var.MyProductFileName)_x86.dll.x86" Guid="80E87D91-69A8-4942-ABC1-36652B1CA700">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_x86.dll.x86" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" SelfRegCost="1" />
|
<File Id="FILE.$(var.MyProductFileName)_x86.dll.x86" Name="$(var.MyProductFileName)-x86.dll" KeyPath="yes" SelfRegCost="1" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- install assembly -->
|
<!-- install assembly -->
|
||||||
<Component Id="C.$(var.MyProductFileName)_msil.dll" Guid="0D8BA6AE-9F87-402B-AE1A-95B0AE3BE179">
|
<Component Id="C.$(var.MyProductFileName)_msil.dll" Guid="1772CDE5-4B2F-48CF-B2DA-CA43818053A8">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_msil.dll" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_msil.dll" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.$(var.MyProductFileName)_msil.xml" Guid="1657F707-C112-454C-91AE-0FDEBBF454AB">
|
<Component Id="C.$(var.MyProductFileName)_msil.xml" Guid="C76745D2-51FA-4028-B827-3F2F3F763751">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_msil.xml" Name="$(var.MyProductFileName)-msil.xml" KeyPath="yes" />
|
<File Id="FILE.$(var.MyProductFileName)_msil.xml" Name="$(var.MyProductFileName)-msil.xml" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<!--
|
<!--
|
||||||
<Component Id="C.$(var.MyProductFileName)_msil.dll.GAC" Guid="6469467D-8C90-4889-8138-4028F9DA6E85">
|
<Component Id="C.$(var.MyProductFileName)_msil.dll.GAC" Guid="D86F8764-2FCC-43DA-A174-23E0FD6D45B7">
|
||||||
<File Id="FILE.$(var.MyProductFileName)_msil.dll.GAC" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" Assembly=".net" />
|
<File Id="FILE.$(var.MyProductFileName)_msil.dll.GAC" Name="$(var.MyProductFileName)-msil.dll" KeyPath="yes" Assembly=".net" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.policy.$(var.MyProductFileName)_msil.dll.GAC">
|
<Component Id="C.policy.$(var.MyProductFileName)_msil.dll.GAC">
|
||||||
@ -141,103 +187,103 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- On WinArm64 ServiceInstall launcher-a64.exe -->
|
<!-- On WinArm64 ServiceInstall launcher-a64.exe -->
|
||||||
<Component Id="C.launcher_a64.exe.a64" Guid="E37E6D75-C44B-4189-8E86-CE5A3E0B0626">
|
<Component Id="C.launcher_a64.exe.a64" Guid="D8B657EA-7B08-48D1-B5F7-76CFB68E1BD5">
|
||||||
<File Id="FILE.launcher_a64.exe.a64" Name="launcher-a64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_a64.exe.a64" Name="launcher-a64.exe" KeyPath="yes" />
|
||||||
<ServiceInstall
|
<ServiceInstall
|
||||||
Id="launcher_a64.exe.a64"
|
Id="launcher_a64.exe.a64"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Description="$(var.MyDescription)"
|
Description="$(var.MyDescription)"
|
||||||
Type="ownProcess"
|
Type="ownProcess"
|
||||||
Start="auto"
|
Start="auto"
|
||||||
ErrorControl="ignore" />
|
ErrorControl="ignore" />
|
||||||
<ServiceControl
|
<ServiceControl
|
||||||
Id="launcher_a64.exe.a64"
|
Id="launcher_a64.exe.a64"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Start="install"
|
Start="install"
|
||||||
Stop="both"
|
Stop="both"
|
||||||
Remove="uninstall" />
|
Remove="uninstall" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x64.exe.a64" Guid="CF5F3EEE-F739-4F50-9938-13C0D2CD9C7A">
|
<Component Id="C.launcher_x64.exe.a64" Guid="3EFC0561-6EA2-4E7E-B707-C2EA706CFBA0">
|
||||||
<File Id="FILE.launcher_x64.exe.a64" Name="launcher-x64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x64.exe.a64" Name="launcher-x64.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x86.exe.a64" Guid="D5E9FF96-9E00-46BA-8719-BC49CF35BBE6">
|
<Component Id="C.launcher_x86.exe.a64" Guid="69F16682-10AE-4FC4-9007-8D80CE0D8388">
|
||||||
<File Id="FILE.launcher_x86.exe.a64" Name="launcher-x86.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x86.exe.a64" Name="launcher-x86.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "ARM64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win64 ServiceInstall launcher-x64.exe -->
|
<!-- On Win64 ServiceInstall launcher-x64.exe -->
|
||||||
<Component Id="C.launcher_a64.exe.x64" Guid="10A3F0F9-6555-4071-9C93-EA50E4B3F115">
|
<Component Id="C.launcher_a64.exe.x64" Guid="29760ACE-69CD-4061-8C0C-8A6E72D23A45">
|
||||||
<File Id="FILE.launcher_a64.exe.x64" Name="launcher-a64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_a64.exe.x64" Name="launcher-a64.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x64.exe.x64" Guid="2AB4E729-F7CB-4B4A-BE81-6C0C3B3194FC">
|
<Component Id="C.launcher_x64.exe.x64" Guid="36ACBA60-1C92-4D2A-B497-CD4FB13A042F">
|
||||||
<File Id="FILE.launcher_x64.exe.x64" Name="launcher-x64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x64.exe.x64" Name="launcher-x64.exe" KeyPath="yes" />
|
||||||
<ServiceInstall
|
<ServiceInstall
|
||||||
Id="launcher_x64.exe.x64"
|
Id="launcher_x64.exe.x64"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Description="$(var.MyDescription)"
|
Description="$(var.MyDescription)"
|
||||||
Type="ownProcess"
|
Type="ownProcess"
|
||||||
Start="auto"
|
Start="auto"
|
||||||
ErrorControl="ignore" />
|
ErrorControl="ignore" />
|
||||||
<ServiceControl
|
<ServiceControl
|
||||||
Id="launcher_x64.exe.x64"
|
Id="launcher_x64.exe.x64"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Start="install"
|
Start="install"
|
||||||
Stop="both"
|
Stop="both"
|
||||||
Remove="uninstall" />
|
Remove="uninstall" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x86.exe.x64" Guid="C5B6D411-8A6A-4944-8C4F-7D9FB9A72826">
|
<Component Id="C.launcher_x86.exe.x64" Guid="98F17F67-AC1D-4E16-A147-B7AE113E3CB3">
|
||||||
<File Id="FILE.launcher_x86.exe.x64" Name="launcher-x86.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x86.exe.x64" Name="launcher-x86.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
<Condition><![CDATA[OSARCH = "AMD64"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win32 ServiceInstall launcher-x86.exe -->
|
<!-- On Win32 ServiceInstall launcher-x86.exe -->
|
||||||
<Component Id="C.launcher_a64.exe.x86" Guid="5048AEF5-9DE2-406E-A2EA-F237BAD13286">
|
<Component Id="C.launcher_a64.exe.x86" Guid="9024A9FE-7445-4241-ADA3-82A57C92719A">
|
||||||
<File Id="FILE.launcher_a64.exe.x86" Name="launcher-a64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_a64.exe.x86" Name="launcher-a64.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x64.exe.x86" Guid="88CDBE92-8B67-485A-838F-FA4AD37F306F">
|
<Component Id="C.launcher_x64.exe.x86" Guid="A85DA9CD-26AA-460E-950D-CA9692B87465">
|
||||||
<File Id="FILE.launcher_x64.exe.x86" Name="launcher-x64.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x64.exe.x86" Name="launcher-x64.exe" KeyPath="yes" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launcher_x86.exe.x86" Guid="E995D906-0273-4758-9B26-99A3A8CD143A">
|
<Component Id="C.launcher_x86.exe.x86" Guid="01FCCF6B-9F4B-4F29-8149-489470FFD449">
|
||||||
<File Id="FILE.launcher_x86.exe.x86" Name="launcher-x86.exe" KeyPath="yes" />
|
<File Id="FILE.launcher_x86.exe.x86" Name="launcher-x86.exe" KeyPath="yes" />
|
||||||
<ServiceInstall
|
<ServiceInstall
|
||||||
Id="launcher_x86.exe.x86"
|
Id="launcher_x86.exe.x86"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Description="$(var.MyDescription)"
|
Description="$(var.MyDescription)"
|
||||||
Type="ownProcess"
|
Type="ownProcess"
|
||||||
Start="auto"
|
Start="auto"
|
||||||
ErrorControl="ignore" />
|
ErrorControl="ignore" />
|
||||||
<ServiceControl
|
<ServiceControl
|
||||||
Id="launcher_x86.exe.x86"
|
Id="launcher_x86.exe.x86"
|
||||||
Name="[P.LauncherName]"
|
Name="$(var.MyProductName).Launcher"
|
||||||
Start="install"
|
Start="install"
|
||||||
Stop="both"
|
Stop="both"
|
||||||
Remove="uninstall" />
|
Remove="uninstall" />
|
||||||
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
<Condition><![CDATA[OSARCH = "x86"]]></Condition>
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<Component Id="C.launchctl_a64.exe" Guid="B9B5CF8E-317D-40EE-A208-BC46A2A99BAB">
|
<Component Id="C.launchctl_a64.exe" Guid="A7D830DD-20D2-48BF-85B6-E306BCCAFD2D">
|
||||||
<File Name="launchctl-a64.exe" KeyPath="yes" />
|
<File Name="launchctl-a64.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launchctl_x64.exe" Guid="2753623B-66F1-4514-B9C7-F879178DFF49">
|
<Component Id="C.launchctl_x64.exe" Guid="CCC8974A-4CD0-443E-840D-1C92535BBD04">
|
||||||
<File Name="launchctl-x64.exe" KeyPath="yes" />
|
<File Name="launchctl-x64.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.launchctl_x86.exe" Guid="EBDEC4FB-07BB-47CA-BFFF-EB854CA2D22D">
|
<Component Id="C.launchctl_x86.exe" Guid="6E382342-10D4-4274-8FA9-F1B44C40C277">
|
||||||
<File Name="launchctl-x86.exe" KeyPath="yes" />
|
<File Name="launchctl-x86.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<Component Id="C.fsptool_a64.exe" Guid="F75A8B14-000C-4933-AD83-EC0D1D3AD3CA">
|
<Component Id="C.fsptool_a64.exe" Guid="8ACEB970-CAD5-491D-8CE8-12675CC0E812">
|
||||||
<File Name="fsptool-a64.exe" KeyPath="yes" />
|
<File Name="fsptool-a64.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.fsptool_x64.exe" Guid="013FE508-097D-4433-9C60-717F5446E7F4">
|
<Component Id="C.fsptool_x64.exe" Guid="35EE49E2-9565-4FA2-A0AC-D51FD94FA380">
|
||||||
<File Name="fsptool-x64.exe" KeyPath="yes" />
|
<File Name="fsptool-x64.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
<Component Id="C.fsptool_x86.exe" Guid="6C16DC2C-E12F-49FB-A665-3AF0475487AD">
|
<Component Id="C.fsptool_x86.exe" Guid="0E6D5742-D500-4E24-A0FA-E6316DB70D8B">
|
||||||
<File Name="fsptool-x86.exe" KeyPath="yes" />
|
<File Name="fsptool-x86.exe" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
@ -409,7 +455,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On WinArm64 copy fuse-a64.pc -->
|
<!-- On WinArm64 copy fuse-a64.pc -->
|
||||||
<Component Id="C.fuse_a64.pc" Guid="74E6E9BD-AF16-4635-AE52-84B33E4E196E">
|
<Component Id="C.fuse_a64.pc" Guid="776C28B5-DA1A-4EB6-96E6-3D22FE1573AC">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse_a64.pc"
|
Id="FILE.fuse_a64.pc"
|
||||||
Name="fuse.pc"
|
Name="fuse.pc"
|
||||||
@ -419,7 +465,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win64 copy fuse-x64.pc -->
|
<!-- On Win64 copy fuse-x64.pc -->
|
||||||
<Component Id="C.fuse_x64.pc" Guid="407395D2-D076-411E-B1D0-D97E21E11A3C">
|
<Component Id="C.fuse_x64.pc" Guid="89D39F6E-2994-4E6F-ACB6-5B544057C051">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse_x64.pc"
|
Id="FILE.fuse_x64.pc"
|
||||||
Name="fuse.pc"
|
Name="fuse.pc"
|
||||||
@ -429,7 +475,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win32 copy fuse-x86.pc -->
|
<!-- On Win32 copy fuse-x86.pc -->
|
||||||
<Component Id="C.fuse_x86.pc" Guid="0568EBCB-782E-4C17-9B64-BAFCC43F64ED">
|
<Component Id="C.fuse_x86.pc" Guid="75637ECD-B3EC-4A19-98B7-9AFAB0722D9A">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse_x86.pc"
|
Id="FILE.fuse_x86.pc"
|
||||||
Name="fuse.pc"
|
Name="fuse.pc"
|
||||||
@ -439,7 +485,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On WinArm64 copy fuse3-x64.pc -->
|
<!-- On WinArm64 copy fuse3-x64.pc -->
|
||||||
<Component Id="C.fuse3_a64.pc" Guid="2B6444DB-25E5-45B4-BC61-157D3B992F2B">
|
<Component Id="C.fuse3_a64.pc" Guid="5A69B633-11E4-46E4-8D08-BED1BE7BF4F0">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse3_a64.pc"
|
Id="FILE.fuse3_a64.pc"
|
||||||
Name="fuse3.pc"
|
Name="fuse3.pc"
|
||||||
@ -449,7 +495,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win64 copy fuse3-x64.pc -->
|
<!-- On Win64 copy fuse3-x64.pc -->
|
||||||
<Component Id="C.fuse3_x64.pc" Guid="FE59E3BA-E5EA-4822-80B1-19A1DE6B62C7">
|
<Component Id="C.fuse3_x64.pc" Guid="EEAF35B5-5D6C-47D6-BEE3-5E44DD5A294B">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse3_x64.pc"
|
Id="FILE.fuse3_x64.pc"
|
||||||
Name="fuse3.pc"
|
Name="fuse3.pc"
|
||||||
@ -459,7 +505,7 @@
|
|||||||
</Component>
|
</Component>
|
||||||
|
|
||||||
<!-- On Win32 copy fuse3-x86.pc -->
|
<!-- On Win32 copy fuse3-x86.pc -->
|
||||||
<Component Id="C.fuse3_x86.pc" Guid="176205D0-07EA-4DFC-947F-18E89ABDAFAB">
|
<Component Id="C.fuse3_x86.pc" Guid="476CF5E5-2B8E-4D75-B1A5-FFA8C3DAECB2">
|
||||||
<File
|
<File
|
||||||
Id="FILE.fuse3_x86.pc"
|
Id="FILE.fuse3_x86.pc"
|
||||||
Name="fuse3.pc"
|
Name="fuse3.pc"
|
||||||
@ -737,62 +783,6 @@
|
|||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
</DirectoryRef>
|
</DirectoryRef>
|
||||||
<DirectoryRef Id="SYMDIR">
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.sys.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-a64.sys.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-a64.sys.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_x64.sys.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-x64.sys.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x64.sys.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_x86.sys.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-x86.sys.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x86.sys.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_a64.dll.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-a64.dll.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-a64.dll.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_x64.dll.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-x64.dll.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x64.dll.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.$(var.MyProductFileName)_x86.dll.pdb">
|
|
||||||
<File Name="$(var.MyProductFileName)-x86.dll.pdb" Source="..\build\$(var.Configuration)\$(var.MyProductFileName)-x86.dll.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launcher_a64.pdb">
|
|
||||||
<File Name="launcher-a64.pdb" Source="..\build\$(var.Configuration)\launcher-a64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launcher_x64.pdb">
|
|
||||||
<File Name="launcher-x64.pdb" Source="..\build\$(var.Configuration)\launcher-x64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launcher_x86.pdb">
|
|
||||||
<File Name="launcher-x86.pdb" Source="..\build\$(var.Configuration)\launcher-x86.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launchctl_a64.pdb">
|
|
||||||
<File Name="launchctl-a64.pdb" Source="..\build\$(var.Configuration)\launchctl-a64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launchctl_x64.pdb">
|
|
||||||
<File Name="launchctl-x64.pdb" Source="..\build\$(var.Configuration)\launchctl-x64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.launchctl_x86.pdb">
|
|
||||||
<File Name="launchctl-x86.pdb" Source="..\build\$(var.Configuration)\launchctl-x86.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.fsptool_a64.pdb">
|
|
||||||
<File Name="fsptool-a64.pdb" Source="..\build\$(var.Configuration)\fsptool-a64.public.pdb" KeyPath="yes" />
|
|
||||||
</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_a64.pdb">
|
|
||||||
<File Name="memfs-a64.pdb" Source="..\build\$(var.Configuration)\memfs-a64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.memfs_x64.pdb">
|
|
||||||
<File Name="memfs-x64.pdb" Source="..\build\$(var.Configuration)\memfs-x64.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
<Component Id="C.memfs_x86.pdb">
|
|
||||||
<File Name="memfs-x86.pdb" Source="..\build\$(var.Configuration)\memfs-x86.public.pdb" KeyPath="yes" />
|
|
||||||
</Component>
|
|
||||||
</DirectoryRef>
|
|
||||||
|
|
||||||
<ComponentGroup Id="C.$(var.MyProductName).bin">
|
<ComponentGroup Id="C.$(var.MyProductName).bin">
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_a64.sys" />
|
<ComponentRef Id="C.$(var.MyProductFileName)_a64.sys" />
|
||||||
@ -927,26 +917,6 @@
|
|||||||
<ComponentRef Id="C.notifyfs.vcxproj" />
|
<ComponentRef Id="C.notifyfs.vcxproj" />
|
||||||
<ComponentRef Id="C.notifyfs.vcxproj.filters" />
|
<ComponentRef Id="C.notifyfs.vcxproj.filters" />
|
||||||
</ComponentGroup>
|
</ComponentGroup>
|
||||||
<ComponentGroup Id="C.$(var.MyProductName).sym">
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_a64.sys.pdb" />
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_x64.sys.pdb" />
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_x86.sys.pdb" />
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_a64.dll.pdb" />
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_x64.dll.pdb" />
|
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_x86.dll.pdb" />
|
|
||||||
<ComponentRef Id="C.launcher_a64.pdb" />
|
|
||||||
<ComponentRef Id="C.launcher_x64.pdb" />
|
|
||||||
<ComponentRef Id="C.launcher_x86.pdb" />
|
|
||||||
<ComponentRef Id="C.launchctl_a64.pdb" />
|
|
||||||
<ComponentRef Id="C.launchctl_x64.pdb" />
|
|
||||||
<ComponentRef Id="C.launchctl_x86.pdb" />
|
|
||||||
<ComponentRef Id="C.fsptool_a64.pdb" />
|
|
||||||
<ComponentRef Id="C.fsptool_x64.pdb" />
|
|
||||||
<ComponentRef Id="C.fsptool_x86.pdb" />
|
|
||||||
<ComponentRef Id="C.memfs_a64.pdb" />
|
|
||||||
<ComponentRef Id="C.memfs_x64.pdb" />
|
|
||||||
<ComponentRef Id="C.memfs_x86.pdb" />
|
|
||||||
</ComponentGroup>
|
|
||||||
<ComponentGroup Id="C.$(var.MyProductName).net">
|
<ComponentGroup Id="C.$(var.MyProductName).net">
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_msil.dll" />
|
<ComponentRef Id="C.$(var.MyProductFileName)_msil.dll" />
|
||||||
<ComponentRef Id="C.$(var.MyProductFileName)_msil.xml" />
|
<ComponentRef Id="C.$(var.MyProductFileName)_msil.xml" />
|
||||||
@ -978,6 +948,7 @@
|
|||||||
Absent="disallow">
|
Absent="disallow">
|
||||||
<ComponentRef Id="C.INSTALLDIR" />
|
<ComponentRef Id="C.INSTALLDIR" />
|
||||||
<ComponentRef Id="C.License.txt" />
|
<ComponentRef Id="C.License.txt" />
|
||||||
|
<ComponentRef Id="C.SXSDIR" />
|
||||||
<Feature
|
<Feature
|
||||||
Id="F.User"
|
Id="F.User"
|
||||||
Level="1"
|
Level="1"
|
||||||
@ -1013,7 +984,6 @@
|
|||||||
<ComponentGroupRef Id="C.$(var.MyProductName).lib" />
|
<ComponentGroupRef Id="C.$(var.MyProductName).lib" />
|
||||||
<ComponentGroupRef Id="C.$(var.MyProductName).smp" />
|
<ComponentGroupRef Id="C.$(var.MyProductName).smp" />
|
||||||
<ComponentGroupRef Id="C.$(var.MyProductName).smp.net" />
|
<ComponentGroupRef Id="C.$(var.MyProductName).smp.net" />
|
||||||
<ComponentGroupRef Id="C.$(var.MyProductName).sym" />
|
|
||||||
</Feature>
|
</Feature>
|
||||||
<Feature
|
<Feature
|
||||||
Id="F.KernelDeveloper"
|
Id="F.KernelDeveloper"
|
||||||
@ -1056,7 +1026,24 @@
|
|||||||
Order="10">NOT Installed</Publish>
|
Order="10">NOT Installed</Publish>
|
||||||
</UI>
|
</UI>
|
||||||
|
|
||||||
|
<!-- Custom Actions -->
|
||||||
<Binary Id="CustomActions" SourceFile="..\build\$(var.Configuration)\CustomActions.dll" />
|
<Binary Id="CustomActions" SourceFile="..\build\$(var.Configuration)\CustomActions.dll" />
|
||||||
|
|
||||||
|
<!-- InstanceID computes a unique per-installer-run ID -->
|
||||||
|
<CustomAction
|
||||||
|
Id="Action.InstanceID"
|
||||||
|
BinaryKey="CustomActions"
|
||||||
|
DllEntry="InstanceID"
|
||||||
|
Execute="firstSequence"
|
||||||
|
Return="check" />
|
||||||
|
<InstallExecuteSequence>
|
||||||
|
<Custom Action="Action.InstanceID" Before="AppSearch" />
|
||||||
|
</InstallExecuteSequence>
|
||||||
|
<InstallUISequence>
|
||||||
|
<Custom Action="Action.InstanceID" Before="AppSearch" />
|
||||||
|
</InstallUISequence>
|
||||||
|
|
||||||
|
<!-- ServiceRunning determines if the old driver (that did not support unload) is running. -->
|
||||||
<CustomAction
|
<CustomAction
|
||||||
Id="Params.ServiceRunning"
|
Id="Params.ServiceRunning"
|
||||||
Property="ServiceRunning"
|
Property="ServiceRunning"
|
||||||
@ -1069,16 +1056,109 @@
|
|||||||
Return="ignore" />
|
Return="ignore" />
|
||||||
<CustomAction
|
<CustomAction
|
||||||
Id="Action.ServiceRunning.Error"
|
Id="Action.ServiceRunning.Error"
|
||||||
Error="The $(var.MyProductName) service appears to be running. If you just uninstalled $(var.MyProductName) please restart your computer. If you are running a development version of $(var.MyProductName) please remove it before proceeding." />
|
Error="A component from an older version of $(var.MyProductName) that cannot be upgraded appears to be running. If you just uninstalled an older version of $(var.MyProductName) please restart your computer." />
|
||||||
<InstallExecuteSequence>
|
<InstallExecuteSequence>
|
||||||
<Custom Action="Params.ServiceRunning" Before="Action.ServiceRunning" />
|
<Custom Action="Params.ServiceRunning" Before="Action.ServiceRunning" />
|
||||||
<Custom Action="Action.ServiceRunning" Before="LaunchConditions" />
|
<Custom Action="Action.ServiceRunning" After="LaunchConditions">
|
||||||
|
<![CDATA[NOT Installed]]>
|
||||||
|
</Custom>
|
||||||
<Custom Action="Action.ServiceRunning.Error" After="Action.ServiceRunning">
|
<Custom Action="Action.ServiceRunning.Error" After="Action.ServiceRunning">
|
||||||
<![CDATA[NOT Installed AND (0 <> ServiceRunning)]]>
|
<![CDATA[NOT Installed AND (0 <> ServiceRunning)]]>
|
||||||
</Custom>
|
</Custom>
|
||||||
<ScheduleReboot After="RemoveFiles">
|
|
||||||
<![CDATA[(REMOVE ~= "ALL") AND (0 <> ServiceRunning)]]>
|
|
||||||
</ScheduleReboot>
|
|
||||||
</InstallExecuteSequence>
|
</InstallExecuteSequence>
|
||||||
|
<InstallUISequence>
|
||||||
|
<Custom Action="Params.ServiceRunning" Before="Action.ServiceRunning" />
|
||||||
|
<Custom Action="Action.ServiceRunning" After="LaunchConditions">
|
||||||
|
<![CDATA[NOT Installed]]>
|
||||||
|
</Custom>
|
||||||
|
<Custom Action="Action.ServiceRunning.Error" After="Action.ServiceRunning">
|
||||||
|
<![CDATA[NOT Installed AND (0 <> ServiceRunning)]]>
|
||||||
|
</Custom>
|
||||||
|
</InstallUISequence>
|
||||||
|
|
||||||
|
<!-- InstallSymlinks installs SxS symlinks -->
|
||||||
|
<SetProperty
|
||||||
|
Id="Deferred.InstallSymlinks"
|
||||||
|
Value='InstallJunctions "[INSTALLDIR]\" "[SXSDIR]\" bin'
|
||||||
|
Before="Deferred.InstallSymlinks"
|
||||||
|
Sequence="execute" />
|
||||||
|
<CustomAction
|
||||||
|
Id="Deferred.InstallSymlinks"
|
||||||
|
BinaryKey="CustomActions"
|
||||||
|
DllEntry="DeferredAction"
|
||||||
|
Execute="deferred"
|
||||||
|
Impersonate="no"
|
||||||
|
Return="check" />
|
||||||
|
<SetProperty
|
||||||
|
Id="Rollback.InstallSymlinks"
|
||||||
|
Value='RemoveFiles "[INSTALLDIR]\" bin'
|
||||||
|
Before="Rollback.InstallSymlinks"
|
||||||
|
Sequence="execute" />
|
||||||
|
<CustomAction
|
||||||
|
Id="Rollback.InstallSymlinks"
|
||||||
|
BinaryKey="CustomActions"
|
||||||
|
DllEntry="DeferredAction"
|
||||||
|
Execute="rollback"
|
||||||
|
Impersonate="no"
|
||||||
|
Return="ignore" />
|
||||||
|
<InstallExecuteSequence>
|
||||||
|
<!--
|
||||||
|
deferred: `InstallSymlinks` on install or repair
|
||||||
|
rollback: `RemoveSymlinks` on install only
|
||||||
|
-->
|
||||||
|
<Custom Action="Rollback.InstallSymlinks" After="InstallFiles">
|
||||||
|
NOT Installed
|
||||||
|
</Custom>
|
||||||
|
<Custom Action="Deferred.InstallSymlinks" After="Rollback.InstallSymlinks">
|
||||||
|
(NOT Installed) OR REINSTALL
|
||||||
|
</Custom>
|
||||||
|
</InstallExecuteSequence>
|
||||||
|
|
||||||
|
<!-- RemoveSymlinks removes SxS symlinks -->
|
||||||
|
<SetProperty
|
||||||
|
Id="Deferred.RemoveSymlinks"
|
||||||
|
Value='RemoveFiles "[INSTALLDIR]\" bin'
|
||||||
|
Before="Deferred.RemoveSymlinks"
|
||||||
|
Sequence="execute" />
|
||||||
|
<CustomAction
|
||||||
|
Id="Deferred.RemoveSymlinks"
|
||||||
|
BinaryKey="CustomActions"
|
||||||
|
DllEntry="DeferredAction"
|
||||||
|
Execute="deferred"
|
||||||
|
Impersonate="no"
|
||||||
|
Return="ignore" />
|
||||||
|
<SetProperty
|
||||||
|
Id="Rollback.RemoveSymlinks"
|
||||||
|
Value='InstallJunctions "[INSTALLDIR]\" "[SXSDIR]\" bin'
|
||||||
|
Before="Rollback.RemoveSymlinks"
|
||||||
|
Sequence="execute" />
|
||||||
|
<CustomAction
|
||||||
|
Id="Rollback.RemoveSymlinks"
|
||||||
|
BinaryKey="CustomActions"
|
||||||
|
DllEntry="DeferredAction"
|
||||||
|
Execute="rollback"
|
||||||
|
Impersonate="no"
|
||||||
|
Return="check" />
|
||||||
|
<InstallExecuteSequence>
|
||||||
|
<!--
|
||||||
|
deferred: `RemoveSymlinks` on uninstall
|
||||||
|
rollback: `InstallSymlinks` on uninstall
|
||||||
|
-->
|
||||||
|
<Custom Action="Rollback.RemoveSymlinks" Before="RemoveFiles">
|
||||||
|
REMOVE ~= "ALL"
|
||||||
|
</Custom>
|
||||||
|
<Custom Action="Deferred.RemoveSymlinks" After="Rollback.RemoveSymlinks">
|
||||||
|
REMOVE ~= "ALL"
|
||||||
|
</Custom>
|
||||||
|
</InstallExecuteSequence>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Specify WIXFAILWHENDEFERRED=1 on the msiexec cmdline for rollback testing.
|
||||||
|
See http://tinyurl.com/yxkaywek
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<Property Id="WIXFAILWHENDEFERRED" Value="0" Secure="yes" />
|
||||||
|
<CustomActionRef Id="WixFailWhenDeferred" />
|
||||||
|
-->
|
||||||
</Product>
|
</Product>
|
||||||
</Wix>
|
</Wix>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||||
<Pedantic>True</Pedantic>
|
<Pedantic>True</Pedantic>
|
||||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||||
<SuppressIces>ICE30</SuppressIces>
|
<SuppressIces>ICE30;ICE61</SuppressIces>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
@ -29,12 +29,16 @@
|
|||||||
<SuppressAllWarnings>False</SuppressAllWarnings>
|
<SuppressAllWarnings>False</SuppressAllWarnings>
|
||||||
<Pedantic>True</Pedantic>
|
<Pedantic>True</Pedantic>
|
||||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||||
<SuppressIces>ICE30</SuppressIces>
|
<SuppressIces>ICE30;ICE61</SuppressIces>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Product.wxs" />
|
<Compile Include="Product.wxs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<WixExtension Include="WixUtilExtension">
|
||||||
|
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
|
||||||
|
<Name>WixUtilExtension</Name>
|
||||||
|
</WixExtension>
|
||||||
<WixExtension Include="WixUIExtension">
|
<WixExtension Include="WixUIExtension">
|
||||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||||
<Name>WixUIExtension</Name>
|
<Name>WixUIExtension</Name>
|
||||||
|
@ -1,27 +1,30 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<Project>
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<PropertyGroup>
|
||||||
|
<BaseIntermediateOutputPath>$(SolutionDir)build\$(MSBuildProjectName).build\</BaseIntermediateOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.common.props))/build.common.props" />
|
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), build.common.props))/build.common.props" />
|
||||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{4920E350-D496-4652-AE98-6C4208AEC1D8}</ProjectGuid>
|
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<ProjectName>memfs-dotnet</ProjectName>
|
<ProjectName>memfs-dotnet</ProjectName>
|
||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
|
||||||
<RootNamespace>memfs</RootNamespace>
|
<RootNamespace>memfs</RootNamespace>
|
||||||
<AssemblyName>memfs-dotnet-msil</AssemblyName>
|
<AssemblyName>memfs-dotnet-msil</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
<TargetFramework>net452</TargetFramework>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
|
||||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
@ -33,32 +36,16 @@
|
|||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
<Optimize>true</Optimize>
|
<Optimize>true</Optimize>
|
||||||
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
<OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath>
|
||||||
<BaseIntermediateOutputPath>$(SolutionDir)build\$(ProjectName).build\</BaseIntermediateOutputPath>
|
|
||||||
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
<IntermediateOutputPath>$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
|
||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<ProjectReference Include="..\dotnet\winfsp.net.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\..\..\tst\memfs-dotnet\Program.cs">
|
<Compile Include="..\..\..\tst\memfs-dotnet\Program.cs" />
|
||||||
<Link>Program.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||||
<ProjectReference Include="..\dotnet\winfsp.net.csproj">
|
|
||||||
<Project>{94580219-cc8d-4fe5-a3be-437b0b3481e1}</Project>
|
|
||||||
<Name>winfsp.net</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
|
||||||
<Target Name="BeforeBuild">
|
|
||||||
</Target>
|
|
||||||
<Target Name="AfterBuild">
|
|
||||||
</Target>
|
|
||||||
-->
|
|
||||||
</Project>
|
</Project>
|
@ -284,6 +284,7 @@
|
|||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\security-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\stream-tests.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\timeout-test.c" />
|
||||||
|
<ClCompile Include="..\..\..\tst\winfsp-tests\loadun-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\uuid5-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\uuid5-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\version-test.c" />
|
||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\volpath-test.c" />
|
<ClCompile Include="..\..\..\tst\winfsp-tests\volpath-test.c" />
|
||||||
|
@ -112,6 +112,9 @@
|
|||||||
<ClCompile Include="..\..\..\tst\winfsp-tests\notify-test.c">
|
<ClCompile Include="..\..\..\tst\winfsp-tests\notify-test.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\tst\winfsp-tests\loadun-test.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
<ClInclude Include="..\..\..\ext\tlib\testsuite.h">
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\ntstatus.c" />
|
<ClCompile Include="..\..\src\dll\ntstatus.c" />
|
||||||
<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\sxs.c" />
|
||||||
<ClCompile Include="..\..\src\dll\util.c" />
|
<ClCompile Include="..\..\src\dll\util.c" />
|
||||||
<ClCompile Include="..\..\src\dll\wksid.c" />
|
<ClCompile Include="..\..\src\dll\wksid.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
||||||
|
@ -178,6 +178,9 @@
|
|||||||
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
<Filter>Source\shared\ku</Filter>
|
<Filter>Source\shared\ku</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\dll\sxs.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\library.def">
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
@ -260,6 +260,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||||
<ClCompile Include="..\..\src\sys\silo.c" />
|
<ClCompile Include="..\..\src\sys\silo.c" />
|
||||||
<ClCompile Include="..\..\src\sys\statistics.c" />
|
<ClCompile Include="..\..\src\sys\statistics.c" />
|
||||||
|
<ClCompile Include="..\..\src\sys\sxs.c" />
|
||||||
<ClCompile Include="..\..\src\sys\trace.c" />
|
<ClCompile Include="..\..\src\sys\trace.c" />
|
||||||
<ClCompile Include="..\..\src\sys\util.c" />
|
<ClCompile Include="..\..\src\sys\util.c" />
|
||||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||||
@ -290,6 +291,9 @@
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
@ -303,6 +307,9 @@ stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(MyProductFileArch).inf</Comma
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
@ -316,6 +323,9 @@ stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(MyProductFileArch).inf</Comma
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
@ -328,6 +338,9 @@ stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(MyProductFileArch).inf</Comma
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
@ -342,6 +355,9 @@ stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(MyProductFileArch).inf</Comma
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
@ -354,6 +370,9 @@ stampinf -d * -v $(MyVersion) -f $(OutDir)driver-$(MyProductFileArch).inf</Comma
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">set DriverFile=$(TargetFileName)
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">set DriverFile=$(TargetFileName)
|
||||||
set Provider="$(MyCompanyName)"
|
set Provider="$(MyCompanyName)"
|
||||||
set CatalogFile=driver-$(MyProductFileArch).cat
|
set CatalogFile=driver-$(MyProductFileArch).cat
|
||||||
|
if "$(MyProductFileArch)"=="a64" set ArchDecoration=ntarm64
|
||||||
|
if "$(MyProductFileArch)"=="x64" set ArchDecoration=ntamd64
|
||||||
|
if "$(MyProductFileArch)"=="x86" set ArchDecoration=ntx86
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
if exist $(OutDir)driver-$(MyProductFileArch).inf del $(OutDir)driver-$(MyProductFileArch).inf
|
||||||
|
@ -134,6 +134,9 @@
|
|||||||
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
<Filter>Source\shared\ku</Filter>
|
<Filter>Source\shared\ku</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\sys\sxs.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -6,18 +6,17 @@
|
|||||||
|
|
||||||
I am running Windows 7 and I am finding that the installed driver is not signed.::
|
I am running Windows 7 and I am finding that the installed driver is not signed.::
|
||||||
|
|
||||||
Your Windows 7 OS is missing SHA-2 Code Signing Support. You need to install the following security advisory that will rectify the problem:
|
Your Windows 7 OS is missing SHA-2 Code Signing Support. Make sure it is fully updated.
|
||||||
https://technet.microsoft.com/en-us/library/security/3033929.aspx
|
|
||||||
|
|
||||||
|
I cannot run a program located in a WinFsp drive as administrator. I cannot run `regedit.exe` from within a WinFsp drive.::
|
||||||
|
|
||||||
|
When running an executable as administrator, the Windows OS seems to require that the name of the file system that is housing the executable is "NTFS". For example, the MEMFS file system with the command line `memfs-x64.exe -i -F NTFS -m X:` works.
|
||||||
|
|
||||||
|
|
||||||
Disconnecting (unmapping) a network drive does not work.::
|
Disconnecting (unmapping) a network drive does not work.::
|
||||||
|
|
||||||
You may have Dokany installed. Dokany installs its own Network Provider DLL that unfortunately interferes with the WinFsp handling of network drives. The solution is to change your system's Network Provider order and ensure that the WinFsp Network Provider runs before the Dokany one. Instructions on how to change the Network Provider order can be found in this http://blogs.interfacett.com/changing-the-network-provider-order-in-windows-10[article].
|
You may have Dokany installed. Dokany installs its own Network Provider DLL that unfortunately interferes with the WinFsp handling of network drives. The solution is to change your system's Network Provider order and ensure that the WinFsp Network Provider runs before the Dokany one. Instructions on how to change the Network Provider order can be found in this https://www.interfacett.com/blogs/changing-the-network-provider-order-in-windows-10/[article].
|
||||||
|
|
||||||
|
|
||||||
Case-sensitive file systems do not work properly when mounted as a directory.::
|
|
||||||
|
|
||||||
This is fixed as of WinFsp 2018.2 B3.
|
|
||||||
|
|
||||||
|
|
||||||
Why is the DLL not installed in the Windows system directories?::
|
Why is the DLL not installed in the Windows system directories?::
|
||||||
@ -29,7 +28,7 @@ There are a few alternative methods to overcome this problem. WinFsp recommends
|
|||||||
|
|
||||||
Does WinFsp provide debugging symbols?::
|
Does WinFsp provide debugging symbols?::
|
||||||
|
|
||||||
Public debugging symbols are already included in the installer. You need to install the "Developer" feature; the symbols can be found in the `sym` directory under the WinFsp installation directory.
|
Debugging symbols can be found in the https://github.com/winfsp/winfsp.sym repository.
|
||||||
|
|
||||||
|
|
||||||
Is there a maximum number of concurrent file systems?::
|
Is there a maximum number of concurrent file systems?::
|
||||||
@ -61,11 +60,6 @@ With this in mind here are the reasons for the current WinFsp-FUSE behavior:
|
|||||||
- Most importantly: inability to guarantee that the mount point will cease to exist if the file system crashes. WinFsp attempts to guarantee that all resources used by a file system will get cleaned up. This is certainly true for the kernel-mode FSD, but an attempt is made to do so also in user mode. For this reason, drive symbolic links are marked as temporary and (importantly for our discussion) mount directories are opened with `FILE_FLAG_DELETE_ON_CLOSE`. There is no way to guarantee the removal of a reparse point in the same way.
|
- Most importantly: inability to guarantee that the mount point will cease to exist if the file system crashes. WinFsp attempts to guarantee that all resources used by a file system will get cleaned up. This is certainly true for the kernel-mode FSD, but an attempt is made to do so also in user mode. For this reason, drive symbolic links are marked as temporary and (importantly for our discussion) mount directories are opened with `FILE_FLAG_DELETE_ON_CLOSE`. There is no way to guarantee the removal of a reparse point in the same way.
|
||||||
|
|
||||||
|
|
||||||
WinFsp-FUSE does not have the ability to support multiple file systems from within the same process. Why?::
|
|
||||||
|
|
||||||
This is supported as of WinFsp 2018.2 B2.
|
|
||||||
|
|
||||||
|
|
||||||
I have problems getting permissions to work properly in a WinFsp-FUSE file system. Can you help?::
|
I have problems getting permissions to work properly in a WinFsp-FUSE file system. Can you help?::
|
||||||
|
|
||||||
The WinFsp-FUSE layer includes a built-in command line option that can help: `-o uid=-1`. This instructs the WinFsp-FUSE layer to present all file system files as if they are owned by the user that launched the file system.
|
The WinFsp-FUSE layer includes a built-in command line option that can help: `-o uid=-1`. This instructs the WinFsp-FUSE layer to present all file system files as if they are owned by the user that launched the file system.
|
||||||
|
@ -30,7 +30,6 @@ This document contains a list of known open-source file systems and file system
|
|||||||
- https://github.com/winfsp/cgofuse[Go: cgofuse] - Cross-platform FUSE library for Go
|
- https://github.com/winfsp/cgofuse[Go: cgofuse] - Cross-platform FUSE library for Go
|
||||||
- https://github.com/SerCeMan/jnr-fuse[Java: jnr-fuse] - FUSE implementation in Java using Java Native Runtime (JNR)
|
- https://github.com/SerCeMan/jnr-fuse[Java: jnr-fuse] - FUSE implementation in Java using Java Native Runtime (JNR)
|
||||||
- https://github.com/jnr-winfsp-team/jnr-winfsp[Java: jnr-winfsp] - A Java binding for WinFsp using Java Native Runtime (JNR)
|
- https://github.com/jnr-winfsp-team/jnr-winfsp[Java: jnr-winfsp] - A Java binding for WinFsp using Java Native Runtime (JNR)
|
||||||
- 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/billziss-gh/fusepy[Python: fusepy] - Simple ctypes bindings for FUSE
|
- https://github.com/billziss-gh/fusepy[Python: fusepy] - Simple ctypes bindings for FUSE
|
||||||
- https://github.com/pleiszenburg/refuse[Python: refuse] - Simple cross-plattform ctypes bindings for libfuse / FUSE for macOS / WinFsp
|
- https://github.com/pleiszenburg/refuse[Python: refuse] - Simple cross-plattform ctypes bindings for libfuse / FUSE for macOS / WinFsp
|
||||||
- https://github.com/Scille/winfspy[Python: winfspy] - WinFSP binding for Python
|
- https://github.com/Scille/winfspy[Python: winfspy] - WinFSP binding for Python
|
||||||
|
@ -65,6 +65,8 @@ Primary registry key used to store WinFsp settings. On a 64-bit system (x64 or A
|
|||||||
|
|
||||||
* `InstallDir (REG_SZ)`: Contains the WinFsp installation directory.
|
* `InstallDir (REG_SZ)`: Contains the WinFsp installation directory.
|
||||||
|
|
||||||
|
* `SxsDir (REG_SZ)`: Contains the WinFsp Side-by-Side (SxS) directory. The SxS directory allows for multiple versions of WinFsp to be active at the same time and among other benefits it enables reinstalling WinFsp without reboot. The SxS directory contains primarily executable files.
|
||||||
|
|
||||||
* `DistinctPermsForSameOwnerGroup (REG_DWORD)`: Directs how WinFsp-FUSE should consider UNIX owner and group permissions in the case when the Windows owner and group SID are the same (for example, this can happen when someone uses a Microsoft account as their primary login). When this setting is 0 and the Windows owner and group SID are the same, WinFsp-FUSE combines the UNIX owner and group permissions (for example, user permission `rw-` and group permission `---` combine to `---`), which can result in inadvertent "access denied" errors. When this setting is 1 and even if the Windows owner and group SID are the same, WinFsp-FUSE looks at the UNIX owner permissions and the UNIX group permissions separately. The default value is 1 since v1.11B1 and was 0 in earlier versions.
|
* `DistinctPermsForSameOwnerGroup (REG_DWORD)`: Directs how WinFsp-FUSE should consider UNIX owner and group permissions in the case when the Windows owner and group SID are the same (for example, this can happen when someone uses a Microsoft account as their primary login). When this setting is 0 and the Windows owner and group SID are the same, WinFsp-FUSE combines the UNIX owner and group permissions (for example, user permission `rw-` and group permission `---` combine to `---`), which can result in inadvertent "access denied" errors. When this setting is 1 and even if the Windows owner and group SID are the same, WinFsp-FUSE looks at the UNIX owner permissions and the UNIX group permissions separately. The default value is 1 since v1.11B1 and was 0 in earlier versions.
|
||||||
|
|
||||||
* `MountBroadcastDriveChange (REG_DWORD)`: A value of 1 instructs WinFsp to broadcast an additional "drive change" message to all top-level windows during mounting and unmounting. The default value is 0. Normally the Windows infrastructure broadcasts a `WM_DEVICECHANGE` message whenever a drive gets added/removed. In some rare systems it is possible for this message to get lost or stalled. The workaround for these rare systems is to enable this registry setting, in which case WinFsp will broadcast the `WM_DEVICECHANGE` using a slightly different but more reliable method than the one Windows uses.
|
* `MountBroadcastDriveChange (REG_DWORD)`: A value of 1 instructs WinFsp to broadcast an additional "drive change" message to all top-level windows during mounting and unmounting. The default value is 0. Normally the Windows infrastructure broadcasts a `WM_DEVICECHANGE` message whenever a drive gets added/removed. In some rare systems it is possible for this message to get lost or stalled. The workaround for these rare systems is to enable this registry setting, in which case WinFsp will broadcast the `WM_DEVICECHANGE` using a slightly different but more reliable method than the one Windows uses.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.c
|
* @file tlib/callstack.c
|
||||||
*
|
*
|
||||||
* @copyright 2014-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/callstack.h>
|
#include <tlib/callstack.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/callstack.h
|
* @file tlib/callstack.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/injection.h>
|
#include <tlib/injection.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/injection.h
|
* @file tlib/injection.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tlib/testsuite.h>
|
#include <tlib/testsuite.h>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file tlib/testsuite.h
|
* @file tlib/testsuite.h
|
||||||
*
|
*
|
||||||
* @copyright 2014-2022 Bill Zissimopoulos
|
* @copyright 2014-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
#ifndef TLIB_TESTSUITE_H_INCLUDED
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#if !defined(WINFSP_DLL_INTERNAL)
|
#if !defined(WINFSP_DLL_INTERNAL)
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* FUSE: Filesystem in Userspace
|
* FUSE: Filesystem in Userspace
|
||||||
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
* Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file fuse3/fuse_opt.h
|
* @file fuse3/fuse_opt.h
|
||||||
* WinFsp FUSE3 compatible API.
|
* WinFsp FUSE3 compatible API.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file fuse3/winfsp_fuse.h
|
* @file fuse3/winfsp_fuse.h
|
||||||
* WinFsp FUSE3 compatible API.
|
* WinFsp FUSE3 compatible API.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file winfsp/fsctl.h
|
* @file winfsp/fsctl.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -111,6 +111,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 's', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 's', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_NOTIFY \
|
#define FSP_FSCTL_NOTIFY \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'n', METHOD_NEITHER, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'n', METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||||
|
#define FSP_FSCTL_UNLOAD \
|
||||||
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'U', METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||||
|
|
||||||
/* fsctl internal device codes (usable only in-kernel) */
|
/* fsctl internal device codes (usable only in-kernel) */
|
||||||
#define FSP_FSCTL_TRANSACT_INTERNAL \
|
#define FSP_FSCTL_TRANSACT_INTERNAL \
|
||||||
@ -694,6 +696,12 @@ FSP_API NTSTATUS FspFsctlNotify(HANDLE VolumeHandle,
|
|||||||
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
||||||
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
|
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize);
|
||||||
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
|
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
|
||||||
|
FSP_API NTSTATUS FspFsctlServiceVersion(PUINT32 PVersion);
|
||||||
|
FSP_API NTSTATUS FspFsctlStartService(VOID);
|
||||||
|
FSP_API NTSTATUS FspFsctlStopService(VOID);
|
||||||
|
FSP_API NTSTATUS FspFsctlEnumServices(
|
||||||
|
VOID (*EnumFn)(PVOID Context, PWSTR ServiceName, BOOLEAN Running),
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* In order to use the WinFsp Launch API a program must include <winfsp/launch.h>
|
* In order to use the WinFsp Launch API a program must include <winfsp/launch.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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1047,11 +1047,49 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
|
|
||||||
NTSTATUS (*Obsolete0)(VOID);
|
NTSTATUS (*Obsolete0)(VOID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inform the file system that its dispatcher has been stopped.
|
||||||
|
*
|
||||||
|
* Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless
|
||||||
|
* the user mode file system requested the unmount. Since WinFsp v2.0 it is possible
|
||||||
|
* for the FSD to unmount a file system volume without an explicit user mode file system
|
||||||
|
* request. For example, this happens when the FSD is being uninstalled.
|
||||||
|
*
|
||||||
|
* A user mode file system can use this operation to determine when its dispatcher
|
||||||
|
* has been stopped. The Normally parameter can be used to determine why the dispatcher
|
||||||
|
* was stopped: it is TRUE when the file system is being stopped via
|
||||||
|
* FspFileSystemStopDispatcher and FALSE otherwise.
|
||||||
|
*
|
||||||
|
* When the file system receives a request with Normally == TRUE it need not take any
|
||||||
|
* extra steps. This case is the same as for pre-v2.0 versions: since the file system
|
||||||
|
* stopped the dispatcher via FspFileSystemStopDispatcher, it will likely exit its
|
||||||
|
* process soon.
|
||||||
|
*
|
||||||
|
* When the file system receives a request with Normally == FALSE it may need to take
|
||||||
|
* extra steps to exit its process as this is not done by default.
|
||||||
|
*
|
||||||
|
* A file system that uses the FspService infrastructure may use the
|
||||||
|
* FspFileSystemStopServiceIfNecessary API to correctly handle all cases.
|
||||||
|
*
|
||||||
|
* This operation is the last one that a file system will receive.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system on which this request is posted.
|
||||||
|
* @param Normally
|
||||||
|
* TRUE if the file system is being stopped via FspFileSystemStopDispatcher.
|
||||||
|
* FALSE if the file system is being stopped because of another reason such
|
||||||
|
* as driver unload/uninstall.
|
||||||
|
* @see
|
||||||
|
* FspFileSystemStopServiceIfNecessary
|
||||||
|
*/
|
||||||
|
VOID (*DispatcherStopped)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
BOOLEAN Normally);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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[32])();
|
NTSTATUS (*Reserved[31])();
|
||||||
} 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.");
|
||||||
@ -1074,7 +1112,8 @@ typedef struct _FSP_FILE_SYSTEM
|
|||||||
SRWLOCK OpGuardLock;
|
SRWLOCK OpGuardLock;
|
||||||
BOOLEAN UmFileContextIsUserContext2, UmFileContextIsFullContext;
|
BOOLEAN UmFileContextIsUserContext2, UmFileContextIsFullContext;
|
||||||
UINT16 UmNoReparsePointsDirCheck:1;
|
UINT16 UmNoReparsePointsDirCheck:1;
|
||||||
UINT16 UmReservedFlags:15;
|
UINT16 UmReservedFlags:14;
|
||||||
|
UINT16 DispatcherStopping:1;
|
||||||
} FSP_FILE_SYSTEM;
|
} FSP_FILE_SYSTEM;
|
||||||
FSP_FSCTL_STATIC_ASSERT(
|
FSP_FSCTL_STATIC_ASSERT(
|
||||||
(4 == sizeof(PVOID) && 660 == sizeof(FSP_FILE_SYSTEM)) ||
|
(4 == sizeof(PVOID) && 660 == sizeof(FSP_FILE_SYSTEM)) ||
|
||||||
@ -1108,7 +1147,7 @@ FSP_API NTSTATUS FspFileSystemPreflight(PWSTR DevicePath,
|
|||||||
* @param VolumeParams
|
* @param VolumeParams
|
||||||
* Volume parameters for the newly created file system.
|
* Volume parameters for the newly created file system.
|
||||||
* @param Interface
|
* @param Interface
|
||||||
* A pointer to the actual operations that actually implement this user mode file system.
|
* A pointer to the operations that implement this user mode file system.
|
||||||
* @param PFileSystem [out]
|
* @param PFileSystem [out]
|
||||||
* Pointer that will receive the file system object created on successful return from this
|
* Pointer that will receive the file system object created on successful return from this
|
||||||
* call.
|
* call.
|
||||||
@ -1746,6 +1785,23 @@ UINT32 FspFileSystemGetEaPackedSize(PFILE_FULL_EA_INFORMATION SingleEa)
|
|||||||
*/
|
*/
|
||||||
FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
|
FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
|
||||||
PVOID Buffer, ULONG Length, PULONG PBytesTransferred);
|
PVOID Buffer, ULONG Length, PULONG PBytesTransferred);
|
||||||
|
/**
|
||||||
|
* Stop a file system service, if any.
|
||||||
|
*
|
||||||
|
* This is a helper for implementing the DispatcherStopped operation, but only for file systems
|
||||||
|
* that use the FspService infrastructure.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system object.
|
||||||
|
* @param Normally
|
||||||
|
* TRUE if the file system is being stopped via FspFileSystemStopDispatcher.
|
||||||
|
* FALSE if the file system is being stopped because of another reason such
|
||||||
|
* as driver unload/uninstall.
|
||||||
|
* @see
|
||||||
|
* DispatcherStopped
|
||||||
|
*/
|
||||||
|
FSP_API VOID FspFileSystemStopServiceIfNecessary(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
BOOLEAN Normally);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Directory buffering
|
* Directory buffering
|
||||||
@ -2043,6 +2099,8 @@ FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service);
|
|||||||
* to connect the service process to the Service Control Manager. If the Service Control Manager is
|
* to connect the service process to the Service Control Manager. If the Service Control Manager is
|
||||||
* not available (and console mode is allowed) it will enter console mode.
|
* not available (and console mode is allowed) it will enter console mode.
|
||||||
*
|
*
|
||||||
|
* This function should be called once per process.
|
||||||
|
*
|
||||||
* @param Service
|
* @param Service
|
||||||
* The service object.
|
* The service object.
|
||||||
* @return
|
* @return
|
||||||
@ -2120,6 +2178,7 @@ FSP_API NTSTATUS FspCallNamedPipeSecurelyEx(PWSTR PipeName,
|
|||||||
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
|
PULONG PBytesTransferred, ULONG Timeout, BOOLEAN AllowImpersonation,
|
||||||
PSID Sid);
|
PSID Sid);
|
||||||
FSP_API NTSTATUS FspVersion(PUINT32 PVersion);
|
FSP_API NTSTATUS FspVersion(PUINT32 PVersion);
|
||||||
|
FSP_API PWSTR FspSxsIdent(VOID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delay load
|
* Delay load
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @file winfsp/winfsp.hpp
|
* @file winfsp/winfsp.hpp
|
||||||
* WinFsp C++ Layer.
|
* WinFsp C++ Layer.
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/debug.c
|
* @file dll/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/debuglog.c
|
* @file dll/debuglog.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/dirbuf.c
|
* @file dll/dirbuf.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
34
src/dll/fs.c
34
src/dll/fs.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fs.c
|
* @file dll/fs.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -358,6 +358,21 @@ exit:
|
|||||||
CloseHandle(DispatcherThread);
|
CloseHandle(DispatcherThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetCurrentThreadId() == GetThreadId(FileSystem->DispatcherThread))
|
||||||
|
{
|
||||||
|
if (0 != FileSystem->Interface->DispatcherStopped)
|
||||||
|
{
|
||||||
|
/* Normally = !!FileSystem->DispatcherStopping */
|
||||||
|
BOOLEAN Normally = !!(
|
||||||
|
_InterlockedOr16(
|
||||||
|
(PVOID)((PUINT8)&FileSystem->UmFileContextIsFullContext +
|
||||||
|
sizeof(FileSystem->UmFileContextIsFullContext)),
|
||||||
|
0) &
|
||||||
|
0x8000);
|
||||||
|
FileSystem->Interface->DispatcherStopped(FileSystem, Normally);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,6 +406,11 @@ FSP_API NTSTATUS FspFileSystemStartDispatcher(FSP_FILE_SYSTEM *FileSystem, ULONG
|
|||||||
if (0 == FileSystem->DispatcherThread)
|
if (0 == FileSystem->DispatcherThread)
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
#if defined(FSP_CFG_REJECT_EARLY_IRP)
|
||||||
|
FspFsctlTransact(FileSystem->VolumeHandle, 0, 0, 0, 0, FALSE);
|
||||||
|
/* send a Transact0 to inform the FSD that the dispatcher is _almost_ ready */
|
||||||
|
#endif
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +419,12 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
if (0 == FileSystem->DispatcherThread)
|
if (0 == FileSystem->DispatcherThread)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* FileSystem->DispatcherStopping = 1 */
|
||||||
|
_InterlockedOr16(
|
||||||
|
(PVOID)((PUINT8)&FileSystem->UmFileContextIsFullContext +
|
||||||
|
sizeof(FileSystem->UmFileContextIsFullContext)),
|
||||||
|
0x8000);
|
||||||
|
|
||||||
FspFsctlStop0(FileSystem->VolumeHandle);
|
FspFsctlStop0(FileSystem->VolumeHandle);
|
||||||
|
|
||||||
WaitForSingleObject(FileSystem->DispatcherThread, INFINITE);
|
WaitForSingleObject(FileSystem->DispatcherThread, INFINITE);
|
||||||
@ -406,6 +432,12 @@ FSP_API VOID FspFileSystemStopDispatcher(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
FileSystem->DispatcherThread = 0;
|
FileSystem->DispatcherThread = 0;
|
||||||
|
|
||||||
FspFsctlStop(FileSystem->VolumeHandle);
|
FspFsctlStop(FileSystem->VolumeHandle);
|
||||||
|
|
||||||
|
/* FileSystem->DispatcherStopping = 0 */
|
||||||
|
_InterlockedAnd16(
|
||||||
|
(PVOID)((PUINT8)&FileSystem->UmFileContextIsFullContext +
|
||||||
|
sizeof(FileSystem->UmFileContextIsFullContext)),
|
||||||
|
0x7fff);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
408
src/dll/fsctl.c
408
src/dll/fsctl.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsctl.c
|
* @file dll/fsctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -31,20 +31,20 @@ static ULONG FspFsctlServiceVersionValue;
|
|||||||
static DWORD FspFsctlTransactCode = FSP_FSCTL_TRANSACT;
|
static DWORD FspFsctlTransactCode = FSP_FSCTL_TRANSACT;
|
||||||
static DWORD FspFsctlTransactBatchCode = FSP_FSCTL_TRANSACT_BATCH;
|
static DWORD FspFsctlTransactBatchCode = FSP_FSCTL_TRANSACT_BATCH;
|
||||||
|
|
||||||
static VOID FspFsctlServiceVersion(PUINT32 PVersion);
|
|
||||||
static NTSTATUS FspFsctlStartService(VOID);
|
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
||||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||||
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,
|
PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize,
|
||||||
PHANDLE PVolumeHandle)
|
PHANDLE PVolumeHandle)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
WCHAR SxsDevicePathBuf[MAX_PATH];
|
||||||
PWSTR DeviceRoot;
|
PWSTR DeviceRoot;
|
||||||
SIZE_T DeviceRootSize, DevicePathSize, VolumeParamsSize;
|
SIZE_T DeviceRootSize, DevicePathSize, VolumeParamsSize;
|
||||||
WCHAR DevicePathBuf[MAX_PATH + sizeof *VolumeParams], *DevicePathPtr, *DevicePathEnd;
|
WCHAR DevicePathBuf[MAX_PATH + sizeof *VolumeParams], *DevicePathPtr, *DevicePathEnd;
|
||||||
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
||||||
DWORD Bytes;
|
DWORD Bytes;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath);
|
||||||
|
|
||||||
if (sizeof(WCHAR) <= VolumeNameSize)
|
if (sizeof(WCHAR) <= VolumeNameSize)
|
||||||
VolumeNameBuf[0] = L'\0';
|
VolumeNameBuf[0] = L'\0';
|
||||||
@ -229,12 +229,15 @@ exit:
|
|||||||
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
||||||
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize)
|
PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
WCHAR SxsDevicePathBuf[MAX_PATH];
|
||||||
PWSTR DeviceRoot;
|
PWSTR DeviceRoot;
|
||||||
SIZE_T DeviceRootSize, DevicePathSize;
|
SIZE_T DeviceRootSize, DevicePathSize;
|
||||||
WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr;
|
WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr;
|
||||||
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
||||||
DWORD Bytes;
|
DWORD Bytes;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath);
|
||||||
|
|
||||||
/* check lengths; everything must fit within MAX_PATH */
|
/* check lengths; everything must fit within MAX_PATH */
|
||||||
DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\";
|
DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\";
|
||||||
@ -298,16 +301,71 @@ FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsctlUnload(PWSTR DevicePath)
|
||||||
|
{
|
||||||
|
WCHAR SxsDevicePathBuf[MAX_PATH];
|
||||||
|
PWSTR DeviceRoot;
|
||||||
|
SIZE_T DeviceRootSize, DevicePathSize;
|
||||||
|
WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr;
|
||||||
|
HANDLE VolumeHandle = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD Bytes;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath);
|
||||||
|
|
||||||
|
/* check lengths; everything must fit within MAX_PATH */
|
||||||
|
DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\";
|
||||||
|
DeviceRootSize = lstrlenW(DeviceRoot) * sizeof(WCHAR);
|
||||||
|
DevicePathSize = lstrlenW(DevicePath) * sizeof(WCHAR);
|
||||||
|
if (DeviceRootSize + DevicePathSize + sizeof(WCHAR) > sizeof DevicePathBuf)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
/* prepare the device path to be opened */
|
||||||
|
DevicePathPtr = DevicePathBuf;
|
||||||
|
memcpy(DevicePathPtr, DeviceRoot, DeviceRootSize);
|
||||||
|
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DeviceRootSize);
|
||||||
|
memcpy(DevicePathPtr, DevicePath, DevicePathSize);
|
||||||
|
DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DevicePathSize);
|
||||||
|
*DevicePathPtr = L'\0';
|
||||||
|
|
||||||
|
VolumeHandle = CreateFileW(DevicePathBuf,
|
||||||
|
0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||||
|
if (INVALID_HANDLE_VALUE == VolumeHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
if (STATUS_OBJECT_PATH_NOT_FOUND == Result ||
|
||||||
|
STATUS_OBJECT_NAME_NOT_FOUND == Result)
|
||||||
|
Result = STATUS_NO_SUCH_DEVICE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_UNLOAD, 0, 0, 0, 0, &Bytes, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != VolumeHandle)
|
||||||
|
CloseHandle(VolumeHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL WINAPI FspFsctlServiceVersionInitialize(
|
static BOOL WINAPI FspFsctlServiceVersionInitialize(
|
||||||
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
{
|
{
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
WCHAR DriverName[256];
|
||||||
PWSTR ModuleFileName;
|
PWSTR ModuleFileName;
|
||||||
SC_HANDLE ScmHandle = 0;
|
SC_HANDLE ScmHandle = 0;
|
||||||
SC_HANDLE SvcHandle = 0;
|
SC_HANDLE SvcHandle = 0;
|
||||||
QUERY_SERVICE_CONFIGW *ServiceConfig = 0;
|
QUERY_SERVICE_CONFIGW *ServiceConfig = 0;
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
|
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
|
||||||
ScmHandle = OpenSCManagerW(0, 0, 0);
|
ScmHandle = OpenSCManagerW(0, 0, 0);
|
||||||
if (0 == ScmHandle)
|
if (0 == ScmHandle)
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -363,37 +421,59 @@ exit:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID FspFsctlServiceVersion(PUINT32 PVersion)
|
FSP_API NTSTATUS FspFsctlServiceVersion(PUINT32 PVersion)
|
||||||
{
|
{
|
||||||
InitOnceExecuteOnce(&FspFsctlServiceVersionInitOnce, FspFsctlServiceVersionInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspFsctlServiceVersionInitOnce, FspFsctlServiceVersionInitialize, 0, 0);
|
||||||
|
|
||||||
if (0 != PVersion)
|
if (0 != PVersion)
|
||||||
*PVersion = FspFsctlServiceVersionValue;
|
*PVersion = FspFsctlServiceVersionValue;
|
||||||
|
|
||||||
|
return 0 != FspFsctlServiceVersionValue ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsctlStartService(VOID)
|
static FSP_ADAPTIVE_LOCK FspFsctlStartStopServiceLock = FSP_ADAPTIVE_LOCK_INIT;
|
||||||
|
static VOID FspFsctlStartStopServiceLockAcquire(VOID)
|
||||||
|
{
|
||||||
|
extern HINSTANCE DllInstance;
|
||||||
|
WCHAR DllPath[MAX_PATH];
|
||||||
|
PWSTR FileName = 0;
|
||||||
|
|
||||||
|
if (0 != GetModuleFileNameW(DllInstance, DllPath, MAX_PATH))
|
||||||
|
FileName = DllPath;
|
||||||
|
|
||||||
|
FspAdaptiveLockAcquire(&FspFsctlStartStopServiceLock,
|
||||||
|
FileName, 0xfffffffffffffff0ull, (10 + 1) * 1000);
|
||||||
|
}
|
||||||
|
static VOID FspFsctlStartStopServiceLockRelease(VOID)
|
||||||
|
{
|
||||||
|
FspAdaptiveLockRelease(&FspFsctlStartStopServiceLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN FspFsctlRunningInContainer(VOID)
|
||||||
|
{
|
||||||
|
/* Determine if we are running inside container.
|
||||||
|
*
|
||||||
|
* See https://github.com/microsoft/perfview/blob/V1.9.65/src/TraceEvent/TraceEventSession.cs#L525
|
||||||
|
* See https://stackoverflow.com/a/50748300
|
||||||
|
*/
|
||||||
|
return ERROR_SUCCESS == RegGetValueW(
|
||||||
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control",
|
||||||
|
L"ContainerType",
|
||||||
|
RRF_RT_REG_DWORD, 0,
|
||||||
|
0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsctlStartServiceByName(PWSTR DriverName)
|
||||||
{
|
{
|
||||||
static SRWLOCK Lock = SRWLOCK_INIT;
|
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
|
||||||
SC_HANDLE ScmHandle = 0;
|
SC_HANDLE ScmHandle = 0;
|
||||||
SC_HANDLE SvcHandle = 0;
|
SC_HANDLE SvcHandle = 0;
|
||||||
SERVICE_STATUS ServiceStatus;
|
SERVICE_STATUS ServiceStatus;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&Lock);
|
FspFsctlStartStopServiceLockAcquire();
|
||||||
|
|
||||||
/* Determine if we are running inside container.
|
if (FspFsctlRunningInContainer())
|
||||||
*
|
|
||||||
* See https://github.com/microsoft/perfview/blob/V1.9.65/src/TraceEvent/TraceEventSession.cs#L525
|
|
||||||
* See https://stackoverflow.com/a/50748300
|
|
||||||
*/
|
|
||||||
LastError = RegGetValueW(
|
|
||||||
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control",
|
|
||||||
L"ContainerType",
|
|
||||||
RRF_RT_REG_DWORD, 0,
|
|
||||||
0, 0);
|
|
||||||
if (ERROR_SUCCESS == LastError)
|
|
||||||
{
|
{
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -453,7 +533,218 @@ exit:
|
|||||||
if (0 != ScmHandle)
|
if (0 != ScmHandle)
|
||||||
CloseServiceHandle(ScmHandle);
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
ReleaseSRWLockExclusive(&Lock);
|
FspFsctlStartStopServiceLockRelease();
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFsctlStartService_EnumFn(PVOID Context, PWSTR ServiceName, BOOLEAN Running)
|
||||||
|
{
|
||||||
|
PWSTR DriverName = Context;
|
||||||
|
if (0 > invariant_wcscmp(DriverName, ServiceName))
|
||||||
|
lstrcpyW(DriverName, ServiceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlStartService(VOID)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* With the introduction of side-by-side (SxS) FSD installations,
|
||||||
|
* we revisit how the FSD is started:
|
||||||
|
*
|
||||||
|
* - If the DLL is started in non-SxS mode, we first try to start
|
||||||
|
* the non-SxS FSD. If that fails we then enumerate all SxS FSD's
|
||||||
|
* and make a best guess on which one to start.
|
||||||
|
*
|
||||||
|
* - If the DLL is started in SxS mode, we only attempt to start
|
||||||
|
* the associated SxS FSD.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (L'\0' == FspSxsIdent()[0])
|
||||||
|
{
|
||||||
|
/* non-SxS mode */
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
WCHAR DriverName[256];
|
||||||
|
|
||||||
|
Result = FspFsctlStartServiceByName(L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
if (NT_SUCCESS(Result) || STATUS_NO_SUCH_DEVICE != Result)
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
/* DO NOT CLOBBER Result. We will return it if our best effort below fails. */
|
||||||
|
|
||||||
|
DriverName[0] = L'\0';
|
||||||
|
FspFsctlEnumServices(FspFsctlStartService_EnumFn, DriverName);
|
||||||
|
|
||||||
|
if (L'\0' == DriverName[0] || !NT_SUCCESS(FspFsctlStartServiceByName(DriverName)))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* SxS mode */
|
||||||
|
|
||||||
|
WCHAR DriverName[256];
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
return FspFsctlStartServiceByName(DriverName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlStopService(VOID)
|
||||||
|
{
|
||||||
|
WCHAR DriverName[256];
|
||||||
|
HANDLE ThreadToken = 0, ProcessToken = 0;
|
||||||
|
BOOL DidSetThreadToken = FALSE, DidAdjustTokenPrivileges = FALSE;
|
||||||
|
TOKEN_PRIVILEGES Privileges, PreviousPrivileges;
|
||||||
|
PRIVILEGE_SET RequiredPrivileges;
|
||||||
|
DWORD PreviousPrivilegesLength;
|
||||||
|
BOOL PrivilegeCheckResult;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
|
||||||
|
FspFsctlStartStopServiceLockAcquire();
|
||||||
|
|
||||||
|
if (FspFsctlRunningInContainer())
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable and check SeLoadDriverPrivilege required for FSP_FSCTL_UNLOAD */
|
||||||
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, TRUE, &ThreadToken))
|
||||||
|
{
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &ProcessToken) ||
|
||||||
|
!DuplicateToken(ProcessToken, SecurityDelegation, &ThreadToken) ||
|
||||||
|
!SetThreadToken(0, ThreadToken))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
DidSetThreadToken = TRUE;
|
||||||
|
CloseHandle(ThreadToken);
|
||||||
|
ThreadToken = 0;
|
||||||
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, TRUE, &ThreadToken))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!LookupPrivilegeValueW(0, SE_LOAD_DRIVER_NAME, &Privileges.Privileges[0].Luid))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
Privileges.PrivilegeCount = 1;
|
||||||
|
Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
if (!AdjustTokenPrivileges(ThreadToken, FALSE,
|
||||||
|
&Privileges, sizeof PreviousPrivileges, &PreviousPrivileges, &PreviousPrivilegesLength))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
DidAdjustTokenPrivileges = 0 == GetLastError();
|
||||||
|
RequiredPrivileges.PrivilegeCount = 1;
|
||||||
|
RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
|
||||||
|
RequiredPrivileges.Privilege[0].Attributes = 0;
|
||||||
|
RequiredPrivileges.Privilege[0].Luid = Privileges.Privileges[0].Luid;
|
||||||
|
if (!PrivilegeCheck(ThreadToken, &RequiredPrivileges, &PrivilegeCheckResult))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!PrivilegeCheckResult)
|
||||||
|
{
|
||||||
|
Result = STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspFsctlUnload(L"" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
if (!NT_SUCCESS(Result) && STATUS_NO_SUCH_DEVICE != Result)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (DidAdjustTokenPrivileges)
|
||||||
|
AdjustTokenPrivileges(ThreadToken, FALSE, &PreviousPrivileges, 0, 0, 0);
|
||||||
|
if (DidSetThreadToken)
|
||||||
|
SetThreadToken(0, 0);
|
||||||
|
if (0 != ThreadToken)
|
||||||
|
CloseHandle(ThreadToken);
|
||||||
|
if (0 != ProcessToken)
|
||||||
|
CloseHandle(ProcessToken);
|
||||||
|
|
||||||
|
FspFsctlStartStopServiceLockRelease();
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlEnumServices(
|
||||||
|
VOID (*EnumFn)(PVOID Context, PWSTR ServiceName, BOOLEAN Running),
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
|
SC_HANDLE ScmHandle = 0;
|
||||||
|
LPENUM_SERVICE_STATUSW Services = 0;
|
||||||
|
DWORD Size, ServiceCount;
|
||||||
|
DWORD LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_ENUMERATE_SERVICE);
|
||||||
|
if (0 == ScmHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnumServicesStatusW(ScmHandle,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_STATE_ALL, 0, 0, &Size, &ServiceCount, 0))
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (ERROR_MORE_DATA != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 == Size)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Services = MemAlloc(Size);
|
||||||
|
if (0 == Services)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnumServicesStatusW(ScmHandle,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_STATE_ALL, Services, Size, &Size, &ServiceCount, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD I = 0; ServiceCount > I; I++)
|
||||||
|
{
|
||||||
|
if (0 != invariant_wcsicmp(Services[I].lpServiceName, L"" FSP_FSCTL_DRIVER_NAME) &&
|
||||||
|
0 != invariant_wcsnicmp(Services[I].lpServiceName,
|
||||||
|
L"" FSP_FSCTL_DRIVER_NAME FSP_SXS_SEPARATOR_STRING,
|
||||||
|
sizeof(FSP_FSCTL_DRIVER_NAME FSP_SXS_SEPARATOR_STRING) - 1))
|
||||||
|
continue;
|
||||||
|
EnumFn(Context,
|
||||||
|
Services[I].lpServiceName,
|
||||||
|
SERVICE_STOPPED != Services[I].ServiceStatus.dwCurrentState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Services);
|
||||||
|
if (0 != ScmHandle)
|
||||||
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -461,14 +752,15 @@ exit:
|
|||||||
static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This function adds an ACE that allows Everyone to start a service.
|
* This function adds two ACE's:
|
||||||
|
* - An ACE that allows Everyone to start a service.
|
||||||
|
* - An ACE that denies Everyone (including Administrators) to stop a service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PSID WorldSid;
|
PSID WorldSid;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
EXPLICIT_ACCESSW AccessEntry;
|
EXPLICIT_ACCESSW AccessEntries[2];
|
||||||
ACCESS_MASK AccessRights;
|
|
||||||
PACL Dacl;
|
PACL Dacl;
|
||||||
BOOL DaclPresent, DaclDefaulted;
|
BOOL DaclPresent, DaclDefaulted;
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
@ -513,41 +805,28 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare an EXPLICIT_ACCESS for the SERVICE_QUERY_STATUS | SERVICE_START right for Everyone */
|
/* prepare an EXPLICIT_ACCESS for the SERVICE_QUERY_STATUS | SERVICE_START rights for Everyone */
|
||||||
AccessEntry.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_START;
|
AccessEntries[0].grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_START;
|
||||||
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
AccessEntries[0].grfAccessMode = GRANT_ACCESS;
|
||||||
AccessEntry.grfInheritance = NO_INHERITANCE;
|
AccessEntries[0].grfInheritance = NO_INHERITANCE;
|
||||||
AccessEntry.Trustee.pMultipleTrustee = 0;
|
AccessEntries[0].Trustee.pMultipleTrustee = 0;
|
||||||
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
AccessEntries[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
AccessEntries[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
AccessEntries[0].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
AccessEntry.Trustee.ptstrName = WorldSid;
|
AccessEntries[0].Trustee.ptstrName = WorldSid;
|
||||||
|
|
||||||
/* get the effective rights for Everyone */
|
/* prepare an EXPLICIT_ACCESS to deny the SERVICE_STOP right to Everyone */
|
||||||
AccessRights = 0;
|
AccessEntries[1].grfAccessPermissions = SERVICE_STOP;
|
||||||
if (DaclPresent && 0 != Dacl)
|
AccessEntries[1].grfAccessMode = DENY_ACCESS;
|
||||||
{
|
AccessEntries[1].grfInheritance = NO_INHERITANCE;
|
||||||
LastError = GetEffectiveRightsFromAclW(Dacl, &AccessEntry.Trustee, &AccessRights);
|
AccessEntries[1].Trustee.pMultipleTrustee = 0;
|
||||||
if (0 != LastError)
|
AccessEntries[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
/*
|
AccessEntries[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
* Apparently GetEffectiveRightsFromAclW can fail with ERROR_CIRCULAR_DEPENDENCY
|
AccessEntries[1].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
* in some rare circumstances. Calling GetEffectiveRightsFromAclW is not essential
|
AccessEntries[1].Trustee.ptstrName = WorldSid;
|
||||||
* in this instance. It is only done to check whether the "Everyone/World" SID
|
|
||||||
* already has the access required to start the FSD; if it does not have those
|
|
||||||
* rights already they are added. It is probably safe to just assume that the
|
|
||||||
* required rights are not there if GetEffectiveRightsFromAclW fails; the worst
|
|
||||||
* that can happen is that the rights get added twice (which is benign).
|
|
||||||
*
|
|
||||||
* See https://github.com/winfsp/winfsp/issues/62
|
|
||||||
*/
|
|
||||||
AccessRights = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do we have the required access rights? */
|
|
||||||
if (AccessEntry.grfAccessPermissions != (AccessRights & AccessEntry.grfAccessPermissions))
|
|
||||||
{
|
|
||||||
/* create a new security descriptor with the new access */
|
/* create a new security descriptor with the new access */
|
||||||
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
LastError = BuildSecurityDescriptorW(0, 0, 2, AccessEntries, 0, 0, SecurityDescriptor,
|
||||||
&Size, &NewSecurityDescriptor);
|
&Size, &NewSecurityDescriptor);
|
||||||
if (0 != LastError)
|
if (0 != LastError)
|
||||||
{
|
{
|
||||||
@ -561,7 +840,6 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
Result = FspNtStatusFromWin32(GetLastError());
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -575,7 +853,7 @@ exit:
|
|||||||
NTSTATUS FspFsctlRegister(VOID)
|
NTSTATUS FspFsctlRegister(VOID)
|
||||||
{
|
{
|
||||||
extern HINSTANCE DllInstance;
|
extern HINSTANCE DllInstance;
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
WCHAR DriverName[256];
|
||||||
WCHAR DriverPath[MAX_PATH];
|
WCHAR DriverPath[MAX_PATH];
|
||||||
DWORD Size;
|
DWORD Size;
|
||||||
SC_HANDLE ScmHandle = 0;
|
SC_HANDLE ScmHandle = 0;
|
||||||
@ -584,6 +862,8 @@ NTSTATUS FspFsctlRegister(VOID)
|
|||||||
SERVICE_DESCRIPTION ServiceDescription;
|
SERVICE_DESCRIPTION ServiceDescription;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
|
||||||
Result = FspGetModuleFileName(DllInstance, DriverPath, MAX_PATH, L"" MyFsctlRegisterPath);
|
Result = FspGetModuleFileName(DllInstance, DriverPath, MAX_PATH, L"" MyFsctlRegisterPath);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
@ -674,12 +954,16 @@ exit:
|
|||||||
|
|
||||||
NTSTATUS FspFsctlUnregister(VOID)
|
NTSTATUS FspFsctlUnregister(VOID)
|
||||||
{
|
{
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
WCHAR DriverName[256];
|
||||||
SC_HANDLE ScmHandle = 0;
|
SC_HANDLE ScmHandle = 0;
|
||||||
SC_HANDLE SvcHandle = 0;
|
SC_HANDLE SvcHandle = 0;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
|
||||||
|
FspFsctlStopService();
|
||||||
|
|
||||||
ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_CREATE_SERVICE);
|
ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_CREATE_SERVICE);
|
||||||
/*
|
/*
|
||||||
* The SC_MANAGER_CREATE_SERVICE access right is not strictly needed here,
|
* The SC_MANAGER_CREATE_SERVICE access right is not strictly needed here,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fsop.c
|
* @file dll/fsop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1883,3 +1883,12 @@ FSP_API BOOLEAN FspFileSystemAddNotifyInfo(FSP_FSCTL_NOTIFY_INFO *NotifyInfo,
|
|||||||
{
|
{
|
||||||
return FspFileSystemAddXxxInfo(NotifyInfo, Buffer, Length, PBytesTransferred);
|
return FspFileSystemAddXxxInfo(NotifyInfo, Buffer, Length, PBytesTransferred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspFileSystemStopServiceIfNecessary(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
BOOLEAN Normally)
|
||||||
|
{
|
||||||
|
/* NOTE: .NET calls us with a zero FileSystem pointer! */
|
||||||
|
if (Normally)
|
||||||
|
return;
|
||||||
|
FspServiceStopLoop();
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse.c
|
* @file dll/fuse/fuse.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_compat.c
|
* @file dll/fuse/fuse_compat.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1939,7 +1939,7 @@ int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SizeA = lstrlenA(name);
|
SizeA = lstrlenA(name);
|
||||||
if (SizeA > 255)
|
if (SizeA > 255 * 4)
|
||||||
{
|
{
|
||||||
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
|
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
|
||||||
"too long");
|
"too long");
|
||||||
@ -1949,6 +1949,13 @@ int fsp_fuse_intf_AddDirInfo(void *buf, const char *name,
|
|||||||
SizeW = MultiByteToWideChar(CP_UTF8, 0, name, SizeA, DirInfo->FileNameBuf, 255);
|
SizeW = MultiByteToWideChar(CP_UTF8, 0, name, SizeA, DirInfo->FileNameBuf, 255);
|
||||||
if (0 == SizeW)
|
if (0 == SizeW)
|
||||||
{
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
|
||||||
|
{
|
||||||
|
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
|
||||||
|
"too long");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
|
fsp_fuse_intf_LogBadDirInfo(filedesc->PosixPath, name,
|
||||||
"MultiByteToWideChar failed");
|
"MultiByteToWideChar failed");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1991,7 +1998,7 @@ static NTSTATUS fsp_fuse_intf_FixDirInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
SizeA = lstrlenA(filedesc->PosixPath);
|
SizeA = lstrlenA(filedesc->PosixPath);
|
||||||
PosixPath = MemAlloc(SizeA + 1 + 255 + 1);
|
PosixPath = MemAlloc(SizeA + 1 + 255 * 4 + 1);
|
||||||
if (0 == PosixPath)
|
if (0 == PosixPath)
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
@ -2040,7 +2047,7 @@ static NTSTATUS fsp_fuse_intf_FixDirInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
PosixPathEnd = 0;
|
PosixPathEnd = 0;
|
||||||
SizeA = WideCharToMultiByte(CP_UTF8, 0, DirInfo->FileNameBuf, SizeW, PosixName, 255, 0, 0);
|
SizeA = WideCharToMultiByte(CP_UTF8, 0, DirInfo->FileNameBuf, SizeW, PosixName, 255 * 4, 0, 0);
|
||||||
if (0 == SizeA)
|
if (0 == SizeA)
|
||||||
{
|
{
|
||||||
/* this should never happen because we just converted using MultiByteToWideChar */
|
/* this should never happen because we just converted using MultiByteToWideChar */
|
||||||
@ -2628,6 +2635,17 @@ static NTSTATUS fsp_fuse_intf_SetEa(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
&Uid, &Gid, &Mode, FileInfo);
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID fsp_fuse_intf_DispatcherStopped(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
BOOLEAN Normally)
|
||||||
|
{
|
||||||
|
if (Normally)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct fuse *f = FileSystem->UserContext;
|
||||||
|
|
||||||
|
fsp_fuse_exit(f->env, f);
|
||||||
|
}
|
||||||
|
|
||||||
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
||||||
{
|
{
|
||||||
fsp_fuse_intf_GetVolumeInfo,
|
fsp_fuse_intf_GetVolumeInfo,
|
||||||
@ -2661,6 +2679,8 @@ FSP_FILE_SYSTEM_INTERFACE fsp_fuse_intf =
|
|||||||
fsp_fuse_intf_Overwrite,
|
fsp_fuse_intf_Overwrite,
|
||||||
fsp_fuse_intf_GetEa,
|
fsp_fuse_intf_GetEa,
|
||||||
fsp_fuse_intf_SetEa,
|
fsp_fuse_intf_SetEa,
|
||||||
|
0,
|
||||||
|
fsp_fuse_intf_DispatcherStopped,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_loop.c
|
* @file dll/fuse/fuse_loop.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse_main.c
|
* @file dll/fuse/fuse_main.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse3/fuse2to3.c
|
* @file dll/fuse3/fuse2to3.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse3/fuse3.c
|
* @file dll/fuse3/fuse3.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse/fuse3_compat.c
|
* @file dll/fuse/fuse3_compat.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/fuse3/library.h
|
* @file dll/fuse3/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/launch.c
|
* @file dll/launch.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/ldap.c
|
* @file dll/ldap.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.c
|
* @file dll/library.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/library.h
|
* @file dll/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -70,6 +70,9 @@ NTSTATUS FspNpUnregister(VOID);
|
|||||||
NTSTATUS FspEventLogRegister(VOID);
|
NTSTATUS FspEventLogRegister(VOID);
|
||||||
NTSTATUS FspEventLogUnregister(VOID);
|
NTSTATUS FspEventLogUnregister(VOID);
|
||||||
|
|
||||||
|
PWSTR FspSxsSuffix(VOID);
|
||||||
|
PWSTR FspSxsAppendSuffix(PWCHAR Buffer, SIZE_T Size, PWSTR Ident);
|
||||||
|
|
||||||
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
||||||
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
||||||
|
|
||||||
@ -103,10 +106,26 @@ NTSTATUS FspGetModuleFileName(
|
|||||||
ULONG Size,
|
ULONG Size,
|
||||||
PWSTR RelativePath);
|
PWSTR RelativePath);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRWLOCK Lock;
|
||||||
|
HANDLE Handle;
|
||||||
|
UINT64 Offset;
|
||||||
|
} FSP_ADAPTIVE_LOCK;
|
||||||
|
#define FSP_ADAPTIVE_LOCK_INIT { SRWLOCK_INIT, INVALID_HANDLE_VALUE, 0 }
|
||||||
|
VOID FspAdaptiveLockAcquire(
|
||||||
|
FSP_ADAPTIVE_LOCK *Lock,
|
||||||
|
PWSTR FileName,
|
||||||
|
UINT64 Offset,
|
||||||
|
DWORD Timeout);
|
||||||
|
VOID FspAdaptiveLockRelease(
|
||||||
|
FSP_ADAPTIVE_LOCK *Lock);
|
||||||
|
|
||||||
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
||||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount);
|
PUINT8 *PBuffer, PULONG *PIndex, PULONG PCount);
|
||||||
|
|
||||||
|
VOID FspServiceStopLoop(VOID);
|
||||||
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
|
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
|
||||||
|
|
||||||
static inline ULONG FspPathSuffixIndex(PWSTR FileName)
|
static inline ULONG FspPathSuffixIndex(PWSTR FileName)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/mount.c
|
* @file dll/mount.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
|
||||||
static INIT_ONCE FspMountInitOnce = INIT_ONCE_STATIC_INIT;
|
static INIT_ONCE FspMountInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
|
static NTSTATUS (NTAPI *FspNtOpenSymbolicLinkObject)(
|
||||||
@ -350,6 +351,19 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID FspMountNotifyShellDriveChange(VOID)
|
||||||
|
{
|
||||||
|
HRESULT HResult;
|
||||||
|
LPITEMIDLIST Pidl;
|
||||||
|
|
||||||
|
HResult = SHGetKnownFolderIDList(&FOLDERID_ComputerFolder, KF_FLAG_DEFAULT, 0, &Pidl);
|
||||||
|
if (SUCCEEDED(HResult))
|
||||||
|
{
|
||||||
|
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, Pidl, 0);
|
||||||
|
CoTaskMemFree(Pidl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountSet_Drive(PWSTR VolumeName, PWSTR MountPoint, PHANDLE PMountHandle)
|
static NTSTATUS FspMountSet_Drive(PWSTR VolumeName, PWSTR MountPoint, PHANDLE PMountHandle)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -568,7 +582,7 @@ static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle)
|
|||||||
return CloseHandle(MountHandle) ? STATUS_SUCCESS : FspNtStatusFromWin32(GetLastError());
|
return CloseHandle(MountHandle) ? STATUS_SUCCESS : FspNtStatusFromWin32(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
|
NTSTATUS FspMountSet_Internal(FSP_MOUNT_DESC *Desc)
|
||||||
{
|
{
|
||||||
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
||||||
|
|
||||||
@ -609,7 +623,7 @@ FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
|
|||||||
&Desc->MountHandle);
|
&Desc->MountHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
NTSTATUS FspMountRemove_Internal(FSP_MOUNT_DESC *Desc)
|
||||||
{
|
{
|
||||||
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
||||||
|
|
||||||
@ -623,3 +637,81 @@ FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
|||||||
else
|
else
|
||||||
return FspMountRemove_Directory(Desc->MountHandle);
|
return FspMountRemove_Directory(Desc->MountHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN IsDrive;
|
||||||
|
|
||||||
|
IsDrive =
|
||||||
|
(L'*' == Desc->MountPoint[0] && ':' == Desc->MountPoint[1] && L'\0' == Desc->MountPoint[2]) ||
|
||||||
|
FspPathIsMountmgrDrive(Desc->MountPoint) ||
|
||||||
|
FspPathIsDrive(Desc->MountPoint);
|
||||||
|
|
||||||
|
#if defined(FSP_CFG_REJECT_EARLY_IRP)
|
||||||
|
/*
|
||||||
|
* In the original WinFsp design the FSD could accept incoming file system requests
|
||||||
|
* immediately after the in-kernel file system instance was created. Such requests would
|
||||||
|
* be queued in the internal FSD queues and only delivered to the user mode file system
|
||||||
|
* when its dispatcher was started and actively receiving them.
|
||||||
|
*
|
||||||
|
* At the same time the original WinFsp API design was that a user mode file system first
|
||||||
|
* calls FspFileSystemSetMountPoint to create the file system mount point and then calls
|
||||||
|
* FspFileSystemStartDispatcher to start the dispatcher. This design made sense at the time:
|
||||||
|
* creating a mount point involved the creation of a symbolic link of one kind or another,
|
||||||
|
* which could fail for a number of reasons (e.g. drive already exists), so there was no
|
||||||
|
* point to start the dispatcher if the mounting did not succeed. Compatibility with FUSE
|
||||||
|
* and the Unix mounting protocol was another consideration.
|
||||||
|
*
|
||||||
|
* Unfortunately this API design has proved problematic. The problem is that with the
|
||||||
|
* proliferation of ways to mount a file system in WinFsp more and more system components and
|
||||||
|
* third party filters may attempt to access the mount point upon its creation and before the
|
||||||
|
* file system dispatcher is ready. This can result in various consequences.
|
||||||
|
*
|
||||||
|
* In order to properly fix this problem we should probably mandate that a user mode file
|
||||||
|
* system should start its dispatcher first and then create its mountpoint. This way the user
|
||||||
|
* mode file system would be ready to handle any requests from system components or third
|
||||||
|
* party filters during mount point creation. Unfortunately we cannot easily do so because
|
||||||
|
* of backwards compatibility.
|
||||||
|
*
|
||||||
|
* This problem first appeared as an incompatibility with Avast AntiVirus (GitHub issue #221).
|
||||||
|
* In order to avoid backwards incompatible API changes the "Transact0" work around was
|
||||||
|
* devised: when the FSD first creates an in-kernel file system it remains inoperative and any
|
||||||
|
* requests posted to it will fail with STATUS_CANCELLED, until it receives a Transact0
|
||||||
|
* message (an FSP_FSCTL_TRANSACT message with 0 buffers). In order to enable this work around
|
||||||
|
* a user mode file system would specify the RejectIrpPriorToTransact0 flag upon creation.
|
||||||
|
*
|
||||||
|
* Another instance of this problem appeared when support for directory mounting via the Mount
|
||||||
|
* Manager was added: mounting would not complete unless the RejectIrpPriorToTransact0 flag
|
||||||
|
* was set. At this point the RejectIrpPriorToTransact0 was hard coded to 1 in the FSD.
|
||||||
|
*
|
||||||
|
* However if we are creating a drive the Transact0 work around is unnecessary and perhaps
|
||||||
|
* harmful. So in this case send a Transact0 message to the FSD to allow file system requests
|
||||||
|
* to be queued rather than rejected with STATUS_CANCELLED.
|
||||||
|
*/
|
||||||
|
if (IsDrive)
|
||||||
|
FspFsctlTransact(Desc->VolumeHandle, 0, 0, 0, 0, FALSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result = FspMountSet_Internal(Desc);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN IsDrive;
|
||||||
|
|
||||||
|
IsDrive =
|
||||||
|
FspPathIsMountmgrDrive(Desc->MountPoint) ||
|
||||||
|
FspPathIsDrive(Desc->MountPoint);
|
||||||
|
|
||||||
|
Result = FspMountRemove_Internal(Desc);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Result) && IsDrive)
|
||||||
|
/* send an extra notification to remove the "ghost" drive in the shell's navigation pane */
|
||||||
|
FspMountNotifyShellDriveChange();
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/np.c
|
* @file dll/np.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/ntstatus.c
|
* @file dll/ntstatus.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/security.c
|
* @file dll/security.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/service.c
|
* @file dll/service.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -40,6 +40,8 @@ enum
|
|||||||
GetStatus_WaitHint = 0x4000,
|
GetStatus_WaitHint = 0x4000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static SRWLOCK FspServiceLoopLock = SRWLOCK_INIT;
|
||||||
|
static SRWLOCK FspServiceTableLock = SRWLOCK_INIT;
|
||||||
static SERVICE_TABLE_ENTRYW *FspServiceTable;
|
static SERVICE_TABLE_ENTRYW *FspServiceTable;
|
||||||
static HANDLE FspServiceConsoleModeEvent;
|
static HANDLE FspServiceConsoleModeEvent;
|
||||||
static UINT32 FspServiceConsoleCtrlHandlerDisabled;
|
static UINT32 FspServiceConsoleCtrlHandlerDisabled;
|
||||||
@ -220,6 +222,14 @@ FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service)
|
|||||||
|
|
||||||
FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* FspServiceLoop can only be called once per process, because of StartServiceCtrlDispatcherW
|
||||||
|
* (which returns ERROR_SERVICE_ALREADY_RUNNING if called more than once). Unfortunately this
|
||||||
|
* limitation was never documented and there may be users of FspServiceLoop out there that call
|
||||||
|
* it more than once per process.
|
||||||
|
*/
|
||||||
|
AcquireSRWLockExclusive(&FspServiceLoopLock);
|
||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
SERVICE_TABLE_ENTRYW ServiceTable[2];
|
SERVICE_TABLE_ENTRYW ServiceTable[2];
|
||||||
|
|
||||||
@ -236,7 +246,9 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
|||||||
ServiceTable[0].lpServiceProc = FspServiceEntry;
|
ServiceTable[0].lpServiceProc = FspServiceEntry;
|
||||||
ServiceTable[1].lpServiceName = 0;
|
ServiceTable[1].lpServiceName = 0;
|
||||||
ServiceTable[1].lpServiceProc = 0;
|
ServiceTable[1].lpServiceProc = 0;
|
||||||
|
AcquireSRWLockExclusive(&FspServiceTableLock);
|
||||||
FspServiceTable = ServiceTable;
|
FspServiceTable = ServiceTable;
|
||||||
|
ReleaseSRWLockExclusive(&FspServiceTableLock);
|
||||||
|
|
||||||
if (!StartServiceCtrlDispatcherW(ServiceTable))
|
if (!StartServiceCtrlDispatcherW(ServiceTable))
|
||||||
{
|
{
|
||||||
@ -331,11 +343,42 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
AcquireSRWLockExclusive(&FspServiceTableLock);
|
||||||
FspServiceTable = 0;
|
FspServiceTable = 0;
|
||||||
|
ReleaseSRWLockExclusive(&FspServiceTableLock);
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&FspServiceLoopLock);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI FspServiceStopLoopThread(PVOID Context);
|
||||||
|
VOID FspServiceStopLoop(VOID)
|
||||||
|
{
|
||||||
|
BOOLEAN HasService;
|
||||||
|
HANDLE Thread;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&FspServiceTableLock);
|
||||||
|
HasService = 0 != FspServiceFromTable();
|
||||||
|
ReleaseSRWLockShared(&FspServiceTableLock);
|
||||||
|
|
||||||
|
if (HasService)
|
||||||
|
{
|
||||||
|
Thread = CreateThread(0, 0, FspServiceStopLoopThread, 0, 0, 0);
|
||||||
|
if (0 != Thread)
|
||||||
|
CloseHandle(Thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static DWORD WINAPI FspServiceStopLoopThread(PVOID Context)
|
||||||
|
{
|
||||||
|
AcquireSRWLockShared(&FspServiceTableLock);
|
||||||
|
FSP_SERVICE *Service = FspServiceFromTable();
|
||||||
|
if (0 != Service)
|
||||||
|
FspServiceStop(Service);
|
||||||
|
ReleaseSRWLockShared(&FspServiceTableLock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspServiceStop(FSP_SERVICE *Service)
|
FSP_API VOID FspServiceStop(FSP_SERVICE *Service)
|
||||||
{
|
{
|
||||||
SERVICE_STATUS ServiceStatus;
|
SERVICE_STATUS ServiceStatus;
|
||||||
@ -393,6 +436,7 @@ static VOID WINAPI FspServiceEntry(DWORD Argc, PWSTR *Argv)
|
|||||||
FSP_SERVICE *Service;
|
FSP_SERVICE *Service;
|
||||||
|
|
||||||
Service = FspServiceFromTable();
|
Service = FspServiceFromTable();
|
||||||
|
/* we are subordinate to FspServiceLoop; no need to protect this access with FspServiceTableLock */
|
||||||
if (0 == Service)
|
if (0 == Service)
|
||||||
{
|
{
|
||||||
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
||||||
@ -501,6 +545,7 @@ static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context)
|
|||||||
;
|
;
|
||||||
|
|
||||||
Service = FspServiceFromTable();
|
Service = FspServiceFromTable();
|
||||||
|
/* we are subordinate to FspServiceLoop; no need to protect this access with FspServiceTableLock */
|
||||||
if (0 == Service)
|
if (0 == Service)
|
||||||
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
FspServiceLog(EVENTLOG_ERROR_TYPE,
|
||||||
L"" __FUNCTION__ ": internal error: FspServiceFromTable = 0");
|
L"" __FUNCTION__ ": internal error: FspServiceFromTable = 0");
|
||||||
|
214
src/dll/sxs.c
Normal file
214
src/dll/sxs.c
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
* @file dll/sxs.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this software
|
||||||
|
* in accordance with the commercial license agreement provided in
|
||||||
|
* conjunction with the software. The terms and conditions of any such
|
||||||
|
* commercial license agreement shall govern, supersede, and render
|
||||||
|
* ineffective any application of the GPLv3 license to this software,
|
||||||
|
* notwithstanding of any reference thereto in the software or
|
||||||
|
* associated repository.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dll/library.h>
|
||||||
|
|
||||||
|
static INIT_ONCE FspSxsIdentInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
|
static WCHAR FspSxsIdentBuf[32 + 2] = L"";
|
||||||
|
|
||||||
|
static BOOLEAN FspSxsIdentInitializeFromFile(VOID)
|
||||||
|
{
|
||||||
|
extern HINSTANCE DllInstance;
|
||||||
|
WCHAR Path[MAX_PATH];
|
||||||
|
DWORD Size;
|
||||||
|
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||||
|
CHAR Buffer[ARRAYSIZE(FspSxsIdentBuf) - 2];
|
||||||
|
WCHAR WBuffer[ARRAYSIZE(FspSxsIdentBuf) - 2];
|
||||||
|
BOOLEAN Result = FALSE;
|
||||||
|
|
||||||
|
if (0 == GetModuleFileNameW(DllInstance, Path, MAX_PATH))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Size = lstrlenW(Path);
|
||||||
|
if (4 < Size &&
|
||||||
|
(L'.' == Path[Size - 4]) &&
|
||||||
|
(L'D' == Path[Size - 3] || L'd' == Path[Size - 3]) &&
|
||||||
|
(L'L' == Path[Size - 2] || L'l' == Path[Size - 2]) &&
|
||||||
|
(L'L' == Path[Size - 1] || L'l' == Path[Size - 1]) &&
|
||||||
|
(L'\0' == Path[Size]))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Size -= 4;
|
||||||
|
for (PWCHAR P = Path + Size - 1; Path <= P; P--)
|
||||||
|
{
|
||||||
|
if (L'\\' == *P)
|
||||||
|
break;
|
||||||
|
if (L'-' == *P)
|
||||||
|
{
|
||||||
|
/* arch */
|
||||||
|
Size = (DWORD)(P - Path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Path[Size + 0] = L'.';
|
||||||
|
Path[Size + 1] = L's';
|
||||||
|
Path[Size + 2] = L'x';
|
||||||
|
Path[Size + 3] = L's';
|
||||||
|
Path[Size + 4] = L'\0';
|
||||||
|
|
||||||
|
Handle = CreateFileW(
|
||||||
|
Path,
|
||||||
|
FILE_READ_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == Handle)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (!ReadFile(Handle, Buffer, sizeof Buffer, &Size, 0))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
for (PCHAR P = Buffer, EndP = P + Size; EndP > P; P++)
|
||||||
|
if ('\r' == *P || '\n' == *P)
|
||||||
|
{
|
||||||
|
Size = (DWORD)(P - Buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size = MultiByteToWideChar(CP_UTF8, 0,
|
||||||
|
Buffer, Size, WBuffer, ARRAYSIZE(WBuffer));
|
||||||
|
if (0 == Size)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
FspSxsIdentBuf[0] = FSP_SXS_SEPARATOR_CHAR;
|
||||||
|
memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR));
|
||||||
|
FspSxsIdentBuf[1 + Size] = L'\0';
|
||||||
|
|
||||||
|
Result = TRUE;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle)
|
||||||
|
CloseHandle(Handle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN FspSxsIdentInitializeFromDirectory(VOID)
|
||||||
|
{
|
||||||
|
extern HINSTANCE DllInstance;
|
||||||
|
WCHAR Path[MAX_PATH];
|
||||||
|
HANDLE Handle = INVALID_HANDLE_VALUE;
|
||||||
|
WCHAR FinalPath[MAX_PATH];
|
||||||
|
PWCHAR P, EndP, Q, EndQ;
|
||||||
|
PWCHAR Ident = 0;
|
||||||
|
BOOLEAN Result = FALSE;
|
||||||
|
|
||||||
|
if (0 == GetModuleFileNameW(DllInstance, Path, MAX_PATH))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Handle = CreateFileW(
|
||||||
|
Path,
|
||||||
|
0,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == Handle)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (!GetFinalPathNameByHandleW(Handle, FinalPath, MAX_PATH, VOLUME_NAME_NONE))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
EndP = FinalPath + lstrlenW(FinalPath);
|
||||||
|
for (P = EndP - 1; FinalPath <= P; P--)
|
||||||
|
{
|
||||||
|
if (L'\\' == *P &&
|
||||||
|
P + 9 < EndP &&
|
||||||
|
(L'S' == P[1] || L's' == P[1]) &&
|
||||||
|
(L'X' == P[2] || L'x' == P[2]) &&
|
||||||
|
(L'S' == P[3] || L's' == P[3]) &&
|
||||||
|
L'\\' == P[4] &&
|
||||||
|
(L'S' == P[5] || L's' == P[5]) &&
|
||||||
|
(L'X' == P[6] || L'x' == P[6]) &&
|
||||||
|
(L'S' == P[7] || L's' == P[7]) &&
|
||||||
|
L'.' == P[8] &&
|
||||||
|
L'\\' != P[9])
|
||||||
|
{
|
||||||
|
Ident = P + 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 == Ident)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
FspSxsIdentBuf[0] = FSP_SXS_SEPARATOR_CHAR;
|
||||||
|
EndQ = FspSxsIdentBuf + (ARRAYSIZE(FspSxsIdentBuf) - 1);
|
||||||
|
for (P = Ident, Q = FspSxsIdentBuf + 1; EndP > P && EndQ > Q && L'\\' != *P; P++, Q++)
|
||||||
|
*Q = *P;
|
||||||
|
*Q = L'\0';
|
||||||
|
|
||||||
|
Result = TRUE;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle)
|
||||||
|
CloseHandle(Handle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI FspSxsIdentInitialize(
|
||||||
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
|
{
|
||||||
|
if (FspSxsIdentInitializeFromFile())
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (FspSxsIdentInitializeFromDirectory())
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API PWSTR FspSxsIdent(VOID)
|
||||||
|
{
|
||||||
|
InitOnceExecuteOnce(&FspSxsIdentInitOnce, FspSxsIdentInitialize, 0, 0);
|
||||||
|
return FspSxsIdentBuf + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWSTR FspSxsSuffix(VOID)
|
||||||
|
{
|
||||||
|
InitOnceExecuteOnce(&FspSxsIdentInitOnce, FspSxsIdentInitialize, 0, 0);
|
||||||
|
return FspSxsIdentBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWSTR FspSxsAppendSuffix(PWCHAR Buffer, SIZE_T Size, PWSTR Ident)
|
||||||
|
{
|
||||||
|
PWSTR Suffix;
|
||||||
|
SIZE_T IdentSize, SuffixSize;
|
||||||
|
|
||||||
|
Suffix = FspSxsSuffix();
|
||||||
|
IdentSize = lstrlenW(Ident) * sizeof(WCHAR);
|
||||||
|
SuffixSize = lstrlenW(Suffix) * sizeof(WCHAR);
|
||||||
|
if (Size < IdentSize + SuffixSize + sizeof(WCHAR))
|
||||||
|
return L"<INVALID>";
|
||||||
|
|
||||||
|
memcpy(Buffer, Ident, IdentSize);
|
||||||
|
memcpy((PUINT8)Buffer + IdentSize, Suffix, SuffixSize);
|
||||||
|
*(PWCHAR)((PUINT8)Buffer + IdentSize + SuffixSize) = L'\0';
|
||||||
|
|
||||||
|
return Buffer;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/util.c
|
* @file dll/util.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -418,3 +418,74 @@ NTSTATUS FspGetModuleFileName(
|
|||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FspAdaptiveLockAcquire(
|
||||||
|
FSP_ADAPTIVE_LOCK *Lock,
|
||||||
|
PWSTR FileName,
|
||||||
|
UINT64 Offset,
|
||||||
|
DWORD Timeout)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&Lock->Lock);
|
||||||
|
|
||||||
|
if (0 != FileName)
|
||||||
|
{
|
||||||
|
HANDLE Handle;
|
||||||
|
DWORD BytesTransferred;
|
||||||
|
OVERLAPPED Overlapped;
|
||||||
|
BOOL Success;
|
||||||
|
|
||||||
|
Handle = CreateFileW(
|
||||||
|
FileName,
|
||||||
|
FILE_READ_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_FLAG_OVERLAPPED,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE != Handle)
|
||||||
|
{
|
||||||
|
memset(&Overlapped, 0, sizeof Overlapped);
|
||||||
|
Overlapped.Offset = ((PLARGE_INTEGER)&Offset)->LowPart;
|
||||||
|
Overlapped.OffsetHigh = ((PLARGE_INTEGER)&Offset)->HighPart;
|
||||||
|
|
||||||
|
Success = LockFileEx(
|
||||||
|
Handle,
|
||||||
|
LOCKFILE_EXCLUSIVE_LOCK, 0,
|
||||||
|
1, 0,
|
||||||
|
&Overlapped);
|
||||||
|
if (Success || ERROR_IO_PENDING == GetLastError())
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
if (WAIT_OBJECT_0 == WaitForSingleObject(Handle, Timeout))
|
||||||
|
Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
Lock->Handle = Handle;
|
||||||
|
Lock->Offset = Offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CloseHandle(Handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspAdaptiveLockRelease(
|
||||||
|
FSP_ADAPTIVE_LOCK *Lock)
|
||||||
|
{
|
||||||
|
if (INVALID_HANDLE_VALUE != Lock->Handle)
|
||||||
|
{
|
||||||
|
HANDLE Handle = Lock->Handle;
|
||||||
|
LARGE_INTEGER LargeOffset = *(PLARGE_INTEGER)&Lock->Offset;
|
||||||
|
|
||||||
|
UnlockFile(Handle, LargeOffset.LowPart, LargeOffset.HighPart, 1, 0);
|
||||||
|
|
||||||
|
CloseHandle(Handle);
|
||||||
|
|
||||||
|
Lock->Handle = INVALID_HANDLE_VALUE;
|
||||||
|
Lock->Offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&Lock->Lock);
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file dll/wksid.c
|
* @file dll/wksid.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/FileSystemBase+Const.cs
|
* dotnet/FileSystemBase+Const.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2022 Bill Zissimopoulos
|
* Copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* Copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1188,6 +1188,39 @@ namespace Fsp
|
|||||||
{
|
{
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Inform the file system that its dispatcher has been stopped.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Prior to WinFsp v2.0 the FSD would never unmount a file system volume unless
|
||||||
|
/// the user mode file system requested the unmount. Since WinFsp v2.0 it is possible
|
||||||
|
/// for the FSD to unmount a file system volume without an explicit user mode file system
|
||||||
|
/// request. For example, this happens when the FSD is being uninstalled.
|
||||||
|
/// </para><para>
|
||||||
|
/// A user mode file system can use this operation to determine when its dispatcher
|
||||||
|
/// has been stopped. The Normally parameter can be used to determine why the dispatcher
|
||||||
|
/// was stopped: it is TRUE when the file system is being stopped normally (i.e. via the
|
||||||
|
/// native FspFileSystemStopDispatcher) and FALSE otherwise.
|
||||||
|
/// </para><para>
|
||||||
|
/// A file system that uses the Service class infrastructure may use the
|
||||||
|
/// StopServiceIfNecessary method to correctly handle all cases. The base implementation
|
||||||
|
/// of this method calls the StopServiceIfNecessary method.
|
||||||
|
/// </para><para>
|
||||||
|
/// This operation is the last one that a file system will receive.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="Normally">
|
||||||
|
/// TRUE if the file system is being stopped via the native FspFileSystemStopDispatcher.
|
||||||
|
/// FALSE if the file system is being stopped because of another reason such
|
||||||
|
/// as driver unload/uninstall.
|
||||||
|
/// </param>
|
||||||
|
/// <seealso cref="StopServiceIfNecessary"/>
|
||||||
|
public virtual void DispatcherStopped(
|
||||||
|
Boolean Normally)
|
||||||
|
{
|
||||||
|
StopServiceIfNecessary(Normally);
|
||||||
|
}
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1483,6 +1516,10 @@ namespace Fsp
|
|||||||
{
|
{
|
||||||
return FullEaInformation.PackedSize(EaName, EaValue, NeedEa);
|
return FullEaInformation.PackedSize(EaName, EaValue, NeedEa);
|
||||||
}
|
}
|
||||||
|
public void StopServiceIfNecessary(Boolean Normally)
|
||||||
|
{
|
||||||
|
Api.FspFileSystemStopServiceIfNecessary(IntPtr.Zero, Normally);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/FileSystemHost.cs
|
* dotnet/FileSystemHost.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2022 Bill Zissimopoulos
|
* Copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -1426,6 +1426,21 @@ namespace Fsp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void DispatcherStopped(
|
||||||
|
IntPtr FileSystemPtr,
|
||||||
|
Boolean Normally)
|
||||||
|
{
|
||||||
|
FileSystemBase FileSystem = (FileSystemBase)Api.GetUserContext(FileSystemPtr);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FileSystem.DispatcherStopped(Normally);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
ExceptionHandler(FileSystem, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static FileSystemHost()
|
static FileSystemHost()
|
||||||
{
|
{
|
||||||
_FileSystemInterface.GetVolumeInfo = GetVolumeInfo;
|
_FileSystemInterface.GetVolumeInfo = GetVolumeInfo;
|
||||||
@ -1456,6 +1471,7 @@ namespace Fsp
|
|||||||
_FileSystemInterface.SetDelete = SetDelete;
|
_FileSystemInterface.SetDelete = SetDelete;
|
||||||
_FileSystemInterface.GetEa = GetEa;
|
_FileSystemInterface.GetEa = GetEa;
|
||||||
_FileSystemInterface.SetEa = SetEa;
|
_FileSystemInterface.SetEa = SetEa;
|
||||||
|
_FileSystemInterface.DispatcherStopped = DispatcherStopped;
|
||||||
|
|
||||||
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
|
_FileSystemInterfacePtr = Marshal.AllocHGlobal(FileSystemInterface.Size);
|
||||||
/* Marshal.AllocHGlobal does not zero memory; we must do it ourselves! */
|
/* Marshal.AllocHGlobal does not zero memory; we must do it ourselves! */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/Interop.cs
|
* dotnet/Interop.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2022 Bill Zissimopoulos
|
* Copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -745,6 +745,10 @@ namespace Fsp.Interop
|
|||||||
out FileInfo FileInfo);
|
out FileInfo FileInfo);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
internal delegate Int32 Obsolete0();
|
internal delegate Int32 Obsolete0();
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void DispatcherStopped(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int Size = IntPtr.Size * 64;
|
internal static int Size = IntPtr.Size * 64;
|
||||||
@ -781,6 +785,7 @@ namespace Fsp.Interop
|
|||||||
internal Proto.GetEa GetEa;
|
internal Proto.GetEa GetEa;
|
||||||
internal Proto.SetEa SetEa;
|
internal Proto.SetEa SetEa;
|
||||||
internal Proto.Obsolete0 Obsolete0;
|
internal Proto.Obsolete0 Obsolete0;
|
||||||
|
internal Proto.DispatcherStopped DispatcherStopped;
|
||||||
/* NTSTATUS (*Reserved[33])(); */
|
/* NTSTATUS (*Reserved[33])(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,6 +912,10 @@ namespace Fsp.Interop
|
|||||||
UInt32 Length,
|
UInt32 Length,
|
||||||
out UInt32 PBytesTransferred);
|
out UInt32 PBytesTransferred);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void FspFileSystemStopServiceIfNecessary(
|
||||||
|
IntPtr FileSystem,
|
||||||
|
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
|
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
|
||||||
ref IntPtr PDirBuffer,
|
ref IntPtr PDirBuffer,
|
||||||
@ -1048,6 +1057,7 @@ namespace Fsp.Interop
|
|||||||
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
||||||
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
|
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
|
||||||
internal static Proto.FspFileSystemAddNotifyInfo _FspFileSystemAddNotifyInfo;
|
internal static Proto.FspFileSystemAddNotifyInfo _FspFileSystemAddNotifyInfo;
|
||||||
|
internal static Proto.FspFileSystemStopServiceIfNecessary FspFileSystemStopServiceIfNecessary;
|
||||||
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
||||||
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
||||||
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
||||||
@ -1506,6 +1516,7 @@ namespace Fsp.Interop
|
|||||||
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
||||||
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
|
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
|
||||||
_FspFileSystemAddNotifyInfo = GetEntryPoint<Proto.FspFileSystemAddNotifyInfo>(Module);
|
_FspFileSystemAddNotifyInfo = GetEntryPoint<Proto.FspFileSystemAddNotifyInfo>(Module);
|
||||||
|
FspFileSystemStopServiceIfNecessary = GetEntryPoint<Proto.FspFileSystemStopServiceIfNecessary>(Module);
|
||||||
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
||||||
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
||||||
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dotnet/Service.cs
|
* dotnet/Service.cs
|
||||||
*
|
*
|
||||||
* Copyright 2015-2022 Bill Zissimopoulos
|
* Copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file fsptool/fsptool.c
|
* @file fsptool/fsptool.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -62,10 +62,12 @@ static void usage(void)
|
|||||||
"\n"
|
"\n"
|
||||||
"commands:\n"
|
"commands:\n"
|
||||||
" lsvol list file system devices (volumes)\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"
|
" id [NAME|SID|UID] print user id\n"
|
||||||
" perm [PATH|SDDL|UID:GID:MODE] print permissions\n",
|
" perm [PATH|SDDL|UID:GID:MODE] print permissions\n"
|
||||||
|
" lsdrv list drivers\n"
|
||||||
|
" load load driver\n"
|
||||||
|
" unload unload driver (requires load driver priv)\n"
|
||||||
|
" ver print version\n",
|
||||||
PROGNAME);
|
PROGNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +239,29 @@ NTSTATUS FspToolGetSidFromName(PWSTR Name, PSID *PSid)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ver(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
UINT32 Version;
|
||||||
|
PWSTR SxsIdent;
|
||||||
|
|
||||||
|
Result = FspVersion(&Version);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
SxsIdent = FspSxsIdent();
|
||||||
|
|
||||||
|
if (L'\0' == SxsIdent[0])
|
||||||
|
info("%u.%u", Version >> 16, Version & 0xFFFF);
|
||||||
|
else
|
||||||
|
info("%u.%u (SxS=%S)", Version >> 16, Version & 0xFFFF, SxsIdent);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS lsvol_dev(PWSTR DeviceName)
|
static NTSTATUS lsvol_dev(PWSTR DeviceName)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -255,7 +280,7 @@ static NTSTATUS lsvol_dev(PWSTR DeviceName)
|
|||||||
if (L'\0' == *P)
|
if (L'\0' == *P)
|
||||||
{
|
{
|
||||||
Drive[0] = FspToolGetDriveLetter(&LogicalDrives, VolumeName);
|
Drive[0] = FspToolGetDriveLetter(&LogicalDrives, VolumeName);
|
||||||
info("%-4S%S", Drive[0] ? Drive : L"", VolumeName);
|
info("%-4S%S", Drive[0] ? Drive : L"-", VolumeName);
|
||||||
VolumeName = P + 1;
|
VolumeName = P + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,6 +566,52 @@ static int perm(int argc, wchar_t **argv)
|
|||||||
return FspWin32FromNtStatus(Result);
|
return FspWin32FromNtStatus(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID lsdrv_enumfn(PVOID Context, PWSTR ServiceName, BOOLEAN Running)
|
||||||
|
{
|
||||||
|
info("%-4s%S", Running ? "R" : "-", ServiceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lsdrv(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlEnumServices(lsdrv_enumfn, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlStartService();
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int unload(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlStopService();
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
argc--;
|
argc--;
|
||||||
@ -549,6 +620,9 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (0 == argc)
|
if (0 == argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
|
if (0 == invariant_wcscmp(L"ver", argv[0]))
|
||||||
|
return ver(argc, argv);
|
||||||
|
else
|
||||||
if (0 == invariant_wcscmp(L"lsvol", argv[0]))
|
if (0 == invariant_wcscmp(L"lsvol", argv[0]))
|
||||||
return lsvol(argc, argv);
|
return lsvol(argc, argv);
|
||||||
else
|
else
|
||||||
@ -557,6 +631,15 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
else
|
else
|
||||||
if (0 == invariant_wcscmp(L"perm", argv[0]))
|
if (0 == invariant_wcscmp(L"perm", argv[0]))
|
||||||
return perm(argc, argv);
|
return perm(argc, argv);
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"lsdrv", argv[0]))
|
||||||
|
return lsdrv(argc, argv);
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"load", argv[0]))
|
||||||
|
return load(argc, argv);
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"unload", argv[0]))
|
||||||
|
return unload(argc, argv);
|
||||||
else
|
else
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/launchctl.c
|
* @file launcher/launchctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file launcher/ptrans.c
|
* @file launcher/ptrans.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* Shared kernel/user configuration. This file is to be included by the
|
* Shared kernel/user configuration. This file is to be included by the
|
||||||
* FSD and DLL components ONLY!
|
* FSD and DLL components ONLY!
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -30,4 +30,10 @@
|
|||||||
*/
|
*/
|
||||||
#define FSP_CFG_REJECT_EARLY_IRP
|
#define FSP_CFG_REJECT_EARLY_IRP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SxS separator. The '+' in "WinFsp+20220906T173701Z".
|
||||||
|
*/
|
||||||
|
#define FSP_SXS_SEPARATOR_CHAR '+'
|
||||||
|
#define FSP_SXS_SEPARATOR_STRING "+"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/ku/library.h
|
* @file shared/ku/library.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/ku/mountmgr.c
|
* @file shared/ku/mountmgr.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/ku/uuid5.c
|
* @file shared/ku/uuid5.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file shared/um/minimal.h
|
* @file shared/um/minimal.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -154,8 +154,16 @@ NTSTATUS FspReleaseForModWrite(
|
|||||||
|
|
||||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In some rare cases and under load the mapped page writer's TopLevelIrp
|
||||||
|
* may be trashed by some outside component (observed on Windows 10 1909).
|
||||||
|
*/
|
||||||
|
PIRP TopLevelIrp = IoGetTopLevelIrp();
|
||||||
|
IoSetTopLevelIrp((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP);
|
||||||
|
|
||||||
FspFileNodeRelease(FileNode, Full);
|
FspFileNodeRelease(FileNode, Full);
|
||||||
ASSERT((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP == IoGetTopLevelIrp());
|
|
||||||
|
IoSetTopLevelIrp(TopLevelIrp);
|
||||||
|
|
||||||
FSP_LEAVE("FileObject=%p", FileObject);
|
FSP_LEAVE("FileObject=%p", FileObject);
|
||||||
}
|
}
|
||||||
@ -316,7 +324,9 @@ VOID FspPropagateTopFlags(PIRP Irp, PIRP TopLevelIrp)
|
|||||||
FspFileNodeAcquireMain :
|
FspFileNodeAcquireMain :
|
||||||
FspFileNodeAcquireFull);
|
FspFileNodeAcquireFull);
|
||||||
}
|
}
|
||||||
else if ((PIRP)MM_SYSTEM_RANGE_START <= TopLevelIrp && IO_TYPE_IRP == TopLevelIrp->Type)
|
else if ((PIRP)MM_SYSTEM_RANGE_START <= TopLevelIrp &&
|
||||||
|
IO_TYPE_IRP == TopLevelIrp->Type &&
|
||||||
|
TopLevelIrp->CurrentLocation <= TopLevelIrp->StackCount)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
|
PFILE_OBJECT FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
|
||||||
PFILE_OBJECT TopLevelFileObject = IoGetCurrentIrpStackLocation(TopLevelIrp)->FileObject;
|
PFILE_OBJECT TopLevelFileObject = IoGetCurrentIrpStackLocation(TopLevelIrp)->FileObject;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/cleanup.c
|
* @file sys/cleanup.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -298,6 +298,8 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
ULONG CreateOptions = IrpSp->Parameters.Create.Options;
|
ULONG CreateOptions = IrpSp->Parameters.Create.Options;
|
||||||
USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes;
|
USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor;
|
||||||
|
BOOLEAN SecurityDescriptorRelative = 0 != SecurityDescriptor &&
|
||||||
|
BooleanFlagOn(((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Control, SE_SELF_RELATIVE);
|
||||||
ULONG SecurityDescriptorSize = 0;
|
ULONG SecurityDescriptorSize = 0;
|
||||||
UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart;
|
UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart;
|
||||||
UINT64 AllocationUnit;
|
UINT64 AllocationUnit;
|
||||||
@ -406,7 +408,10 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
if (!RtlValidSecurityDescriptor(SecurityDescriptor))
|
if (!RtlValidSecurityDescriptor(SecurityDescriptor))
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
#endif
|
#endif
|
||||||
|
if (SecurityDescriptorRelative)
|
||||||
SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);
|
SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);
|
||||||
|
else
|
||||||
|
RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* align allocation size */
|
/* align allocation size */
|
||||||
@ -702,8 +707,18 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
|
|
||||||
/* copy the security descriptor (if any) into the request */
|
/* copy the security descriptor (if any) into the request */
|
||||||
if (0 != SecurityDescriptorSize)
|
if (0 != SecurityDescriptorSize)
|
||||||
RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
|
{
|
||||||
SecurityDescriptor, SecurityDescriptorSize);
|
if (SecurityDescriptorRelative)
|
||||||
|
RtlCopyMemory(
|
||||||
|
Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset,
|
||||||
|
SecurityDescriptor,
|
||||||
|
SecurityDescriptorSize);
|
||||||
|
else
|
||||||
|
RtlAbsoluteToSelfRelativeSD(
|
||||||
|
SecurityDescriptor,
|
||||||
|
(PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset),
|
||||||
|
&SecurityDescriptorSize);
|
||||||
|
}
|
||||||
|
|
||||||
/* copy the extra buffer (if any) into the request */
|
/* copy the extra buffer (if any) into the request */
|
||||||
if (0 != ExtraBuffer)
|
if (0 != ExtraBuffer)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/debug.c
|
* @file sys/debug.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 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-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -30,6 +30,7 @@ NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize,
|
|||||||
PDEVICE_OBJECT *PDeviceObject);
|
PDEVICE_OBJECT *PDeviceObject);
|
||||||
NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
|
NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
|
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
|
||||||
|
VOID FspDeviceDoIoDeleteDevice(PDEVICE_OBJECT DeviceObject);
|
||||||
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
|
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
|
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
|
||||||
_IRQL_requires_(DISPATCH_LEVEL)
|
_IRQL_requires_(DISPATCH_LEVEL)
|
||||||
@ -67,13 +68,13 @@ NTSTATUS FspDeviceCopyList(
|
|||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||||
VOID FspDeviceDeleteList(
|
VOID FspDeviceDeleteList(
|
||||||
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
||||||
VOID FspDeviceDeleteAll(VOID);
|
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspDeviceCreateSecure)
|
#pragma alloc_text(PAGE, FspDeviceCreateSecure)
|
||||||
#pragma alloc_text(PAGE, FspDeviceCreate)
|
#pragma alloc_text(PAGE, FspDeviceCreate)
|
||||||
#pragma alloc_text(PAGE, FspDeviceInitialize)
|
#pragma alloc_text(PAGE, FspDeviceInitialize)
|
||||||
#pragma alloc_text(PAGE, FspDeviceDelete)
|
#pragma alloc_text(PAGE, FspDeviceDelete)
|
||||||
|
#pragma alloc_text(PAGE, FspDeviceDoIoDeleteDevice)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceInit)
|
#pragma alloc_text(PAGE, FspFsvolDeviceInit)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFini)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextList)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCopyContextList)
|
||||||
@ -92,7 +93,6 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
||||||
#pragma alloc_text(PAGE, FspDeviceDeleteList)
|
#pragma alloc_text(PAGE, FspDeviceDeleteList)
|
||||||
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
||||||
@ -218,12 +218,16 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DBG
|
FspDeviceDoIoDeleteDevice(DeviceObject);
|
||||||
#pragma prefast(suppress:28175, "Debugging only: ok to access DeviceObject->Size")
|
}
|
||||||
RtlFillMemory(&DeviceExtension->Kind,
|
|
||||||
(PUINT8)DeviceObject + DeviceObject->Size - (PUINT8)&DeviceExtension->Kind, 0xBD);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
VOID FspDeviceDoIoDeleteDevice(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
if (0 == InterlockedCompareExchange(&DeviceExtension->DidIoDeleteDevice, 1, 0))
|
||||||
IoDeleteDevice(DeviceObject);
|
IoDeleteDevice(DeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,22 +946,4 @@ VOID FspDeviceDeleteList(
|
|||||||
FspFree(DeviceObjects);
|
FspFree(DeviceObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspDeviceDeleteAll(VOID)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
PDEVICE_OBJECT *DeviceObjects = 0;
|
|
||||||
ULONG DeviceObjectCount = 0;
|
|
||||||
|
|
||||||
Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (ULONG i = 0; DeviceObjectCount > i; i++)
|
|
||||||
FspDeviceDelete(DeviceObjects[i]);
|
|
||||||
|
|
||||||
FspDeviceDeleteList(DeviceObjects, DeviceObjectCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
FAST_MUTEX FspDeviceGlobalMutex;
|
FAST_MUTEX FspDeviceGlobalMutex;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/devtimer.c
|
* @file sys/devtimer.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -55,6 +55,7 @@ NTSTATUS FspDeviceInitializeAllTimers(VOID)
|
|||||||
VOID FspDeviceFinalizeAllTimers(VOID)
|
VOID FspDeviceFinalizeAllTimers(VOID)
|
||||||
{
|
{
|
||||||
KeCancelTimer(&FspDeviceTimer);
|
KeCancelTimer(&FspDeviceTimer);
|
||||||
|
KeFlushQueuedDpcs();
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/dirctl.c
|
* @file sys/dirctl.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -205,6 +205,7 @@ static NTSTATUS FspFsvolQueryDirectoryCopy(
|
|||||||
ASSERT(sizeof(UINT64) == DirectoryMarker->Length);
|
ASSERT(sizeof(UINT64) == DirectoryMarker->Length);
|
||||||
DirectoryMarkerFound = DirectoryNextOffset == *(PUINT64)DirectoryMarker->Buffer;
|
DirectoryMarkerFound = DirectoryNextOffset == *(PUINT64)DirectoryMarker->Buffer;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */
|
/* CopyLength is the same as FileName.Length except on STATUS_BUFFER_OVERFLOW */
|
||||||
|
210
src/sys/driver.c
210
src/sys/driver.c
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.c
|
* @file sys/driver.c
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -22,15 +22,24 @@
|
|||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
DRIVER_INITIALIZE DriverEntry;
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
static DRIVER_UNLOAD DriverUnload;
|
||||||
static VOID FspDriverMultiVersionInitialize(VOID);
|
static VOID FspDriverMultiVersionInitialize(VOID);
|
||||||
static NTSTATUS FspDriverInitializeDevices(VOID);
|
static NTSTATUS FspDriverInitializeDevices(VOID);
|
||||||
static VOID FspDriverFinalizeDevices(VOID);
|
static VOID FspDriverFinalizeDevices(VOID);
|
||||||
|
static VOID FspDriverFinalizeDevicesForUnload(VOID);
|
||||||
|
static VOID FspDriverFinalizeDevicesEx(BOOLEAN DeleteDevices);
|
||||||
|
NTSTATUS FspDriverUnload(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(INIT, DriverEntry)
|
#pragma alloc_text(INIT, DriverEntry)
|
||||||
|
#pragma alloc_text(PAGE, DriverUnload)
|
||||||
#pragma alloc_text(INIT, FspDriverMultiVersionInitialize)
|
#pragma alloc_text(INIT, FspDriverMultiVersionInitialize)
|
||||||
#pragma alloc_text(PAGE, FspDriverInitializeDevices)
|
#pragma alloc_text(PAGE, FspDriverInitializeDevices)
|
||||||
#pragma alloc_text(PAGE, FspDriverFinalizeDevices)
|
#pragma alloc_text(PAGE, FspDriverFinalizeDevices)
|
||||||
|
#pragma alloc_text(PAGE, FspDriverFinalizeDevicesForUnload)
|
||||||
|
#pragma alloc_text(PAGE, FspDriverFinalizeDevicesEx)
|
||||||
|
#pragma alloc_text(PAGE, FspDriverUnload)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NTSTATUS DriverEntry(
|
NTSTATUS DriverEntry(
|
||||||
@ -40,7 +49,10 @@ NTSTATUS DriverEntry(
|
|||||||
|
|
||||||
FSP_TRACE_INIT();
|
FSP_TRACE_INIT();
|
||||||
|
|
||||||
|
FspSxsIdentInitialize(&DriverObject->DriverName);
|
||||||
|
|
||||||
/* setup the driver object */
|
/* setup the driver object */
|
||||||
|
DriverObject->DriverUnload = DriverUnload;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate;
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate;
|
||||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose;
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose;
|
||||||
DriverObject->MajorFunction[IRP_MJ_READ] = FspRead;
|
DriverObject->MajorFunction[IRP_MJ_READ] = FspRead;
|
||||||
@ -128,6 +140,7 @@ NTSTATUS DriverEntry(
|
|||||||
FspDriverObject = DriverObject;
|
FspDriverObject = DriverObject;
|
||||||
FspDriverMultiVersionInitialize();
|
FspDriverMultiVersionInitialize();
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&FspDriverUnloadMutex);
|
||||||
ExInitializeFastMutex(&FspDeviceGlobalMutex);
|
ExInitializeFastMutex(&FspDeviceGlobalMutex);
|
||||||
|
|
||||||
Result = FspSiloInitialize(FspDriverInitializeDevices, FspDriverFinalizeDevices);
|
Result = FspSiloInitialize(FspDriverInitializeDevices, FspDriverFinalizeDevices);
|
||||||
@ -176,6 +189,26 @@ exit:
|
|||||||
&DriverObject->DriverName, RegistryPath);
|
&DriverObject->DriverName, RegistryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID DriverUnload(
|
||||||
|
PDRIVER_OBJECT DriverObject)
|
||||||
|
{
|
||||||
|
FSP_ENTER_VOID(PAGED_CODE());
|
||||||
|
|
||||||
|
FspDriverFinalizeDevices();
|
||||||
|
|
||||||
|
FspDeviceFinalizeAllTimers();
|
||||||
|
|
||||||
|
FspProcessBufferFinalize();
|
||||||
|
|
||||||
|
FspSiloFinalize();
|
||||||
|
|
||||||
|
FSP_TRACE_FINI();
|
||||||
|
|
||||||
|
#pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName")
|
||||||
|
FSP_LEAVE_VOID("DriverName=\"%wZ\"",
|
||||||
|
&DriverObject->DriverName);
|
||||||
|
}
|
||||||
|
|
||||||
static VOID FspDriverMultiVersionInitialize(VOID)
|
static VOID FspDriverMultiVersionInitialize(VOID)
|
||||||
{
|
{
|
||||||
FspProcessorCount = KeQueryActiveProcessorCount(0);
|
FspProcessorCount = KeQueryActiveProcessorCount(0);
|
||||||
@ -206,6 +239,8 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
|
|||||||
FSP_SILO_GLOBALS *Globals;
|
FSP_SILO_GLOBALS *Globals;
|
||||||
UNICODE_STRING DeviceSddl;
|
UNICODE_STRING DeviceSddl;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
|
WCHAR DeviceNameBuf[128];
|
||||||
|
UNICODE_STRING SymlinkName;
|
||||||
GUID Guid;
|
GUID Guid;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
@ -214,20 +249,46 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
|
|||||||
|
|
||||||
/* create the file system control device objects */
|
/* create the file system control device objects */
|
||||||
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
|
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
RtlInitEmptyUnicodeString(&DeviceName, DeviceNameBuf, sizeof DeviceNameBuf);
|
||||||
|
Result = RtlUnicodeStringPrintf(&DeviceName,
|
||||||
|
L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME "%wZ",
|
||||||
|
FspSxsSuffix());
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||||
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||||
&Globals->FsctlDiskDeviceObject);
|
&Globals->FsctlDiskDeviceObject);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
if (0 != FspSxsIdent()->Length)
|
||||||
|
{
|
||||||
|
/* \Device\WinFsp.Disk SxS symlink */
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
Result = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
Globals->InitDoneSymlinkDisk = 1;
|
||||||
|
}
|
||||||
|
RtlInitEmptyUnicodeString(&DeviceName, DeviceNameBuf, sizeof DeviceNameBuf);
|
||||||
|
Result = RtlUnicodeStringPrintf(&DeviceName,
|
||||||
|
L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME "%wZ",
|
||||||
|
FspSxsSuffix());
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||||
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||||
&Globals->FsctlNetDeviceObject);
|
&Globals->FsctlNetDeviceObject);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
if (0 != FspSxsIdent()->Length)
|
||||||
|
{
|
||||||
|
/* \Device\WinFsp.Net SxS symlink */
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||||
|
Result = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
Globals->InitDoneSymlinkNet = 1;
|
||||||
|
}
|
||||||
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
|
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
|
||||||
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
|
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
|
||||||
&Globals->FsmupDeviceObject);
|
&Globals->FsmupDeviceObject);
|
||||||
@ -261,8 +322,9 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
|
|||||||
Result = RtlUnicodeStringPrintf(&DeviceName,
|
Result = RtlUnicodeStringPrintf(&DeviceName,
|
||||||
0 == ((PULONG)&Guid)[0] && 0 == ((PULONG)&Guid)[1] &&
|
0 == ((PULONG)&Guid)[0] && 0 == ((PULONG)&Guid)[1] &&
|
||||||
0 == ((PULONG)&Guid)[2] && 0 == ((PULONG)&Guid)[3] ?
|
0 == ((PULONG)&Guid)[2] && 0 == ((PULONG)&Guid)[3] ?
|
||||||
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME :
|
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "%wZ":
|
||||||
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "%wZ{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||||
|
FspSxsSuffix(),
|
||||||
Guid.Data1, Guid.Data2, Guid.Data3,
|
Guid.Data1, Guid.Data2, Guid.Data3,
|
||||||
Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
|
Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
|
||||||
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
|
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
|
||||||
@ -281,12 +343,25 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
|
|||||||
* as a file system; we register with the MUP instead.
|
* as a file system; we register with the MUP instead.
|
||||||
*/
|
*/
|
||||||
IoRegisterFileSystem(Globals->FsctlDiskDeviceObject);
|
IoRegisterFileSystem(Globals->FsctlDiskDeviceObject);
|
||||||
|
Globals->InitDoneRegisterDisk = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reference primary device objects to allow for IoDeleteDevice during FspDriverUnload.
|
||||||
|
*/
|
||||||
|
ObReferenceObject(Globals->FsctlDiskDeviceObject);
|
||||||
|
ObReferenceObject(Globals->FsctlNetDeviceObject);
|
||||||
|
ObReferenceObject(Globals->FsmupDeviceObject);
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
if (Globals->InitDoneRegisterDisk)
|
||||||
|
{
|
||||||
|
IoUnregisterFileSystem(Globals->FsctlDiskDeviceObject);
|
||||||
|
Globals->InitDoneRegisterDisk = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->MupHandle)
|
if (0 != Globals->MupHandle)
|
||||||
{
|
{
|
||||||
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
||||||
@ -297,11 +372,23 @@ exit:
|
|||||||
FspDeviceDelete(Globals->FsmupDeviceObject);
|
FspDeviceDelete(Globals->FsmupDeviceObject);
|
||||||
Globals->FsmupDeviceObject = 0;
|
Globals->FsmupDeviceObject = 0;
|
||||||
}
|
}
|
||||||
|
if (Globals->InitDoneSymlinkNet)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
Globals->InitDoneSymlinkNet = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->FsctlNetDeviceObject)
|
if (0 != Globals->FsctlNetDeviceObject)
|
||||||
{
|
{
|
||||||
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
||||||
Globals->FsctlNetDeviceObject = 0;
|
Globals->FsctlNetDeviceObject = 0;
|
||||||
}
|
}
|
||||||
|
if (Globals->InitDoneSymlinkDisk)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
Globals->InitDoneSymlinkDisk = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->FsctlDiskDeviceObject)
|
if (0 != Globals->FsctlDiskDeviceObject)
|
||||||
{
|
{
|
||||||
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
||||||
@ -318,40 +405,151 @@ static VOID FspDriverFinalizeDevices(VOID)
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FspDriverFinalizeDevicesEx(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspDriverFinalizeDevicesForUnload(VOID)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FspDriverFinalizeDevicesEx(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspDriverFinalizeDevicesEx(BOOLEAN DeleteDevices)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
FSP_SILO_GLOBALS *Globals;
|
FSP_SILO_GLOBALS *Globals;
|
||||||
|
UNICODE_STRING SymlinkName;
|
||||||
|
|
||||||
FspSiloGetGlobals(&Globals);
|
FspSiloGetGlobals(&Globals);
|
||||||
ASSERT(0 != Globals);
|
ASSERT(0 != Globals);
|
||||||
|
|
||||||
|
if (Globals->InitDoneRegisterDisk)
|
||||||
|
{
|
||||||
IoUnregisterFileSystem(Globals->FsctlDiskDeviceObject);
|
IoUnregisterFileSystem(Globals->FsctlDiskDeviceObject);
|
||||||
|
Globals->InitDoneRegisterDisk = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->MupHandle)
|
if (0 != Globals->MupHandle)
|
||||||
{
|
{
|
||||||
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
||||||
Globals->MupHandle = 0;
|
Globals->MupHandle = 0;
|
||||||
}
|
}
|
||||||
if (0 != Globals->FsmupDeviceObject)
|
if (0 != Globals->FsmupDeviceObject)
|
||||||
|
{
|
||||||
|
if (DeleteDevices)
|
||||||
{
|
{
|
||||||
FspDeviceDelete(Globals->FsmupDeviceObject);
|
FspDeviceDelete(Globals->FsmupDeviceObject);
|
||||||
|
ObDereferenceObject(Globals->FsmupDeviceObject);
|
||||||
Globals->FsmupDeviceObject = 0;
|
Globals->FsmupDeviceObject = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
FspDeviceDoIoDeleteDevice(Globals->FsmupDeviceObject);
|
||||||
|
}
|
||||||
|
if (Globals->InitDoneSymlinkNet)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
Globals->InitDoneSymlinkNet = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->FsctlNetDeviceObject)
|
if (0 != Globals->FsctlNetDeviceObject)
|
||||||
|
{
|
||||||
|
if (DeleteDevices)
|
||||||
{
|
{
|
||||||
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
||||||
|
ObDereferenceObject(Globals->FsctlNetDeviceObject);
|
||||||
Globals->FsctlNetDeviceObject = 0;
|
Globals->FsctlNetDeviceObject = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
FspDeviceDoIoDeleteDevice(Globals->FsctlNetDeviceObject);
|
||||||
|
}
|
||||||
|
if (Globals->InitDoneSymlinkDisk)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
IoDeleteSymbolicLink(&SymlinkName);
|
||||||
|
Globals->InitDoneSymlinkDisk = 0;
|
||||||
|
}
|
||||||
if (0 != Globals->FsctlDiskDeviceObject)
|
if (0 != Globals->FsctlDiskDeviceObject)
|
||||||
|
{
|
||||||
|
if (DeleteDevices)
|
||||||
{
|
{
|
||||||
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
||||||
|
ObDereferenceObject(Globals->FsctlDiskDeviceObject);
|
||||||
Globals->FsctlDiskDeviceObject = 0;
|
Globals->FsctlDiskDeviceObject = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
FspDeviceDoIoDeleteDevice(Globals->FsctlDiskDeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
FspSiloDereferenceGlobals(Globals);
|
FspSiloDereferenceGlobals(Globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspDriverUnload(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_FILE_SYSTEM_CONTROL == IrpSp->MajorFunction);
|
||||||
|
ASSERT(IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction);
|
||||||
|
ASSERT(FSP_FSCTL_UNLOAD == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
UNICODE_STRING DriverServiceName, DriverName, Remain;
|
||||||
|
WCHAR DriverServiceNameBuf[64 + 256];
|
||||||
|
PDEVICE_OBJECT *DeviceObjects = 0;
|
||||||
|
ULONG DeviceObjectCount = 0;
|
||||||
|
|
||||||
|
if (!FspSiloIsHost())
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
|
if (!SeSinglePrivilegeCheck(RtlConvertLongToLuid(SE_LOAD_DRIVER_PRIVILEGE), UserMode))
|
||||||
|
return STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
|
||||||
|
ExAcquireFastMutexUnsafe(&FspDriverUnloadMutex);
|
||||||
|
|
||||||
|
if (!FspDriverUnloadDone)
|
||||||
|
{
|
||||||
|
FspFileNameSuffix(&FspDriverObject->DriverName, &Remain, &DriverName);
|
||||||
|
RtlInitEmptyUnicodeString(&DriverServiceName, DriverServiceNameBuf, sizeof DriverServiceNameBuf);
|
||||||
|
Result = RtlUnicodeStringPrintf(&DriverServiceName,
|
||||||
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%wZ", &DriverName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
Result = ZwUnloadDriver(&DriverServiceName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
FspSiloEnumerate(FspDriverFinalizeDevicesForUnload);
|
||||||
|
FspDriverFinalizeDevicesForUnload();
|
||||||
|
|
||||||
|
Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
for (ULONG I = 0; DeviceObjectCount > I; I++)
|
||||||
|
{
|
||||||
|
FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObjects[I]);
|
||||||
|
if (FspFsvolDeviceExtensionKind == DeviceExtension->Kind)
|
||||||
|
FspIoqStop(((FSP_FSVOL_DEVICE_EXTENSION *)DeviceExtension)->Ioq, FALSE);
|
||||||
|
}
|
||||||
|
FspDeviceDeleteList(DeviceObjects, DeviceObjectCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
FspDriverUnloadDone = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ExReleaseFastMutexUnsafe(&FspDriverUnloadMutex);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
PDRIVER_OBJECT FspDriverObject;
|
PDRIVER_OBJECT FspDriverObject;
|
||||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||||
|
FAST_MUTEX FspDriverUnloadMutex;
|
||||||
|
BOOLEAN FspDriverUnloadDone;
|
||||||
|
|
||||||
ULONG FspProcessorCount;
|
ULONG FspProcessorCount;
|
||||||
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
FSP_MV_CcCoherencyFlushAndPurgeCache *FspMvCcCoherencyFlushAndPurgeCache;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file sys/driver.h
|
* @file sys/driver.h
|
||||||
*
|
*
|
||||||
* @copyright 2015-2022 Bill Zissimopoulos
|
* @copyright 2015-2024 Bill Zissimopoulos
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* This file is part of WinFsp.
|
* This file is part of WinFsp.
|
||||||
@ -364,6 +364,10 @@ VOID FspTraceNtStatus(const char *file, int line, const char *func, NTSTATUS Sta
|
|||||||
/* missing typedef */
|
/* missing typedef */
|
||||||
typedef const void *PCVOID;
|
typedef const void *PCVOID;
|
||||||
|
|
||||||
|
/* driver unload */
|
||||||
|
NTSTATUS FspDriverUnload(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
/* driver major functions */
|
/* driver major functions */
|
||||||
_Function_class_(DRIVER_DISPATCH)
|
_Function_class_(DRIVER_DISPATCH)
|
||||||
_IRQL_requires_max_(APC_LEVEL)
|
_IRQL_requires_max_(APC_LEVEL)
|
||||||
@ -739,23 +743,34 @@ LONG FspCompareUnicodeString(
|
|||||||
PCUNICODE_STRING String2,
|
PCUNICODE_STRING String2,
|
||||||
BOOLEAN CaseInsensitive);
|
BOOLEAN CaseInsensitive);
|
||||||
|
|
||||||
|
/* SxS */
|
||||||
|
VOID FspSxsIdentInitialize(PUNICODE_STRING DriverName);
|
||||||
|
PUNICODE_STRING FspSxsIdent(VOID);
|
||||||
|
PUNICODE_STRING FspSxsSuffix(VOID);
|
||||||
|
|
||||||
/* silos */
|
/* silos */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
PVOID Silo;
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
PDEVICE_OBJECT FsctlDiskDeviceObject;
|
PDEVICE_OBJECT FsctlDiskDeviceObject;
|
||||||
PDEVICE_OBJECT FsctlNetDeviceObject;
|
PDEVICE_OBJECT FsctlNetDeviceObject;
|
||||||
PDEVICE_OBJECT FsmupDeviceObject;
|
PDEVICE_OBJECT FsmupDeviceObject;
|
||||||
HANDLE MupHandle;
|
HANDLE MupHandle;
|
||||||
WCHAR FsmupDeviceNameBuf[64];
|
WCHAR FsmupDeviceNameBuf[128];
|
||||||
|
UINT32 InitDoneSymlinkDisk:1, InitDoneSymlinkNet:1, InitDoneRegisterDisk:1;
|
||||||
} FSP_SILO_GLOBALS;
|
} FSP_SILO_GLOBALS;
|
||||||
typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID);
|
typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID);
|
||||||
typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID);
|
typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID);
|
||||||
|
typedef VOID (*FSP_SILO_ENUM_CALLBACK)(VOID);
|
||||||
|
BOOLEAN FspSiloIsHost(VOID);
|
||||||
NTSTATUS FspSiloGetGlobals(FSP_SILO_GLOBALS **PGlobals);
|
NTSTATUS FspSiloGetGlobals(FSP_SILO_GLOBALS **PGlobals);
|
||||||
VOID FspSiloDereferenceGlobals(FSP_SILO_GLOBALS *Globals);
|
VOID FspSiloDereferenceGlobals(FSP_SILO_GLOBALS *Globals);
|
||||||
VOID FspSiloGetContainerId(GUID *ContainerId);
|
VOID FspSiloGetContainerId(GUID *ContainerId);
|
||||||
NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini);
|
NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini);
|
||||||
NTSTATUS FspSiloPostInitialize(VOID);
|
NTSTATUS FspSiloPostInitialize(VOID);
|
||||||
VOID FspSiloFinalize(VOID);
|
VOID FspSiloFinalize(VOID);
|
||||||
|
VOID FspSiloEnumerate(FSP_SILO_ENUM_CALLBACK EnumFn);
|
||||||
|
|
||||||
/* process buffers */
|
/* process buffers */
|
||||||
#define FspProcessBufferSizeMax (64 * 1024)
|
#define FspProcessBufferSizeMax (64 * 1024)
|
||||||
@ -1182,8 +1197,8 @@ typedef struct
|
|||||||
KSPIN_LOCK SpinLock;
|
KSPIN_LOCK SpinLock;
|
||||||
LONG RefCount;
|
LONG RefCount;
|
||||||
UINT32 Kind;
|
UINT32 Kind;
|
||||||
/* IoTimer emulation */
|
FSP_DEVICE_TIMER DeviceTimer; /* IoTimer emulation */
|
||||||
FSP_DEVICE_TIMER DeviceTimer;
|
LONG DidIoDeleteDevice;
|
||||||
} FSP_DEVICE_EXTENSION;
|
} FSP_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -1285,6 +1300,7 @@ NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize,
|
|||||||
PDEVICE_OBJECT *PDeviceObject);
|
PDEVICE_OBJECT *PDeviceObject);
|
||||||
NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
|
NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
|
VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject);
|
||||||
|
VOID FspDeviceDoIoDeleteDevice(PDEVICE_OBJECT DeviceObject);
|
||||||
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
|
BOOLEAN FspDeviceReference(PDEVICE_OBJECT DeviceObject);
|
||||||
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
|
VOID FspDeviceDereference(PDEVICE_OBJECT DeviceObject);
|
||||||
static inline
|
static inline
|
||||||
@ -1467,7 +1483,6 @@ NTSTATUS FspDeviceCopyList(
|
|||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||||
VOID FspDeviceDeleteList(
|
VOID FspDeviceDeleteList(
|
||||||
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount);
|
||||||
VOID FspDeviceDeleteAll(VOID);
|
|
||||||
NTSTATUS FspDeviceInitializeAllTimers(VOID);
|
NTSTATUS FspDeviceInitializeAllTimers(VOID);
|
||||||
VOID FspDeviceFinalizeAllTimers(VOID);
|
VOID FspDeviceFinalizeAllTimers(VOID);
|
||||||
NTSTATUS FspDeviceInitializeTimer(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS FspDeviceInitializeTimer(PDEVICE_OBJECT DeviceObject,
|
||||||
@ -1999,6 +2014,8 @@ FSP_MV_CcCoherencyFlushAndPurgeCache(
|
|||||||
extern PDRIVER_OBJECT FspDriverObject;
|
extern PDRIVER_OBJECT FspDriverObject;
|
||||||
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
||||||
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||||
|
extern FAST_MUTEX FspDriverUnloadMutex;
|
||||||
|
extern BOOLEAN FspDriverUnloadDone;
|
||||||
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
||||||
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
||||||
extern FAST_MUTEX FspDeviceGlobalMutex;
|
extern FAST_MUTEX FspDeviceGlobalMutex;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user