mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 01:12:58 -05:00
Compare commits
15 Commits
release/1.
...
v1.12B1
Author | SHA1 | Date | |
---|---|---|---|
deee7edded | |||
f41f410546 | |||
a2dc40fe3a | |||
637e8bb8c2 | |||
ec832b45ff | |||
fc03b485f3 | |||
651e45c3ba | |||
95c2fadce0 | |||
b4453c89cc | |||
5483dcbd73 | |||
f1cfe758ec | |||
e9143a73a6 | |||
264450f627 | |||
a731f0e5d8 | |||
d7450d740e |
@ -1,6 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
|
||||||
|
## v1.12B1 (2022.2)
|
||||||
|
|
||||||
|
- [NEW] A new registry setting `MountUseMountmgrFromFSD` has been added. See [WinFsp Registry Settings](https://github.com/winfsp/winfsp/wiki/WinFsp-Registry-Settings) for details.
|
||||||
|
|
||||||
|
- [BUILD] Product configuration for the relative paths to the File System Driver, Network Provider and EventLog is now possible via the file `build.version.props` located in `build\VStudio`.
|
||||||
|
|
||||||
|
|
||||||
## v1.11 (2022+ARM64)
|
## v1.11 (2022+ARM64)
|
||||||
|
|
||||||
- [NEW] ARM64 support! For details see [WinFsp on ARM64](https://github.com/winfsp/winfsp/wiki/WinFsp-on-ARM64).
|
- [NEW] ARM64 support! For details see [WinFsp on ARM64](https://github.com/winfsp/winfsp/wiki/WinFsp-on-ARM64).
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<Import Project="$(MsbuildThisFileDirectory)\build.version.props" />
|
<Import Project="$(MsbuildThisFileDirectory)\build.version.props" />
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601;MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NTDDI_VERSION=0x06010000;_WIN32_WINNT=0x0601;MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid);MyFsctlRegisterPath=$(MyFsctlRegisterPath);MyNpRegisterPath=$(MyNpRegisterPath);MyEventLogRegisterPath=$(MyEventLogRegisterPath)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>MyProductName=$(MyProductName);MyProductFileName=$(MyProductFileName);MyDescription=$(MyDescription);MyCompanyName=$(MyCompanyName);MyCopyright=$(MyCopyright);MyProductVersion=$(MyProductVersion);MyProductStage=$(MyProductStage);MyVersion=$(MyVersion);MyVersionWithCommas=$(MyVersionWithCommas);MyFullVersion=$(MyFullVersion);MyFspFsctlDeviceClassGuid=$(MyFspFsctlDeviceClassGuid);MyFspFsvrtDeviceClassGuid=$(MyFspFsvrtDeviceClassGuid);MyFsctlRegisterPath=$(MyFsctlRegisterPath);MyNpRegisterPath=$(MyNpRegisterPath);MyEventLogRegisterPath=$(MyEventLogRegisterPath)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(IsKernelModeToolset)'=='true'">
|
<ItemDefinitionGroup Condition="'$(IsKernelModeToolset)'=='true'">
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
<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.11</MyCanonicalVersion>
|
<MyCanonicalVersion>1.12</MyCanonicalVersion>
|
||||||
|
|
||||||
<MyProductVersion>2022+ARM64</MyProductVersion>
|
<MyProductVersion>2022.2 Beta1</MyProductVersion>
|
||||||
<MyProductStage>Gold</MyProductStage>
|
<MyProductStage>Beta</MyProductStage>
|
||||||
|
|
||||||
<MyCrossCert>DigiCert High Assurance EV Root CA.crt</MyCrossCert>
|
<MyCrossCert>DigiCertGlobalG3CodeSigningECCSHA3842021CA1.cer</MyCrossCert>
|
||||||
<MyCertIssuer>DigiCert</MyCertIssuer>
|
<MyCertIssuer>DigiCert</MyCertIssuer>
|
||||||
|
|
||||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||||
@ -40,5 +40,37 @@
|
|||||||
<!-- When rebranding WinFsp you MUST change the following GUIDs - use VS "Create GUID" tool -->
|
<!-- When rebranding WinFsp you MUST change the following GUIDs - use VS "Create GUID" tool -->
|
||||||
<MyFspFsctlDeviceClassGuid>{ 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } }</MyFspFsctlDeviceClassGuid>
|
<MyFspFsctlDeviceClassGuid>{ 0x6f9d25fa, 0x6dee, 0x4a9d, { 0x80, 0xf5, 0xe9, 0x8e, 0x14, 0xf3, 0x5e, 0x54 } }</MyFspFsctlDeviceClassGuid>
|
||||||
<MyFspFsvrtDeviceClassGuid>{ 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } }</MyFspFsvrtDeviceClassGuid>
|
<MyFspFsvrtDeviceClassGuid>{ 0xb48171c3, 0xdd50, 0x4852, { 0x83, 0xa3, 0x34, 0x4c, 0x50, 0xd9, 0x3b, 0x17 } }</MyFspFsvrtDeviceClassGuid>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Configure paths used for registration via DllRegisterServer:
|
||||||
|
|
||||||
|
- MyFsctlRegisterPath: File System Driver registration path
|
||||||
|
- MyNpRegisterPath: Network Provider registration path
|
||||||
|
- MyEventLogRegisterPath: Event Log registration path
|
||||||
|
|
||||||
|
These paths are assumed to be relative to the location of the WinFsp DLL during
|
||||||
|
registration: during DLLRegisterServer the DLL uses PathCombineW to combine its own
|
||||||
|
location with these paths to produce the final locations to be used for registration.
|
||||||
|
|
||||||
|
For example, if the DLL location is `C:\Program Files (x86)\WinFsp\bin\winfsp-x64.dll`:
|
||||||
|
|
||||||
|
- Combining with the path "." will produce the original DLL location:
|
||||||
|
`C:\Program Files (x86)\WinFsp\bin\winfsp-x64.dll`
|
||||||
|
|
||||||
|
- Combining with the path "..\\NetworkProvider.dll" will produce:
|
||||||
|
`C:\Program Files (x86)\WinFsp\bin\NetworkProvider.dll`
|
||||||
|
|
||||||
|
- For Network Provider registrations only it is allowed to use environment variables
|
||||||
|
in the path. For example combining the above DLL location with the path
|
||||||
|
"..\\NetworkProvider-\x25PROCESSOR_ARCHITECTURE\x25.dll" will produce:
|
||||||
|
`C:\Program Files (x86)\WinFsp\bin\NetworkProvider-%PROCESSOR_ARCHITECTURE%.dll`
|
||||||
|
|
||||||
|
(Note that the \x25 escape sequence must be used otherwise the VS build system will
|
||||||
|
try to interpret the string %PROCESSOR_ARCHITECTURE% as an environment variable during
|
||||||
|
the build.)
|
||||||
|
-->
|
||||||
|
<MyFsctlRegisterPath>"."</MyFsctlRegisterPath>
|
||||||
|
<MyNpRegisterPath>"."</MyNpRegisterPath>
|
||||||
|
<MyEventLogRegisterPath>"."</MyEventLogRegisterPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
@ -75,6 +75,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\service.c" />
|
<ClCompile Include="..\..\src\dll\service.c" />
|
||||||
<ClCompile Include="..\..\src\dll\util.c" />
|
<ClCompile Include="..\..\src\dll\util.c" />
|
||||||
<ClCompile Include="..\..\src\dll\wksid.c" />
|
<ClCompile Include="..\..\src\dll\wksid.c" />
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -287,7 +288,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -314,7 +315,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -341,7 +342,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -371,7 +372,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
||||||
</Link>
|
</Link>
|
||||||
@ -402,7 +403,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
||||||
</Link>
|
</Link>
|
||||||
@ -433,7 +434,7 @@ copy /b $(OutDir)fuse3-$(MyProductFileArch).pc + %(FullPath) $(OutDir)fuse3-$(My
|
|||||||
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
<MapFileName>$(OutDir)$(TargetFileName).map</MapFileName>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>..\..\src\dll\library.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;credui.lib;secur32.lib;version.lib;netapi32.lib;wldap32.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);credui.lib;netapi32.lib;rpcrt4.lib;secur32.lib;shlwapi.lib;version.lib;wldap32.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetFileName).public.pdb</StripPrivateSymbols>
|
||||||
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/PDBALTPATH:$(TargetFileName).pdb %(AdditionalOptions)</AdditionalOptions>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -175,6 +175,9 @@
|
|||||||
<ClCompile Include="..\..\src\dll\debug.c">
|
<ClCompile Include="..\..\src\dll\debug.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
|
<Filter>Source\shared\ku</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\library.def">
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
@ -228,6 +228,7 @@
|
|||||||
<FilesToPackage Include="$(TargetPath)" />
|
<FilesToPackage Include="$(TargetPath)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
<ClCompile Include="..\..\src\shared\ku\posix.c" />
|
||||||
<ClCompile Include="..\..\src\shared\ku\uuid5.c" />
|
<ClCompile Include="..\..\src\shared\ku\uuid5.c" />
|
||||||
<ClCompile Include="..\..\src\sys\cleanup.c" />
|
<ClCompile Include="..\..\src\sys\cleanup.c" />
|
||||||
|
@ -131,6 +131,9 @@
|
|||||||
<ClCompile Include="..\..\src\sys\devtimer.c">
|
<ClCompile Include="..\..\src\sys\devtimer.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\shared\ku\mountmgr.c">
|
||||||
|
<Filter>Source\shared\ku</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -71,6 +71,8 @@ Primary registry key used to store WinFsp settings. On a 64-bit system (x64 or A
|
|||||||
|
|
||||||
* `MountDoNotUseLauncher (REG_DWORD)`: A value of 1 disallows the use of the Launcher for drive mounting. The default value of 0 allows use of the Launcher for drive mounting when necessary. In general the Launcher is not necessary for mounting. However when running a file system in the Windows Service context (session 0) under an account that is not LocalSystem (e.g. `NT AUTHORITY\NETWORK SERVICE`), the Launcher is used to create global drives.
|
* `MountDoNotUseLauncher (REG_DWORD)`: A value of 1 disallows the use of the Launcher for drive mounting. The default value of 0 allows use of the Launcher for drive mounting when necessary. In general the Launcher is not necessary for mounting. However when running a file system in the Windows Service context (session 0) under an account that is not LocalSystem (e.g. `NT AUTHORITY\NETWORK SERVICE`), the Launcher is used to create global drives.
|
||||||
|
|
||||||
|
* `MountUseMountmgrFromFSD (REG_DWORD)`: A value of 1 instructs WinFsp to use the Mount Manager from the FSD (File System Driver) which runs in kernel mode. The default value of 0 instructs WinFsp to use the Mount Manager from the DLL which runs in user mode. Using the Mount Manager from user mode requires Administrator access and this setting allows a file system to circumvent the Administrator access requirement. This setting is not recommended for general use.
|
||||||
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -91,6 +91,8 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
/* fsctl device codes */
|
/* fsctl device codes */
|
||||||
#define FSP_FSCTL_MOUNTDEV \
|
#define FSP_FSCTL_MOUNTDEV \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'M', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
|
#define FSP_FSCTL_MOUNTMGR \
|
||||||
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'm', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_VOLUME_NAME \
|
#define FSP_FSCTL_VOLUME_NAME \
|
||||||
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'N', METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||||
#define FSP_FSCTL_VOLUME_LIST \
|
#define FSP_FSCTL_VOLUME_LIST \
|
||||||
@ -226,7 +228,7 @@ enum
|
|||||||
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
|
UINT32 CasePreservedExtendedAttributes:1; /* preserve case of EA (default is UPPERCASE) */\
|
||||||
UINT32 WslFeatures:1; /* support features required for WSLinux */\
|
UINT32 WslFeatures:1; /* support features required for WSLinux */\
|
||||||
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\
|
UINT32 DirectoryMarkerAsNextOffset:1; /* directory marker is next offset instead of last name */\
|
||||||
UINT32 RejectIrpPriorToTransact0:1; /* reject IRP's prior to FspFsctlTransact with 0 buffers */\
|
UINT32 RejectIrpPriorToTransact0:1; /* DEPRECATED: reject IRP's prior to FspFsctlTransact0 */\
|
||||||
UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\
|
UINT32 SupportsPosixUnlinkRename:1; /* file system supports POSIX-style unlink and rename */\
|
||||||
UINT32 PostDispositionWhenNecessaryOnly:1; /* post Disposition for dirs or READONLY attr check */\
|
UINT32 PostDispositionWhenNecessaryOnly:1; /* post Disposition for dirs or READONLY attr check */\
|
||||||
UINT32 KmReservedFlags:1;\
|
UINT32 KmReservedFlags:1;\
|
||||||
@ -679,6 +681,8 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
|||||||
PHANDLE PVolumeHandle);
|
PHANDLE PVolumeHandle);
|
||||||
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
||||||
BOOLEAN Persistent, GUID *UniqueId);
|
BOOLEAN Persistent, GUID *UniqueId);
|
||||||
|
FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle,
|
||||||
|
PWSTR MountPoint);
|
||||||
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
||||||
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
||||||
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
||||||
|
@ -100,9 +100,11 @@ NTSTATUS FspEventLogRegister(VOID)
|
|||||||
WCHAR Path[MAX_PATH];
|
WCHAR Path[MAX_PATH];
|
||||||
DWORD RegResult, DwordValue;
|
DWORD RegResult, DwordValue;
|
||||||
HKEY RegKey;
|
HKEY RegKey;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == GetModuleFileNameW(DllInstance, Path, MAX_PATH))
|
Result = FspGetModuleFileName(DllInstance, Path, MAX_PATH, L"" MyEventLogRegisterPath);
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
RegResult = RegCreateKeyExW(
|
RegResult = RegCreateKeyExW(
|
||||||
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" FSP_EVENTLOG_NAME,
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" FSP_EVENTLOG_NAME,
|
||||||
|
@ -130,6 +130,22 @@ FSP_API NTSTATUS FspFsctlMakeMountdev(HANDLE VolumeHandle,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlUseMountmgr(HANDLE VolumeHandle,
|
||||||
|
PWSTR MountPoint)
|
||||||
|
{
|
||||||
|
DWORD Bytes;
|
||||||
|
|
||||||
|
Bytes = 0 != MountPoint ? lstrlenW(MountPoint) * sizeof(WCHAR) : 0;
|
||||||
|
|
||||||
|
if (!DeviceIoControl(VolumeHandle,
|
||||||
|
FSP_FSCTL_MOUNTMGR,
|
||||||
|
MountPoint, Bytes, 0, 0,
|
||||||
|
&Bytes, 0))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
||||||
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
PVOID ResponseBuf, SIZE_T ResponseBufSize,
|
||||||
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
PVOID RequestBuf, SIZE_T *PRequestBufSize,
|
||||||
@ -568,8 +584,9 @@ NTSTATUS FspFsctlRegister(VOID)
|
|||||||
SERVICE_DESCRIPTION ServiceDescription;
|
SERVICE_DESCRIPTION ServiceDescription;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == GetModuleFileNameW(DllInstance, DriverPath, MAX_PATH))
|
Result = FspGetModuleFileName(DllInstance, DriverPath, MAX_PATH, L"" MyFsctlRegisterPath);
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
Size = lstrlenW(DriverPath);
|
Size = lstrlenW(DriverPath);
|
||||||
if (4 < Size &&
|
if (4 < Size &&
|
||||||
@ -583,6 +600,14 @@ NTSTATUS FspFsctlRegister(VOID)
|
|||||||
DriverPath[Size - 2] = L'y';
|
DriverPath[Size - 2] = L'y';
|
||||||
DriverPath[Size - 1] = L's';
|
DriverPath[Size - 1] = L's';
|
||||||
}
|
}
|
||||||
|
else if (4 < Size &&
|
||||||
|
(L'.' == DriverPath[Size - 4]) &&
|
||||||
|
(L'S' == DriverPath[Size - 3] || L's' == DriverPath[Size - 3]) &&
|
||||||
|
(L'Y' == DriverPath[Size - 2] || L'y' == DriverPath[Size - 2]) &&
|
||||||
|
(L'S' == DriverPath[Size - 1] || L's' == DriverPath[Size - 1]) &&
|
||||||
|
(L'\0' == DriverPath[Size]))
|
||||||
|
{
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* should not happen! */
|
/* should not happen! */
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
|
@ -73,6 +73,15 @@ NTSTATUS FspEventLogUnregister(VOID);
|
|||||||
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);
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
ULONG FspLdapConnect(PWSTR HostName, PVOID *PLdap);
|
ULONG FspLdapConnect(PWSTR HostName, PVOID *PLdap);
|
||||||
VOID FspLdapClose(PVOID Ldap);
|
VOID FspLdapClose(PVOID Ldap);
|
||||||
ULONG FspLdapGetValue(PVOID Ldap, PWSTR Base, ULONG Scope, PWSTR Filter, PWSTR Attribute,
|
ULONG FspLdapGetValue(PVOID Ldap, PWSTR Base, ULONG Scope, PWSTR Filter, PWSTR Attribute,
|
||||||
@ -82,6 +91,11 @@ ULONG FspLdapGetTrustPosixOffset(PVOID Ldap, PWSTR Context, PWSTR Domain, PWSTR
|
|||||||
|
|
||||||
PWSTR FspDiagIdent(VOID);
|
PWSTR FspDiagIdent(VOID);
|
||||||
NTSTATUS FspGetModuleVersion(PWSTR ModuleFileName, PUINT32 PVersion);
|
NTSTATUS FspGetModuleVersion(PWSTR ModuleFileName, PUINT32 PVersion);
|
||||||
|
NTSTATUS FspGetModuleFileName(
|
||||||
|
HMODULE Module,
|
||||||
|
PWSTR FileName,
|
||||||
|
ULONG Size,
|
||||||
|
PWSTR RelativePath);
|
||||||
|
|
||||||
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
||||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
@ -126,6 +140,12 @@ static inline BOOLEAN FspPathIsMountmgrMountPoint(PWSTR FileName)
|
|||||||
) &&
|
) &&
|
||||||
L':' == FileName[5];
|
L':' == FileName[5];
|
||||||
}
|
}
|
||||||
|
static inline BOOLEAN FspPathIsMountmgrDrive(PWSTR FileName)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
FspPathIsMountmgrMountPoint(FileName) &&
|
||||||
|
L'\0' == FileName[6];
|
||||||
|
}
|
||||||
|
|
||||||
#define FSP_NEXT_EA(Ea, EaEnd) \
|
#define FSP_NEXT_EA(Ea, EaEnd) \
|
||||||
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
|
(0 != (Ea)->NextEntryOffset ? (PVOID)((PUINT8)(Ea) + (Ea)->NextEntryOffset) : (EaEnd))
|
||||||
|
360
src/dll/mount.c
360
src/dll/mount.c
@ -31,6 +31,7 @@ static NTSTATUS (NTAPI *FspNtClose)(
|
|||||||
HANDLE Handle);
|
HANDLE Handle);
|
||||||
static BOOLEAN FspMountDoNotUseLauncherValue;
|
static BOOLEAN FspMountDoNotUseLauncherValue;
|
||||||
static BOOLEAN FspMountBroadcastDriveChangeValue;
|
static BOOLEAN FspMountBroadcastDriveChangeValue;
|
||||||
|
static BOOLEAN FspMountUseMountmgrFromFSDValue;
|
||||||
|
|
||||||
static VOID FspMountInitializeFromRegistry(VOID)
|
static VOID FspMountInitializeFromRegistry(VOID)
|
||||||
{
|
{
|
||||||
@ -53,6 +54,14 @@ static VOID FspMountInitializeFromRegistry(VOID)
|
|||||||
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
||||||
if (ERROR_SUCCESS == Result)
|
if (ERROR_SUCCESS == Result)
|
||||||
FspMountBroadcastDriveChangeValue = !!Value;
|
FspMountBroadcastDriveChangeValue = !!Value;
|
||||||
|
|
||||||
|
Value = 0;
|
||||||
|
Size = sizeof Value;
|
||||||
|
Result = RegGetValueW(HKEY_LOCAL_MACHINE, L"" FSP_FSCTL_PRODUCT_FULL_REGKEY,
|
||||||
|
L"MountUseMountmgrFromFSD",
|
||||||
|
RRF_RT_REG_DWORD, 0, &Value, &Size);
|
||||||
|
if (ERROR_SUCCESS == Result)
|
||||||
|
FspMountUseMountmgrFromFSDValue = !!Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL WINAPI FspMountInitialize(
|
static BOOL WINAPI FspMountInitialize(
|
||||||
@ -80,93 +89,17 @@ static BOOL WINAPI FspMountInitialize(
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
static NTSTATUS FspMountSet_Directory(PWSTR VolumeName, PWSTR MountPoint,
|
||||||
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle);
|
||||||
|
static NTSTATUS FspMountRemove_Directory(HANDLE MountHandle);
|
||||||
|
|
||||||
|
static NTSTATUS FspMountSet_MountmgrDrive(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
|
||||||
{
|
{
|
||||||
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
DWORD Bytes = 0;
|
/* use MountManager from FSD and exit */
|
||||||
NTSTATUS Result;
|
return FspFsctlUseMountmgr(VolumeHandle, MountPoint + 4);
|
||||||
|
|
||||||
if (0 == POutputBufferLength)
|
|
||||||
POutputBufferLength = &Bytes;
|
|
||||||
|
|
||||||
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
0,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
if (INVALID_HANDLE_VALUE == MgrHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceIoControl(MgrHandle,
|
|
||||||
IoControlCode,
|
|
||||||
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
|
|
||||||
&Bytes, 0))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
*POutputBufferLength = Bytes;
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
if (INVALID_HANDLE_VALUE != MgrHandle)
|
|
||||||
CloseHandle(MgrHandle);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint)
|
|
||||||
{
|
|
||||||
/* only support drives for now! (format: \\.\X:) */
|
|
||||||
if (L'\0' != MountPoint[6])
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
/* mountmgr.h */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
Disabled = 0,
|
|
||||||
Enabled,
|
|
||||||
} MOUNTMGR_AUTO_MOUNT_STATE;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MOUNTMGR_AUTO_MOUNT_STATE CurrentState;
|
|
||||||
} MOUNTMGR_QUERY_AUTO_MOUNT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
MOUNTMGR_AUTO_MOUNT_STATE NewState;
|
|
||||||
} MOUNTMGR_SET_AUTO_MOUNT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
WCHAR DeviceName[1];
|
|
||||||
} MOUNTMGR_TARGET_NAME;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
USHORT SymbolicLinkNameOffset;
|
|
||||||
USHORT SymbolicLinkNameLength;
|
|
||||||
USHORT DeviceNameOffset;
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
} MOUNTMGR_CREATE_POINT_INPUT;
|
|
||||||
|
|
||||||
GUID UniqueId;
|
GUID UniqueId;
|
||||||
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
|
||||||
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
|
||||||
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
|
||||||
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
|
|
||||||
ULONG VolumeNameSize, QueryAutoMountSize, TargetNameSize, CreatePointInputSize;
|
|
||||||
HKEY RegKey;
|
|
||||||
LONG RegResult;
|
|
||||||
WCHAR RegValueName[MAX_PATH];
|
|
||||||
UINT8 RegValueData[sizeof UniqueId];
|
|
||||||
DWORD RegValueNameSize, RegValueDataSize;
|
|
||||||
DWORD RegType;
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
/* transform our volume into one that can be used by the MountManager */
|
/* transform our volume into one that can be used by the MountManager */
|
||||||
@ -174,190 +107,115 @@ static NTSTATUS FspMountSet_Mountmgr(HANDLE VolumeHandle, PWSTR VolumeName, PWST
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
VolumeNameSize = lstrlenW(VolumeName) * sizeof(WCHAR);
|
/* use the MountManager to create the drive */
|
||||||
QueryAutoMountSize = sizeof QueryAutoMount;
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeNameSize;
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
CreatePointInputSize = sizeof *CreatePointInput +
|
UVolumeName.Buffer = VolumeName;
|
||||||
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeNameSize;
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
TargetName = MemAlloc(TargetNameSize);
|
Result = FspMountmgrCreateDrive(&UVolumeName, &UniqueId, &UMountPoint);
|
||||||
if (0 == TargetName)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatePointInput = MemAlloc(CreatePointInputSize);
|
|
||||||
if (0 == CreatePointInput)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* query the current AutoMount value and save it */
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */
|
|
||||||
0, 0, &QueryAutoMount, &QueryAutoMountSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
/* disable AutoMount */
|
|
||||||
SetAutoMount.NewState = 0;
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
|
||||||
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* announce volume arrival */
|
|
||||||
memset(TargetName, 0, sizeof *TargetName);
|
|
||||||
TargetName->DeviceNameLength = (USHORT)VolumeNameSize;
|
|
||||||
memcpy(TargetName->DeviceName,
|
|
||||||
VolumeName, TargetName->DeviceNameLength);
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */
|
|
||||||
TargetName, TargetNameSize, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* reset the AutoMount value to the saved one */
|
|
||||||
SetAutoMount.NewState = QueryAutoMount.CurrentState;
|
|
||||||
FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
|
||||||
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
|
||||||
#if 0
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* create mount point */
|
|
||||||
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
|
||||||
CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput;
|
|
||||||
CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
|
||||||
CreatePointInput->DeviceNameOffset =
|
|
||||||
CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength;
|
|
||||||
CreatePointInput->DeviceNameLength = (USHORT)VolumeNameSize;
|
|
||||||
memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset,
|
|
||||||
L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength);
|
|
||||||
((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] =
|
|
||||||
MountPoint[4] & ~0x20;
|
|
||||||
/* convert to uppercase */
|
|
||||||
memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset,
|
|
||||||
VolumeName, CreatePointInput->DeviceNameLength);
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_CREATE_POINT */
|
|
||||||
CreatePointInput, CreatePointInputSize, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
/* HACK: delete the MountManager registry entries */
|
|
||||||
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\MountedDevices",
|
|
||||||
0, KEY_READ | KEY_WRITE, &RegKey);
|
|
||||||
if (ERROR_SUCCESS == RegResult)
|
|
||||||
{
|
|
||||||
for (DWORD I = 0;; I++)
|
|
||||||
{
|
|
||||||
RegValueNameSize = MAX_PATH;
|
|
||||||
RegValueDataSize = sizeof RegValueData;
|
|
||||||
RegResult = RegEnumValueW(RegKey,
|
|
||||||
I, RegValueName, &RegValueNameSize, 0, &RegType, RegValueData, &RegValueDataSize);
|
|
||||||
if (ERROR_NO_MORE_ITEMS == RegResult)
|
|
||||||
break;
|
|
||||||
else if (ERROR_SUCCESS != RegResult)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (REG_BINARY == RegType &&
|
|
||||||
sizeof RegValueData == RegValueDataSize &&
|
|
||||||
InlineIsEqualGUID((GUID *)&RegValueData, &UniqueId))
|
|
||||||
{
|
|
||||||
RegResult = RegDeleteValueW(RegKey, RegValueName);
|
|
||||||
if (ERROR_SUCCESS == RegResult)
|
|
||||||
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
|
||||||
I = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegCloseKey(RegKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MemFree(CreatePointInput);
|
return Result;
|
||||||
MemFree(TargetName);
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountSet_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE PMountHandle)
|
||||||
|
{
|
||||||
|
GUID UniqueId;
|
||||||
|
HANDLE MountHandle = INVALID_HANDLE_VALUE;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PMountHandle = 0;
|
||||||
|
|
||||||
|
/* create the directory mount point */
|
||||||
|
Result = FspMountSet_Directory(VolumeName, MountPoint + 4, SecurityDescriptor, &MountHandle);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
|
{
|
||||||
|
/* use MountManager from FSD and exit */
|
||||||
|
Result = FspFsctlUseMountmgr(VolumeHandle, MountPoint + 4);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
*PMountHandle = MountHandle;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* transform our volume into one that can be used by the MountManager */
|
||||||
|
Result = FspFsctlMakeMountdev(VolumeHandle, FALSE, &UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* notify the MountManager about the created directory mount point */
|
||||||
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
|
UVolumeName.Buffer = VolumeName;
|
||||||
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
Result = FspMountmgrNotifyCreateDirectory(&UVolumeName, &UniqueId, &UMountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
*PMountHandle = MountHandle;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result) && INVALID_HANDLE_VALUE != MountHandle)
|
||||||
|
FspMountRemove_Directory(MountHandle);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspMountRemove_Mountmgr(PWSTR MountPoint)
|
static NTSTATUS FspMountRemove_MountmgrDrive(HANDLE VolumeHandle, PWSTR MountPoint)
|
||||||
{
|
{
|
||||||
/* mountmgr.h */
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
typedef struct
|
/* use MountManager from FSD and exit */
|
||||||
{
|
return FspFsctlUseMountmgr(VolumeHandle, 0);
|
||||||
ULONG SymbolicLinkNameOffset;
|
|
||||||
USHORT SymbolicLinkNameLength;
|
|
||||||
USHORT Reserved1;
|
|
||||||
ULONG UniqueIdOffset;
|
|
||||||
USHORT UniqueIdLength;
|
|
||||||
USHORT Reserved2;
|
|
||||||
ULONG DeviceNameOffset;
|
|
||||||
USHORT DeviceNameLength;
|
|
||||||
USHORT Reserved3;
|
|
||||||
} MOUNTMGR_MOUNT_POINT;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ULONG Size;
|
|
||||||
ULONG NumberOfMountPoints;
|
|
||||||
MOUNTMGR_MOUNT_POINT MountPoints[1];
|
|
||||||
} MOUNTMGR_MOUNT_POINTS;
|
|
||||||
|
|
||||||
MOUNTMGR_MOUNT_POINT *Input = 0;
|
/* use the MountManager to delete the drive */
|
||||||
MOUNTMGR_MOUNT_POINTS *Output = 0;
|
UNICODE_STRING UMountPoint;
|
||||||
ULONG InputSize, OutputSize;
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
return FspMountmgrDeleteDrive(&UMountPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountRemove_MountmgrDirectory(HANDLE VolumeHandle, PWSTR VolumeName, PWSTR MountPoint,
|
||||||
|
HANDLE MountHandle)
|
||||||
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
if (FspMountUseMountmgrFromFSDValue)
|
||||||
OutputSize = 4096;
|
/* use MountManager from FSD, but do not exit; additional processing is required below */
|
||||||
|
FspFsctlUseMountmgr(VolumeHandle, 0);
|
||||||
Input = MemAlloc(InputSize);
|
else
|
||||||
if (0 == Input)
|
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
/* notify the MountManager about the deleted directory mount point */
|
||||||
goto exit;
|
UNICODE_STRING UVolumeName, UMountPoint;
|
||||||
|
UVolumeName.Length = UVolumeName.MaximumLength = (USHORT)(lstrlenW(VolumeName) * sizeof(WCHAR));
|
||||||
|
UVolumeName.Buffer = VolumeName;
|
||||||
|
UMountPoint.Length = UMountPoint.MaximumLength = (USHORT)((lstrlenW(MountPoint) - 4) * sizeof(WCHAR));
|
||||||
|
UMountPoint.Buffer = MountPoint + 4;
|
||||||
|
FspMountmgrNotifyDeleteDirectory(&UVolumeName, &UMountPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Output = MemAlloc(OutputSize);
|
/* delete the directory mount point */
|
||||||
if (0 == Output)
|
Result = FspMountRemove_Directory(MountHandle);
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(Input, 0, sizeof *Input);
|
|
||||||
Input->SymbolicLinkNameOffset = sizeof *Input;
|
|
||||||
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
|
||||||
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
|
|
||||||
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
|
|
||||||
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] = MountPoint[4] & ~0x20;
|
|
||||||
/* convert to uppercase */
|
|
||||||
Result = FspMountmgrControl(
|
|
||||||
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
|
||||||
/* IOCTL_MOUNTMGR_DELETE_POINTS */
|
|
||||||
Input, InputSize, Output, &OutputSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MemFree(Output);
|
|
||||||
MemFree(Input);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,8 +598,11 @@ FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc)
|
|||||||
Desc->MountPoint[0] = L'*';
|
Desc->MountPoint[0] = L'*';
|
||||||
return STATUS_NO_SUCH_DEVICE;
|
return STATUS_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
|
else if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
||||||
|
return FspMountSet_MountmgrDrive(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint);
|
||||||
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
||||||
return FspMountSet_Mountmgr(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint);
|
return FspMountSet_MountmgrDirectory(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint,
|
||||||
|
Desc->Security, &Desc->MountHandle);
|
||||||
else if (FspPathIsDrive(Desc->MountPoint))
|
else if (FspPathIsDrive(Desc->MountPoint))
|
||||||
return FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
|
return FspMountSet_Drive(Desc->VolumeName, Desc->MountPoint,
|
||||||
&Desc->MountHandle);
|
&Desc->MountHandle);
|
||||||
@ -754,8 +615,11 @@ FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc)
|
|||||||
{
|
{
|
||||||
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
InitOnceExecuteOnce(&FspMountInitOnce, FspMountInitialize, 0, 0);
|
||||||
|
|
||||||
if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
if (FspPathIsMountmgrDrive(Desc->MountPoint))
|
||||||
return FspMountRemove_Mountmgr(Desc->MountPoint);
|
return FspMountRemove_MountmgrDrive(Desc->VolumeHandle, Desc->MountPoint);
|
||||||
|
else if (FspPathIsMountmgrMountPoint(Desc->MountPoint))
|
||||||
|
return FspMountRemove_MountmgrDirectory(Desc->VolumeHandle, Desc->VolumeName, Desc->MountPoint,
|
||||||
|
Desc->MountHandle);
|
||||||
else if (FspPathIsDrive(Desc->MountPoint))
|
else if (FspPathIsDrive(Desc->MountPoint))
|
||||||
return FspMountRemove_Drive(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
return FspMountRemove_Drive(Desc->VolumeName, Desc->MountPoint, Desc->MountHandle);
|
||||||
else
|
else
|
||||||
|
32
src/dll/np.c
32
src/dll/np.c
@ -1152,15 +1152,34 @@ DWORD APIENTRY NPCloseEnum(HANDLE hEnum)
|
|||||||
NTSTATUS FspNpRegister(VOID)
|
NTSTATUS FspNpRegister(VOID)
|
||||||
{
|
{
|
||||||
extern HINSTANCE DllInstance;
|
extern HINSTANCE DllInstance;
|
||||||
WCHAR ProviderPath[MAX_PATH];
|
WCHAR DllPath[MAX_PATH], ProviderPath[MAX_PATH];
|
||||||
|
PWSTR VersionInfoPath;
|
||||||
|
BOOLEAN HasPercent;
|
||||||
WCHAR RegBuffer[1024];
|
WCHAR RegBuffer[1024];
|
||||||
PWSTR P, Part;
|
PWSTR P, Part;
|
||||||
DWORD RegResult, RegType, RegBufferSize, RegBufferOffset;
|
DWORD RegResult, RegType, RegBufferSize, RegBufferOffset;
|
||||||
HKEY RegKey;
|
HKEY RegKey;
|
||||||
BOOLEAN FoundProvider;
|
BOOLEAN FoundProvider;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
if (0 == GetModuleFileNameW(DllInstance, ProviderPath, MAX_PATH))
|
VersionInfoPath = ProviderPath;
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
HasPercent = FALSE;
|
||||||
|
for (P = L"" MyNpRegisterPath; *P; P++)
|
||||||
|
if ('%' == *P)
|
||||||
|
{
|
||||||
|
HasPercent = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (HasPercent)
|
||||||
|
{
|
||||||
|
VersionInfoPath = DllPath;
|
||||||
|
if (0 == GetModuleFileNameW(DllInstance, DllPath, MAX_PATH))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspGetModuleFileName(DllInstance, ProviderPath, MAX_PATH, L"" MyNpRegisterPath);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
RegResult = RegCreateKeyExW(
|
RegResult = RegCreateKeyExW(
|
||||||
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME,
|
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\" FSP_NP_NAME,
|
||||||
@ -1187,12 +1206,12 @@ NTSTATUS FspNpRegister(VOID)
|
|||||||
DWORD Size;
|
DWORD Size;
|
||||||
PWSTR Description;
|
PWSTR Description;
|
||||||
|
|
||||||
Size = GetFileVersionInfoSizeW(ProviderPath, &Size/*dummy*/);
|
Size = GetFileVersionInfoSizeW(VersionInfoPath, &Size/*dummy*/);
|
||||||
if (0 < Size)
|
if (0 < Size)
|
||||||
{
|
{
|
||||||
VersionInfo = MemAlloc(Size);
|
VersionInfo = MemAlloc(Size);
|
||||||
if (0 != VersionInfo &&
|
if (0 != VersionInfo &&
|
||||||
GetFileVersionInfoW(ProviderPath, 0, Size, VersionInfo) &&
|
GetFileVersionInfoW(VersionInfoPath, 0, Size, VersionInfo) &&
|
||||||
VerQueryValueW(VersionInfo, L"\\StringFileInfo\\040904b0\\FileDescription",
|
VerQueryValueW(VersionInfo, L"\\StringFileInfo\\040904b0\\FileDescription",
|
||||||
&Description, &Size))
|
&Description, &Size))
|
||||||
{
|
{
|
||||||
@ -1208,7 +1227,8 @@ NTSTATUS FspNpRegister(VOID)
|
|||||||
goto close_and_exit;
|
goto close_and_exit;
|
||||||
|
|
||||||
RegResult = RegSetValueExW(RegKey,
|
RegResult = RegSetValueExW(RegKey,
|
||||||
L"ProviderPath", 0, REG_SZ, (PVOID)ProviderPath, (lstrlenW(ProviderPath) + 1) * sizeof(WCHAR));
|
L"ProviderPath", 0, HasPercent ? REG_EXPAND_SZ : REG_SZ,
|
||||||
|
(PVOID)ProviderPath, (lstrlenW(ProviderPath) + 1) * sizeof(WCHAR));
|
||||||
if (ERROR_SUCCESS != RegResult)
|
if (ERROR_SUCCESS != RegResult)
|
||||||
goto close_and_exit;
|
goto close_and_exit;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
#include <aclapi.h>
|
#include <aclapi.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
|
||||||
static INIT_ONCE FspDiagIdentInitOnce = INIT_ONCE_STATIC_INIT;
|
static INIT_ONCE FspDiagIdentInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
static WCHAR FspDiagIdentBuf[20] = L"UNKNOWN";
|
static WCHAR FspDiagIdentBuf[20] = L"UNKNOWN";
|
||||||
@ -248,3 +249,33 @@ NTSTATUS FspGetModuleVersion(PWSTR ModuleFileName, PUINT32 PVersion)
|
|||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspGetModuleFileName(
|
||||||
|
HMODULE Module,
|
||||||
|
PWSTR FileName,
|
||||||
|
ULONG Size,
|
||||||
|
PWSTR RelativePath)
|
||||||
|
{
|
||||||
|
if (MAX_PATH > Size)
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
if (0 != RelativePath &&
|
||||||
|
L'\0' != RelativePath[0] &&
|
||||||
|
(L'.' != RelativePath[0] || L'\0' != RelativePath[1]))
|
||||||
|
{
|
||||||
|
WCHAR Temp[MAX_PATH];
|
||||||
|
|
||||||
|
if (0 == GetModuleFileNameW(Module, Temp, MAX_PATH))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (0 == PathCombineW(FileName, Temp, RelativePath))
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (0 == GetModuleFileNameW(Module, FileName, MAX_PATH))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
599
src/shared/ku/mountmgr.c
Normal file
599
src/shared/ku/mountmgr.c
Normal file
@ -0,0 +1,599 @@
|
|||||||
|
/**
|
||||||
|
* @file shared/ku/mountmgr.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2022 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 <shared/ku/library.h>
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4459) /* declaration of 'identifier' hides global declaration */
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
||||||
|
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength);
|
||||||
|
static NTSTATUS FspMountmgrNotifyVolumeArrival(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId);
|
||||||
|
static NTSTATUS FspMountmgrNotifyMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint, BOOLEAN Created);
|
||||||
|
static NTSTATUS FspMountmgrCreateMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
static NTSTATUS FspMountmgrDeleteMountPoint(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
static VOID FspMountmgrDeleteRegistry(
|
||||||
|
GUID *UniqueId);
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrControl)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyVolumeArrival)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrCreateMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrDeleteMountPoint)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrCreateDrive)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrDeleteDrive)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyCreateDirectory)
|
||||||
|
#pragma alloc_text(PAGE, FspMountmgrNotifyDeleteDirectory)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrControl(ULONG IoControlCode,
|
||||||
|
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, PULONG POutputBufferLength)
|
||||||
|
{
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
HANDLE MgrHandle = 0;
|
||||||
|
ULONG Bytes = 0;
|
||||||
|
|
||||||
|
if (0 == POutputBufferLength)
|
||||||
|
POutputBufferLength = &Bytes;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\MountPointManager");
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&DeviceName,
|
||||||
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||||
|
0/*RootDirectory*/,
|
||||||
|
0);
|
||||||
|
|
||||||
|
IoStatus.Status = ZwOpenFile(
|
||||||
|
&MgrHandle,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatus,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_ALERT);
|
||||||
|
if (!NT_SUCCESS(IoStatus.Status))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
IoStatus.Status = ZwDeviceIoControlFile(
|
||||||
|
MgrHandle,
|
||||||
|
0, 0, 0,
|
||||||
|
&IoStatus,
|
||||||
|
IoControlCode,
|
||||||
|
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength);
|
||||||
|
if (!NT_SUCCESS(IoStatus.Status))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
*POutputBufferLength = (ULONG)IoStatus.Information;
|
||||||
|
IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != MgrHandle)
|
||||||
|
ZwClose(MgrHandle);
|
||||||
|
|
||||||
|
return IoStatus.Status;
|
||||||
|
#else
|
||||||
|
HANDLE MgrHandle = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD Bytes = 0;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 == POutputBufferLength)
|
||||||
|
POutputBufferLength = &Bytes;
|
||||||
|
|
||||||
|
MgrHandle = CreateFileW(L"\\\\.\\MountPointManager",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
0,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
if (INVALID_HANDLE_VALUE == MgrHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DeviceIoControl(MgrHandle,
|
||||||
|
IoControlCode,
|
||||||
|
InputBuffer, InputBufferLength, OutputBuffer, *POutputBufferLength,
|
||||||
|
&Bytes, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*POutputBufferLength = Bytes;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (INVALID_HANDLE_VALUE != MgrHandle)
|
||||||
|
CloseHandle(MgrHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrNotifyVolumeArrival(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Disabled = 0,
|
||||||
|
Enabled,
|
||||||
|
} MOUNTMGR_AUTO_MOUNT_STATE;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MOUNTMGR_AUTO_MOUNT_STATE CurrentState;
|
||||||
|
} MOUNTMGR_QUERY_AUTO_MOUNT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MOUNTMGR_AUTO_MOUNT_STATE NewState;
|
||||||
|
} MOUNTMGR_SET_AUTO_MOUNT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
WCHAR DeviceName[1];
|
||||||
|
} MOUNTMGR_TARGET_NAME;
|
||||||
|
|
||||||
|
MOUNTMGR_QUERY_AUTO_MOUNT QueryAutoMount;
|
||||||
|
MOUNTMGR_SET_AUTO_MOUNT SetAutoMount;
|
||||||
|
MOUNTMGR_TARGET_NAME *TargetName = 0;
|
||||||
|
ULONG QueryAutoMountSize, TargetNameSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
QueryAutoMountSize = sizeof QueryAutoMount;
|
||||||
|
TargetNameSize = FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + VolumeName->Length;
|
||||||
|
|
||||||
|
TargetName = MemAlloc(TargetNameSize);
|
||||||
|
if (0 == TargetName)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query the current AutoMount value and save it */
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 15, METHOD_BUFFERED, FILE_ANY_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT */
|
||||||
|
0, 0, &QueryAutoMount, &QueryAutoMountSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* disable AutoMount */
|
||||||
|
SetAutoMount.NewState = 0;
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* announce volume arrival */
|
||||||
|
memset(TargetName, 0, sizeof *TargetName);
|
||||||
|
TargetName->DeviceNameLength = VolumeName->Length;
|
||||||
|
memcpy(TargetName->DeviceName, VolumeName->Buffer, VolumeName->Length);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 11, METHOD_BUFFERED, FILE_READ_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION */
|
||||||
|
TargetName, TargetNameSize, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* reset the AutoMount value to the saved one */
|
||||||
|
SetAutoMount.NewState = QueryAutoMount.CurrentState;
|
||||||
|
FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 16, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_SET_AUTO_MOUNT */
|
||||||
|
&SetAutoMount, sizeof SetAutoMount, 0, 0);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(TargetName);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrNotifyMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint, BOOLEAN Created)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SourceVolumeNameOffset;
|
||||||
|
USHORT SourceVolumeNameLength;
|
||||||
|
USHORT TargetVolumeNameOffset;
|
||||||
|
USHORT TargetVolumeNameLength;
|
||||||
|
} MOUNTMGR_VOLUME_MOUNT_POINT;
|
||||||
|
|
||||||
|
MOUNTMGR_VOLUME_MOUNT_POINT *VolumeMountPoint = 0;
|
||||||
|
ULONG VolumeMountPointSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
VolumeMountPointSize = sizeof *VolumeMountPoint +
|
||||||
|
sizeof L"\\DosDevices\\" - sizeof(WCHAR) + MountPoint->Length + VolumeName->Length;
|
||||||
|
|
||||||
|
VolumeMountPoint = MemAlloc(VolumeMountPointSize);
|
||||||
|
if (0 == VolumeMountPoint)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* notify volume mount point created/deleted */
|
||||||
|
memset(VolumeMountPoint, 0, sizeof *VolumeMountPoint);
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset = sizeof *VolumeMountPoint;
|
||||||
|
VolumeMountPoint->SourceVolumeNameLength = (USHORT)(
|
||||||
|
sizeof L"\\DosDevices\\" - sizeof(WCHAR) + MountPoint->Length);
|
||||||
|
VolumeMountPoint->TargetVolumeNameOffset =
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + VolumeMountPoint->SourceVolumeNameLength;
|
||||||
|
VolumeMountPoint->TargetVolumeNameLength = VolumeName->Length;
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset,
|
||||||
|
L"\\DosDevices\\", sizeof L"\\DosDevices\\" - sizeof(WCHAR));
|
||||||
|
memcpy((PUINT8)VolumeMountPoint +
|
||||||
|
VolumeMountPoint->SourceVolumeNameOffset + (sizeof L"\\DosDevices\\" - sizeof(WCHAR)),
|
||||||
|
MountPoint->Buffer, MountPoint->Length);
|
||||||
|
memcpy((PUINT8)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset,
|
||||||
|
VolumeName->Buffer, VolumeName->Length);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
Created ?
|
||||||
|
CTL_CODE('m', 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) :
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED */
|
||||||
|
CTL_CODE('m', 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED */
|
||||||
|
VolumeMountPoint, VolumeMountPointSize, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(VolumeMountPoint);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrCreateMountPoint(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
USHORT SymbolicLinkNameOffset;
|
||||||
|
USHORT SymbolicLinkNameLength;
|
||||||
|
USHORT DeviceNameOffset;
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
} MOUNTMGR_CREATE_POINT_INPUT;
|
||||||
|
|
||||||
|
MOUNTMGR_CREATE_POINT_INPUT *CreatePointInput = 0;
|
||||||
|
ULONG CreatePointInputSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
CreatePointInputSize = sizeof *CreatePointInput +
|
||||||
|
sizeof L"\\DosDevices\\X:" - sizeof(WCHAR) + VolumeName->Length;
|
||||||
|
|
||||||
|
CreatePointInput = MemAlloc(CreatePointInputSize);
|
||||||
|
if (0 == CreatePointInput)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create mount point */
|
||||||
|
memset(CreatePointInput, 0, sizeof *CreatePointInput);
|
||||||
|
CreatePointInput->SymbolicLinkNameOffset = sizeof *CreatePointInput;
|
||||||
|
CreatePointInput->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
CreatePointInput->DeviceNameOffset =
|
||||||
|
CreatePointInput->SymbolicLinkNameOffset + CreatePointInput->SymbolicLinkNameLength;
|
||||||
|
CreatePointInput->DeviceNameLength = VolumeName->Length;
|
||||||
|
memcpy((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset,
|
||||||
|
L"\\DosDevices\\X:", CreatePointInput->SymbolicLinkNameLength);
|
||||||
|
((PWCHAR)((PUINT8)CreatePointInput + CreatePointInput->SymbolicLinkNameOffset))[12] =
|
||||||
|
MountPoint->Buffer[0] & ~0x20;
|
||||||
|
/* convert to uppercase */
|
||||||
|
memcpy((PUINT8)CreatePointInput + CreatePointInput->DeviceNameOffset,
|
||||||
|
VolumeName->Buffer, VolumeName->Length);
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_CREATE_POINT */
|
||||||
|
CreatePointInput, CreatePointInputSize, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(CreatePointInput);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMountmgrDeleteMountPoint(
|
||||||
|
PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* mountmgr.h */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG SymbolicLinkNameOffset;
|
||||||
|
USHORT SymbolicLinkNameLength;
|
||||||
|
USHORT Reserved1;
|
||||||
|
ULONG UniqueIdOffset;
|
||||||
|
USHORT UniqueIdLength;
|
||||||
|
USHORT Reserved2;
|
||||||
|
ULONG DeviceNameOffset;
|
||||||
|
USHORT DeviceNameLength;
|
||||||
|
USHORT Reserved3;
|
||||||
|
} MOUNTMGR_MOUNT_POINT;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
ULONG NumberOfMountPoints;
|
||||||
|
MOUNTMGR_MOUNT_POINT MountPoints[1];
|
||||||
|
} MOUNTMGR_MOUNT_POINTS;
|
||||||
|
|
||||||
|
MOUNTMGR_MOUNT_POINT *Input = 0;
|
||||||
|
MOUNTMGR_MOUNT_POINTS *Output = 0;
|
||||||
|
ULONG InputSize, OutputSize;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
InputSize = sizeof *Input + sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
OutputSize = 4096;
|
||||||
|
|
||||||
|
Input = MemAlloc(InputSize);
|
||||||
|
if (0 == Input)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Output = MemAlloc(OutputSize);
|
||||||
|
if (0 == Output)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete mount point */
|
||||||
|
memset(Input, 0, sizeof *Input);
|
||||||
|
Input->SymbolicLinkNameOffset = sizeof *Input;
|
||||||
|
Input->SymbolicLinkNameLength = sizeof L"\\DosDevices\\X:" - sizeof(WCHAR);
|
||||||
|
memcpy((PUINT8)Input + Input->SymbolicLinkNameOffset,
|
||||||
|
L"\\DosDevices\\X:", Input->SymbolicLinkNameLength);
|
||||||
|
((PWCHAR)((PUINT8)Input + Input->SymbolicLinkNameOffset))[12] =
|
||||||
|
MountPoint->Buffer[0] & ~0x20;
|
||||||
|
/* convert to uppercase */
|
||||||
|
Result = FspMountmgrControl(
|
||||||
|
CTL_CODE('m', 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS),
|
||||||
|
/* IOCTL_MOUNTMGR_DELETE_POINTS */
|
||||||
|
Input, InputSize, Output, &OutputSize);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Output);
|
||||||
|
MemFree(Input);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspMountmgrDeleteRegistry(GUID *UniqueId)
|
||||||
|
{
|
||||||
|
#if defined(_KERNEL_MODE)
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
UNICODE_STRING Path;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE Handle = 0;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
KEY_VALUE_FULL_INFORMATION V;
|
||||||
|
UINT8 B[FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + 255 + sizeof *UniqueId];
|
||||||
|
} FullInformation;
|
||||||
|
ULONG FullInformationLength;
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Path, L"\\Registry\\Machine\\System\\MountedDevices");
|
||||||
|
InitializeObjectAttributes(
|
||||||
|
&ObjectAttributes,
|
||||||
|
&Path,
|
||||||
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
||||||
|
0/*RootDirectory*/,
|
||||||
|
0);
|
||||||
|
|
||||||
|
Result = ZwOpenKey(&Handle, KEY_QUERY_VALUE, &ObjectAttributes);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
for (ULONG I = 0;; I++)
|
||||||
|
{
|
||||||
|
Result = ZwEnumerateValueKey(Handle,
|
||||||
|
I, KeyValueFullInformation, &FullInformation,
|
||||||
|
sizeof FullInformation, &FullInformationLength);
|
||||||
|
if (STATUS_NO_MORE_ENTRIES == Result)
|
||||||
|
break;
|
||||||
|
else if (!NT_SUCCESS(Result))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (REG_BINARY == FullInformation.V.Type &&
|
||||||
|
sizeof *UniqueId == FullInformation.V.DataLength &&
|
||||||
|
InlineIsEqualGUID((GUID *)((PUINT8)&FullInformation.V + FullInformation.V.DataOffset),
|
||||||
|
UniqueId))
|
||||||
|
{
|
||||||
|
ValueName.Length = ValueName.MaximumLength = (USHORT)FullInformation.V.NameLength;
|
||||||
|
ValueName.Buffer = FullInformation.V.Name;
|
||||||
|
Result = ZwDeleteValueKey(Handle, &ValueName);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
||||||
|
I = (ULONG)-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZwClose(Handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
HKEY RegKey;
|
||||||
|
LONG RegResult;
|
||||||
|
WCHAR RegValueName[MAX_PATH];
|
||||||
|
UINT8 RegValueData[sizeof *UniqueId];
|
||||||
|
DWORD RegValueNameSize, RegValueDataSize;
|
||||||
|
DWORD RegType;
|
||||||
|
|
||||||
|
RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\MountedDevices",
|
||||||
|
0, KEY_READ | KEY_WRITE, &RegKey);
|
||||||
|
if (ERROR_SUCCESS == RegResult)
|
||||||
|
{
|
||||||
|
for (DWORD I = 0;; I++)
|
||||||
|
{
|
||||||
|
RegValueNameSize = MAX_PATH;
|
||||||
|
RegValueDataSize = sizeof RegValueData;
|
||||||
|
RegResult = RegEnumValueW(RegKey,
|
||||||
|
I, RegValueName, &RegValueNameSize, 0, &RegType, RegValueData, &RegValueDataSize);
|
||||||
|
if (ERROR_NO_MORE_ITEMS == RegResult)
|
||||||
|
break;
|
||||||
|
else if (ERROR_SUCCESS != RegResult)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (REG_BINARY == RegType &&
|
||||||
|
sizeof RegValueData == RegValueDataSize &&
|
||||||
|
InlineIsEqualGUID((GUID *)&RegValueData, UniqueId))
|
||||||
|
{
|
||||||
|
RegResult = RegDeleteValueW(RegKey, RegValueName);
|
||||||
|
if (ERROR_SUCCESS == RegResult)
|
||||||
|
/* reset index after modifying key; only safe way to use RegEnumValueW with modifications */
|
||||||
|
I = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(RegKey);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* notify the MountManager about the new volume */
|
||||||
|
Result = FspMountmgrNotifyVolumeArrival(VolumeName, UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* use the MountManager to create the drive */
|
||||||
|
Result = FspMountmgrCreateMountPoint(VolumeName, MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* HACK: delete the MountManager registry entries */
|
||||||
|
FspMountmgrDeleteRegistry(UniqueId);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* use the MountManager to delete the drive */
|
||||||
|
Result = FspMountmgrDeleteMountPoint(MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* notify the MountManager about the new volume */
|
||||||
|
Result = FspMountmgrNotifyVolumeArrival(VolumeName, UniqueId);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* notify the MountManager about the created directory mount point */
|
||||||
|
Result = FspMountmgrNotifyMountPoint(VolumeName, MountPoint, TRUE);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
/* HACK: delete the MountManager registry entries */
|
||||||
|
FspMountmgrDeleteRegistry(UniqueId);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint)
|
||||||
|
{
|
||||||
|
FSP_KU_CODE;
|
||||||
|
|
||||||
|
/* notify the MountManager about the deleted directory mount point */
|
||||||
|
return FspMountmgrNotifyMountPoint(VolumeName, MountPoint, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
@ -59,6 +59,8 @@ VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I
|
|||||||
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||||
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
@ -84,6 +86,8 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvrtDeviceInit)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvrtDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
||||||
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
||||||
@ -171,7 +175,7 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject)
|
|||||||
Result = FspFsvolDeviceInit(DeviceObject);
|
Result = FspFsvolDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
Result = STATUS_SUCCESS;
|
Result = FspFsvrtDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsmupDeviceExtensionKind:
|
case FspFsmupDeviceExtensionKind:
|
||||||
Result = FspFsmupDeviceInit(DeviceObject);
|
Result = FspFsmupDeviceInit(DeviceObject);
|
||||||
@ -202,6 +206,7 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
|
|||||||
FspFsvolDeviceFini(DeviceObject);
|
FspFsvolDeviceFini(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
|
FspFsvrtDeviceFini(DeviceObject);
|
||||||
break;
|
break;
|
||||||
case FspFsmupDeviceExtensionKind:
|
case FspFsmupDeviceExtensionKind:
|
||||||
FspFsmupDeviceFini(DeviceObject);
|
FspFsmupDeviceFini(DeviceObject);
|
||||||
@ -848,6 +853,27 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject)
|
|||||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
ExInitializeFastMutex(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
if (0 != FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -1232,13 +1232,18 @@ typedef struct
|
|||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
/* read-only after creation (and insertion in the ContextTable) */
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
UINT16 SectorSize;
|
UINT16 SectorSize;
|
||||||
LONG IsMountdev;
|
|
||||||
BOOLEAN Persistent;
|
|
||||||
GUID UniqueId;
|
|
||||||
UNICODE_STRING VolumeName;
|
UNICODE_STRING VolumeName;
|
||||||
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
||||||
|
FAST_MUTEX MountMutex;
|
||||||
|
/* interlocked access */
|
||||||
|
LONG IsMountdev;
|
||||||
|
/* protected under MountMutex */
|
||||||
|
BOOLEAN Persistent;
|
||||||
|
GUID UniqueId;
|
||||||
|
UNICODE_STRING MountPoint;
|
||||||
} FSP_FSVRT_DEVICE_EXTENSION;
|
} FSP_FSVRT_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -1435,6 +1440,18 @@ BOOLEAN FspFsvolDeviceVolumePrefixInString(PDEVICE_OBJECT DeviceObject, PUNICODE
|
|||||||
TRUE);
|
TRUE);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
|
VOID FspFsvrtDeviceLockMount(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
ExAcquireFastMutexUnsafe(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
|
VOID FspFsvrtDeviceUnlockMount(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
|
ExReleaseFastMutexUnsafe(&FsvrtDeviceExtension->MountMutex);
|
||||||
|
}
|
||||||
|
static inline
|
||||||
VOID FspFsmupDeviceLockPrefixTable(PDEVICE_OBJECT DeviceObject)
|
VOID FspFsmupDeviceLockPrefixTable(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
||||||
@ -1524,6 +1541,16 @@ NTSTATUS FspMountdevMake(
|
|||||||
VOID FspMountdevFini(
|
VOID FspMountdevFini(
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject);
|
PDEVICE_OBJECT FsvrtDeviceObject);
|
||||||
|
|
||||||
|
/* mountmgr */
|
||||||
|
NTSTATUS FspMountmgrCreateDrive(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrDeleteDrive(
|
||||||
|
PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyCreateDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, GUID *UniqueId, PUNICODE_STRING MountPoint);
|
||||||
|
NTSTATUS FspMountmgrNotifyDeleteDirectory(
|
||||||
|
PUNICODE_STRING VolumeName, PUNICODE_STRING MountPoint);
|
||||||
|
|
||||||
/* fsmup */
|
/* fsmup */
|
||||||
NTSTATUS FspMupRegister(
|
NTSTATUS FspMupRegister(
|
||||||
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
@ -1543,6 +1570,8 @@ NTSTATUS FspVolumeMount(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeMakeMountdev(
|
NTSTATUS FspVolumeMakeMountdev(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
|
@ -81,6 +81,10 @@ static NTSTATUS FspFsctlFileSystemControl(
|
|||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
Result = FspVolumeMakeMountdev(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeMakeMountdev(FsctlDeviceObject, Irp, IrpSp);
|
||||||
break;
|
break;
|
||||||
|
case FSP_FSCTL_MOUNTMGR:
|
||||||
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
|
Result = FspVolumeUseMountmgr(FsctlDeviceObject, Irp, IrpSp);
|
||||||
|
break;
|
||||||
case FSP_FSCTL_VOLUME_NAME:
|
case FSP_FSCTL_VOLUME_NAME:
|
||||||
if (0 != IrpSp->FileObject->FsContext2)
|
if (0 != IrpSp->FileObject->FsContext2)
|
||||||
Result = FspVolumeGetName(FsctlDeviceObject, Irp, IrpSp);
|
Result = FspVolumeGetName(FsctlDeviceObject, Irp, IrpSp);
|
||||||
|
@ -138,7 +138,7 @@ NTSTATUS FspMountdevMake(
|
|||||||
* be mounted using the MountManager.
|
* be mounted using the MountManager.
|
||||||
*
|
*
|
||||||
* This function requires protection against concurrency. In general this
|
* This function requires protection against concurrency. In general this
|
||||||
* is achieved by acquiring the GlobalDeviceLock.
|
* is achieved by the caller acquiring the MountMutex.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -178,11 +178,6 @@ NTSTATUS FspMountdevMake(
|
|||||||
|
|
||||||
/* initialize the fsvrt device extension */
|
/* initialize the fsvrt device extension */
|
||||||
RtlCopyMemory(&FsvrtDeviceExtension->UniqueId, &Guid, sizeof Guid);
|
RtlCopyMemory(&FsvrtDeviceExtension->UniqueId, &Guid, sizeof Guid);
|
||||||
RtlInitEmptyUnicodeString(&FsvrtDeviceExtension->VolumeName,
|
|
||||||
FsvrtDeviceExtension->VolumeNameBuf, sizeof FsvrtDeviceExtension->VolumeNameBuf);
|
|
||||||
RtlCopyUnicodeString(&FsvrtDeviceExtension->VolumeName, &FsvolDeviceExtension->VolumeName);
|
|
||||||
|
|
||||||
/* mark the fsvrt device as initialized */
|
|
||||||
InterlockedIncrement(&FspFsvrtDeviceExtension(FsvrtDeviceObject)->IsMountdev);
|
InterlockedIncrement(&FspFsvrtDeviceExtension(FsvrtDeviceObject)->IsMountdev);
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
160
src/sys/volume.c
160
src/sys/volume.c
@ -38,6 +38,8 @@ static NTSTATUS FspVolumeMountNoLock(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeMakeMountdev(
|
NTSTATUS FspVolumeMakeMountdev(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
@ -76,6 +78,7 @@ NTSTATUS FspVolumeWork(
|
|||||||
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeMakeMountdev)
|
#pragma alloc_text(PAGE, FspVolumeMakeMountdev)
|
||||||
|
#pragma alloc_text(PAGE, FspVolumeUseMountmgr)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
||||||
@ -246,6 +249,11 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
VolumeParams.AlwaysUseDoubleBuffering = 1;
|
VolumeParams.AlwaysUseDoubleBuffering = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardcode the RejectIrpPriorToTransact0 = 1 setting.
|
||||||
|
*/
|
||||||
|
VolumeParams.RejectIrpPriorToTransact0 = 1;
|
||||||
|
|
||||||
/* load any fsext provider */
|
/* load any fsext provider */
|
||||||
if (0 != VolumeParams.FsextControlCode)
|
if (0 != VolumeParams.FsextControlCode)
|
||||||
{
|
{
|
||||||
@ -316,8 +324,12 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
{
|
{
|
||||||
if (0 != FsvrtDeviceObject)
|
if (0 != FsvrtDeviceObject)
|
||||||
{
|
{
|
||||||
FspFsvrtDeviceExtension(FsvrtDeviceObject)->SectorSize =
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
FsvolDeviceExtension->VolumeParams.SectorSize;
|
FsvrtDeviceExtension->SectorSize = FsvolDeviceExtension->VolumeParams.SectorSize;
|
||||||
|
RtlInitEmptyUnicodeString(&FsvrtDeviceExtension->VolumeName,
|
||||||
|
FsvrtDeviceExtension->VolumeNameBuf, sizeof FsvrtDeviceExtension->VolumeNameBuf);
|
||||||
|
RtlCopyUnicodeString(&FsvrtDeviceExtension->VolumeName, &FsvolDeviceExtension->VolumeName);
|
||||||
|
|
||||||
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
Result = FspDeviceInitialize(FsvrtDeviceObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -638,7 +650,7 @@ NTSTATUS FspVolumeMakeMountdev(
|
|||||||
if (sizeof(GUID) > OutputBufferLength)
|
if (sizeof(GUID) > OutputBufferLength)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
FspDeviceGlobalLock();
|
FspFsvrtDeviceLockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -654,7 +666,147 @@ NTSTATUS FspVolumeMakeMountdev(
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
FspDeviceGlobalUnlock();
|
FspFsvrtDeviceUnlockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspVolumeUseMountmgr(
|
||||||
|
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_MOUNTMGR == IrpSp->Parameters.FileSystemControl.FsControlCode);
|
||||||
|
ASSERT(0 != IrpSp->FileObject->FsContext2);
|
||||||
|
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
|
ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (0 == FsvrtDeviceObject)
|
||||||
|
return STATUS_INVALID_PARAMETER; /* cannot only use fsvrt with mount manager */
|
||||||
|
if (1024 * sizeof(WCHAR) < InputBufferLength)
|
||||||
|
return STATUS_INVALID_PARAMETER; /* disallow very long paths */
|
||||||
|
|
||||||
|
FspFsvrtDeviceLockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
if (0 < InputBufferLength)
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
PWCHAR MountPointBuf = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
UNICODE_STRING RegPath;
|
||||||
|
UNICODE_STRING RegName;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
KEY_VALUE_PARTIAL_INFORMATION V;
|
||||||
|
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)];
|
||||||
|
} RegValue;
|
||||||
|
ULONG RegLength;
|
||||||
|
BOOLEAN Persistent = FALSE;
|
||||||
|
|
||||||
|
if (!(
|
||||||
|
2 * sizeof(WCHAR) <= InputBufferLength &&
|
||||||
|
(
|
||||||
|
(L'A' <= MountPointBuf[0] && MountPointBuf[0] <= L'Z') ||
|
||||||
|
(L'a' <= MountPointBuf[0] && MountPointBuf[0] <= L'z')
|
||||||
|
) &&
|
||||||
|
L':' == MountPointBuf[1]
|
||||||
|
))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&RegPath, L"" FSP_REGKEY);
|
||||||
|
RtlInitUnicodeString(&RegName, L"MountUseMountmgrFromFSD");
|
||||||
|
RegLength = sizeof RegValue;
|
||||||
|
Result = FspRegistryGetValue(&RegPath, &RegName, &RegValue.V, &RegLength);
|
||||||
|
if (!NT_SUCCESS(Result) || REG_DWORD != RegValue.V.Type || 1 != *(PULONG)&RegValue.V.Data)
|
||||||
|
{
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspMountdevMake(FsvrtDeviceObject, FsvolDeviceObject, Persistent);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (STATUS_TOO_LATE != Result)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = FspAllocNonPaged(InputBufferLength);
|
||||||
|
if (0 == FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = (USHORT)InputBufferLength;
|
||||||
|
RtlCopyMemory(FsvrtDeviceExtension->MountPoint.Buffer, MountPointBuf, InputBufferLength);
|
||||||
|
|
||||||
|
if (2 * sizeof(WCHAR) == FsvrtDeviceExtension->MountPoint.Length)
|
||||||
|
Result = FspMountmgrCreateDrive(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->UniqueId,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
else
|
||||||
|
Result = FspMountmgrNotifyCreateDirectory(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->UniqueId,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = 0;
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
|
|
||||||
|
if (0 == FsvrtDeviceExtension->MountPoint.Buffer)
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 * sizeof(WCHAR) == FsvrtDeviceExtension->MountPoint.Length)
|
||||||
|
Result = FspMountmgrDeleteDrive(
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
else
|
||||||
|
Result = FspMountmgrNotifyDeleteDirectory(
|
||||||
|
&FsvrtDeviceExtension->VolumeName,
|
||||||
|
&FsvrtDeviceExtension->MountPoint);
|
||||||
|
/* ignore Result */
|
||||||
|
|
||||||
|
FspFree(FsvrtDeviceExtension->MountPoint.Buffer);
|
||||||
|
FsvrtDeviceExtension->MountPoint.Buffer = 0;
|
||||||
|
FsvrtDeviceExtension->MountPoint.Length =
|
||||||
|
FsvrtDeviceExtension->MountPoint.MaximumLength = 0;
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FspFsvrtDeviceUnlockMount(FsvrtDeviceObject);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFOzCCAyOgAwIBAgIKYSBNtAAAAAAAJzANBgkqhkiG9w0BAQUFADB/MQswCQYD
|
|
||||||
VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
|
|
||||||
MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQDEyBNaWNyb3Nv
|
|
||||||
ZnQgQ29kZSBWZXJpZmljYXRpb24gUm9vdDAeFw0xMTA0MTUxOTQ1MzNaFw0yMTA0
|
|
||||||
MTUxOTU1MzNaMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx
|
|
||||||
GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhp
|
|
||||||
Z2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
|
||||||
ggEKAoIBAQDGzOVz5vvUu+UtLTKm3+WBP8nNJUm2cSrD1ZQ0Z6IKHLBfaaZAscS3
|
|
||||||
so/QmKSpQVk609yU1jzbdDikSsxNJYL3SqVTEjju80ltcZF+Y7arpl/DpIT4T2JR
|
|
||||||
vvjF7Ns4kuMG5QiRDMQoQVX7y1qJFX5x6DW/TXIJPb46OFBbdzEbjbPHJEWap6xt
|
|
||||||
ABRaBLe6E+tRCphBQSJOZWGHgUFQpnlcid4ZSlfVLuZdHFMsfpjNGgYWpGhz0DQE
|
|
||||||
E1yhcdNafFXbXmThN4cwVgTlEbQpgBLxeTmIogIRfCdmt4i3ePLKCqg4qwpkwr9m
|
|
||||||
XZWEwaElHoddGlALIBLMQbtuC1E4uEvLAgMBAAGjgcswgcgwEQYDVR0gBAowCDAG
|
|
||||||
BgRVHSAAMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSx
|
|
||||||
PsNpA/i/RwHUmCYaCALvY2QrwzAfBgNVHSMEGDAWgBRi+wohW39DbhHaCVRQa/XS
|
|
||||||
lnHxnjBVBgNVHR8ETjBMMEqgSKBGhkRodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
|
|
||||||
cGtpL2NybC9wcm9kdWN0cy9NaWNyb3NvZnRDb2RlVmVyaWZSb290LmNybDANBgkq
|
|
||||||
hkiG9w0BAQUFAAOCAgEAIIzBWe1vnGstwUo+dR1FTEFQHL2A6tmwkosGKhM/Uxae
|
|
||||||
VjlqimO2eCR59X24uUehCpbC9su9omafBuGs0nkJDv083KwCDHCvPxvseH7U60sF
|
|
||||||
YCbZc2GRIe2waGPglxKrb6AS7dmf0tonPLPkVvnR1IEPcb1CfKaJ3M3VvZWiq/GT
|
|
||||||
EX3orDEpqF1mcEGd/HXJ1bMaOSrQhQVQi6yRysSTy3GlnaSUb1gM+m4gxAgxtYWd
|
|
||||||
foH50j3KWxiFbAqG7CIJG6V0NE9/KLyVSqsdtpiwXQmkd3Z+76eOXYT2GCTL0W2m
|
|
||||||
w6GcwhB1gP+dMv3mz0M6gvfOj+FyKptit1/tlRo5XC+UbUi3AV8zL7vcLXM0iQRC
|
|
||||||
ChyLefmj+hfv+qEaEN/gssGV61wMBZc7NT4YiE3bbL8kiY3Ivdifezk6JKDV39Hz
|
|
||||||
ShqX9qZveh+wkKmzrAE5kdNht2TxPlc4A6/OetK1kPWu3DmZ1bY8l+2myxbHfWsq
|
|
||||||
TJCU5kxU/R7NIOzOaJyHWOlhYL7rDsnVGX2f6Xi9DqwhdQePqW7gjGoqa5zj52W8
|
|
||||||
vC08bdwE3GdFNjKvBIG8qABuYUyVxVzUjo6fL8EydL29EWUDB83vt14CV9qG1Boo
|
|
||||||
NK+ISbLPpd2CVm9oqhTiWVT+/+ru7+qScCJggeMlI8CfzA9JsjWqWMM6w9kWlBA=
|
|
||||||
-----END CERTIFICATE-----
|
|
BIN
tools/DigiCertGlobalG3CodeSigningECCSHA3842021CA1.cer
Normal file
BIN
tools/DigiCertGlobalG3CodeSigningECCSHA3842021CA1.cer
Normal file
Binary file not shown.
@ -36,6 +36,10 @@ set dfl_tests=^
|
|||||||
winfsp-tests-x64-mountpoint-drive ^
|
winfsp-tests-x64-mountpoint-drive ^
|
||||||
winfsp-tests-x64-mountpoint-dir ^
|
winfsp-tests-x64-mountpoint-dir ^
|
||||||
winfsp-tests-x64-mountpoint-dir-case-sensitive ^
|
winfsp-tests-x64-mountpoint-dir-case-sensitive ^
|
||||||
|
winfsp-tests-x64-mountmgr-drive ^
|
||||||
|
winfsp-tests-x64-mountmgr-dir ^
|
||||||
|
winfsp-tests-x64-mountmgrfsd-drive ^
|
||||||
|
winfsp-tests-x64-mountmgrfsd-dir ^
|
||||||
winfsp-tests-x64-no-traverse ^
|
winfsp-tests-x64-no-traverse ^
|
||||||
winfsp-tests-x64-oplock ^
|
winfsp-tests-x64-oplock ^
|
||||||
winfsp-tests-x64-notify ^
|
winfsp-tests-x64-notify ^
|
||||||
@ -56,6 +60,10 @@ set dfl_tests=^
|
|||||||
winfsp-tests-x86-mountpoint-drive ^
|
winfsp-tests-x86-mountpoint-drive ^
|
||||||
winfsp-tests-x86-mountpoint-dir ^
|
winfsp-tests-x86-mountpoint-dir ^
|
||||||
winfsp-tests-x86-mountpoint-dir-case-sensitive ^
|
winfsp-tests-x86-mountpoint-dir-case-sensitive ^
|
||||||
|
winfsp-tests-x86-mountmgr-drive ^
|
||||||
|
winfsp-tests-x86-mountmgr-dir ^
|
||||||
|
winfsp-tests-x86-mountmgrfsd-drive ^
|
||||||
|
winfsp-tests-x86-mountmgrfsd-dir ^
|
||||||
winfsp-tests-x86-no-traverse ^
|
winfsp-tests-x86-no-traverse ^
|
||||||
winfsp-tests-x86-oplock ^
|
winfsp-tests-x86-oplock ^
|
||||||
winfsp-tests-x86-notify ^
|
winfsp-tests-x86-notify ^
|
||||||
@ -232,6 +240,30 @@ winfsp-tests-x64 --mountpoint=mymnt * +ea*
|
|||||||
if !ERRORLEVEL! neq 0 goto fail
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x64-mountmgr-drive
|
||||||
|
winfsp-tests-x64 --mountpoint=\\.\X: --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x64-mountmgr-dir
|
||||||
|
winfsp-tests-x64 --mountpoint=\\.\%cd%\mnt --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x64-mountmgrfsd-drive
|
||||||
|
reg add HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /t REG_DWORD /d 1 /f /reg:32
|
||||||
|
winfsp-tests-x64 --mountpoint=\\.\X: --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
reg delete HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /f /reg:32
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x64-mountmgrfsd-dir
|
||||||
|
reg add HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /t REG_DWORD /d 1 /f /reg:32
|
||||||
|
winfsp-tests-x64 --mountpoint=\\.\%cd%\mnt --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
reg delete HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /f /reg:32
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
:winfsp-tests-x64-no-traverse
|
:winfsp-tests-x64-no-traverse
|
||||||
winfsp-tests-x64 --no-traverse * +ea*
|
winfsp-tests-x64 --no-traverse * +ea*
|
||||||
if !ERRORLEVEL! neq 0 goto fail
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
@ -282,6 +314,30 @@ winfsp-tests-x86 --mountpoint=mymnt * +ea*
|
|||||||
if !ERRORLEVEL! neq 0 goto fail
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x86-mountmgr-drive
|
||||||
|
winfsp-tests-x86 --mountpoint=\\.\X: --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x86-mountmgr-dir
|
||||||
|
winfsp-tests-x86 --mountpoint=\\.\%cd%\mnt --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x86-mountmgrfsd-drive
|
||||||
|
reg add HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /t REG_DWORD /d 1 /f /reg:32
|
||||||
|
winfsp-tests-x86 --mountpoint=\\.\X: --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
reg delete HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /f /reg:32
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:winfsp-tests-x86-mountmgrfsd-dir
|
||||||
|
reg add HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /t REG_DWORD /d 1 /f /reg:32
|
||||||
|
winfsp-tests-x86 --mountpoint=\\.\%cd%\mnt --resilient * +ea*
|
||||||
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
reg delete HKLM\Software\WinFsp /v MountUseMountmgrFromFSD /f /reg:32
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
:winfsp-tests-x86-no-traverse
|
:winfsp-tests-x86-no-traverse
|
||||||
winfsp-tests-x86 --no-traverse * +ea*
|
winfsp-tests-x86 --no-traverse * +ea*
|
||||||
if !ERRORLEVEL! neq 0 goto fail
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
|
@ -67,6 +67,9 @@ void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout)
|
|||||||
Result = MemfsStart(Memfs);
|
Result = MemfsStart(Memfs);
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
|
Result = FspFsctlTransact(MemfsFileSystem(Memfs)->VolumeHandle, 0, 0, 0, 0, FALSE);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
memfs_running = 1;
|
memfs_running = 1;
|
||||||
memfs_handle = MemfsFileSystem(Memfs)->VolumeHandle;
|
memfs_handle = MemfsFileSystem(Memfs)->VolumeHandle;
|
||||||
|
|
||||||
|
@ -215,6 +215,9 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
||||||
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
||||||
|
|
||||||
|
Result = FspFsctlTransact(VolumeHandle, 0, 0, 0, 0, FALSE);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : VolumeName);
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : VolumeName);
|
||||||
Thread = (HANDLE)_beginthreadex(0, 0, mount_volume_transact_dotest_thread, FilePath, 0, 0);
|
Thread = (HANDLE)_beginthreadex(0, 0, mount_volume_transact_dotest_thread, FilePath, 0, 0);
|
||||||
@ -246,6 +249,8 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(0 != Request->Hint);
|
ASSERT(0 != Request->Hint);
|
||||||
ASSERT(FspFsctlTransactCreateKind == Request->Kind ||
|
ASSERT(FspFsctlTransactCreateKind == Request->Kind ||
|
||||||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind);
|
FspFsctlTransactQueryVolumeInformationKind == Request->Kind);
|
||||||
|
/* since we made RejectIrpPriorToTransact0 mandatory the assertions below do not hold */
|
||||||
|
#if 0
|
||||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
if (FspFsctlTransactCreateKind == Request->Kind)
|
||||||
{
|
{
|
||||||
ASSERT(FILE_CREATE == ((Request->Req.Create.CreateOptions >> 24) & 0xff));
|
ASSERT(FILE_CREATE == ((Request->Req.Create.CreateOptions >> 24) & 0xff));
|
||||||
@ -265,6 +270,7 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT((wcslen((PVOID)Request->Buffer) + 1) * sizeof(WCHAR) == Request->FileName.Size);
|
ASSERT((wcslen((PVOID)Request->Buffer) + 1) * sizeof(WCHAR) == Request->FileName.Size);
|
||||||
ASSERT(0 == mywcscmp((PVOID)Request->Buffer, -1, L"\\file0", -1));
|
ASSERT(0 == mywcscmp((PVOID)Request->Buffer, -1, L"\\file0", -1));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ASSERT(FspFsctlTransactCanProduceResponse(Response, ResponseBufEnd));
|
ASSERT(FspFsctlTransactCanProduceResponse(Response, ResponseBufEnd));
|
||||||
|
|
||||||
@ -294,7 +300,8 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
GetExitCodeThread(Thread, &ExitCode);
|
GetExitCodeThread(Thread, &ExitCode);
|
||||||
CloseHandle(Thread);
|
CloseHandle(Thread);
|
||||||
|
|
||||||
ASSERT(ERROR_ACCESS_DENIED == ExitCode || ERROR_OPERATION_ABORTED == ExitCode);
|
ASSERT(0 != ExitCode);
|
||||||
|
//ASSERT(ERROR_ACCESS_DENIED == ExitCode || ERROR_OPERATION_ABORTED == ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mount_volume_transact_test(void)
|
void mount_volume_transact_test(void)
|
||||||
|
@ -187,6 +187,8 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
||||||
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
||||||
|
|
||||||
|
Result = FspFsctlTransact(VolumeHandle, 0, 0, 0, 0, FALSE);
|
||||||
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 RequestBuf[FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 RequestBuf[FSP_FSCTL_TRANSACT_BATCH_BUFFER_SIZEMIN];
|
||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 ResponseBuf[FSP_FSCTL_TRANSACT_RSP_SIZEMAX];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 ResponseBuf[FSP_FSCTL_TRANSACT_RSP_SIZEMAX];
|
||||||
@ -223,6 +225,8 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(0 != Request->Hint);
|
ASSERT(0 != Request->Hint);
|
||||||
ASSERT(FspFsctlTransactCreateKind == Request->Kind ||
|
ASSERT(FspFsctlTransactCreateKind == Request->Kind ||
|
||||||
FspFsctlTransactQueryVolumeInformationKind == Request->Kind);
|
FspFsctlTransactQueryVolumeInformationKind == Request->Kind);
|
||||||
|
/* since we made RejectIrpPriorToTransact0 mandatory the assertions below do not hold */
|
||||||
|
#if 0
|
||||||
if (FspFsctlTransactCreateKind == Request->Kind)
|
if (FspFsctlTransactCreateKind == Request->Kind)
|
||||||
{
|
{
|
||||||
ASSERT(FILE_CREATE == ((Request->Req.Create.CreateOptions >> 24) & 0xff));
|
ASSERT(FILE_CREATE == ((Request->Req.Create.CreateOptions >> 24) & 0xff));
|
||||||
@ -239,6 +243,7 @@ void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(!Request->Req.Create.OpenTargetDirectory);
|
ASSERT(!Request->Req.Create.OpenTargetDirectory);
|
||||||
ASSERT(!Request->Req.Create.CaseSensitive);
|
ASSERT(!Request->Req.Create.CaseSensitive);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ResponseBufSize = 0;
|
ResponseBufSize = 0;
|
||||||
RequestBufSize = sizeof RequestBuf;
|
RequestBufSize = sizeof RequestBuf;
|
||||||
|
@ -89,7 +89,7 @@ static void volpath_test(void)
|
|||||||
* when *not* using the MountManager and therefore disable
|
* when *not* using the MountManager and therefore disable
|
||||||
* this test when using a non-MountManager mount point.
|
* this test when using a non-MountManager mount point.
|
||||||
*/
|
*/
|
||||||
if (!NtfsTests && !OptMountPoint)
|
if (NtfsTests || OptMountPoint)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
@ -107,8 +107,15 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
BOOLEAN Success, VolumePathNameSuccess[8];
|
BOOLEAN Success, VolumePathNameSuccess[8];
|
||||||
WCHAR FilePath[MAX_PATH];
|
WCHAR FilePath[MAX_PATH];
|
||||||
WCHAR VolumePathName[MAX_PATH], VolumeName[MAX_PATH];
|
WCHAR VolumePathName[MAX_PATH], VolumeName[MAX_PATH];
|
||||||
|
WCHAR FinalPath[MAX_PATH];
|
||||||
|
DWORD FinalResult;
|
||||||
|
|
||||||
Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint);
|
Result = FspFileSystemSetMountPoint(MemfsFileSystem(memfs), MountPoint);
|
||||||
|
if (STATUS_ACCESS_DENIED == Result)
|
||||||
|
{
|
||||||
|
FspDebugLog(__FUNCTION__ ": need Administrator\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
Prefix = FspFileSystemMountPoint(MemfsFileSystem(memfs));
|
Prefix = FspFileSystemMountPoint(MemfsFileSystem(memfs));
|
||||||
@ -125,6 +132,9 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
Handle = CreateFileW(FilePath,
|
Handle = CreateFileW(FilePath,
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
||||||
|
FinalResult = GetFinalPathNameByHandleW(
|
||||||
|
Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_DOS | FILE_NAME_OPENED);
|
||||||
|
ASSERT(0 != FinalResult && FinalResult < MAX_PATH);
|
||||||
CloseHandle(Handle);
|
CloseHandle(Handle);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
||||||
@ -187,6 +197,9 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
Handle = CreateFileW(FilePath,
|
Handle = CreateFileW(FilePath,
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
||||||
|
FinalResult = GetFinalPathNameByHandleW(
|
||||||
|
Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_DOS | FILE_NAME_OPENED);
|
||||||
|
ASSERT(0 != FinalResult && FinalResult < MAX_PATH);
|
||||||
CloseHandle(Handle);
|
CloseHandle(Handle);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
||||||
@ -232,6 +245,7 @@ static void volpath_mount_dotest(ULONG Flags, PWSTR Prefix, PWSTR MountPoint)
|
|||||||
ASSERT(VolumePathNameSuccess[6]);
|
ASSERT(VolumePathNameSuccess[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
memfs_stop(memfs);
|
memfs_stop(memfs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +284,24 @@ static void volpath_mount_test(void)
|
|||||||
|
|
||||||
//volpath_mount_dotest(MemfsDisk, 0, 0);
|
//volpath_mount_dotest(MemfsDisk, 0, 0);
|
||||||
volpath_mount_dotest(MemfsDisk, 0, MountPoint);
|
volpath_mount_dotest(MemfsDisk, 0, MountPoint);
|
||||||
|
|
||||||
|
WCHAR DirBuf[MAX_PATH];
|
||||||
|
int DirBufLen;
|
||||||
|
GetTestDirectory(DirBuf);
|
||||||
|
ASSERT(
|
||||||
|
L'\\' == DirBuf[0] &&
|
||||||
|
L'\\' == DirBuf[1] &&
|
||||||
|
L'?' == DirBuf[2] &&
|
||||||
|
L'\\' == DirBuf[3]);
|
||||||
|
DirBuf[2] = '.';
|
||||||
|
DirBufLen = lstrlenW(DirBuf);
|
||||||
|
ASSERT(MAX_PATH >= DirBufLen + 5);
|
||||||
|
DirBuf[DirBufLen++] = L'\\';
|
||||||
|
DirBuf[DirBufLen++] = L'm';
|
||||||
|
DirBuf[DirBufLen++] = L'n';
|
||||||
|
DirBuf[DirBufLen++] = L't';
|
||||||
|
DirBuf[DirBufLen++] = L'\0';
|
||||||
|
volpath_mount_dotest(MemfsDisk, 0, DirBuf);
|
||||||
}
|
}
|
||||||
if (WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user