mirror of
https://github.com/winfsp/winfsp.git
synced 2025-07-03 01:12:58 -05:00
Compare commits
1 Commits
v1.2
...
pvt-lockin
Author | SHA1 | Date | |
---|---|---|---|
778939d018 |
@ -1,19 +1,6 @@
|
|||||||
= Changelog
|
= Changelog
|
||||||
|
|
||||||
|
|
||||||
v1.2 (2017.2)::
|
|
||||||
|
|
||||||
Changes since v1.1:
|
|
||||||
|
|
||||||
- WinFsp-FUSE now supports BSD flags (Windows file attributes) during `getattr` and `fgetattr`. It also adds the `chflags` operation. BSD flags support requires use of the `FSP_FUSE_CAP_STAT_EX` capability and the new `struct fuse_stat_ex` which includes an `st_flags` field. If the preprocessor macro `FSP_FUSE_USE_STAT_EX` is defined before inclusion of `<fuse.h>` then `struct fuse_stat` will also be defined to include the `st_flags` field.
|
|
||||||
- WinFsp-FUSE also adds the following OSXFUSE operations: `setcrtime`, `setchgtime`. These can be used to set the creation (birth) time and change (ctime) time of a file.
|
|
||||||
- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`.
|
|
||||||
- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`.
|
|
||||||
- New command line tool `fsptool` allows command line access to some WinFsp features.
|
|
||||||
- The WinFsp launcher now passes the name of the user who launched the file system as a special parameter %U. This is useful to file systems that use the launcher infrastructure, such as SSHFS-Win. [Please note that in earlier betas the user name was passed as parameter %3; the previous method was insecure and is no longer supported.]
|
|
||||||
- Important GitHub issues fixed: #96, #97, #103, #107
|
|
||||||
|
|
||||||
|
|
||||||
v1.2B3 (2017.2 B3)::
|
v1.2B3 (2017.2 B3)::
|
||||||
|
|
||||||
Changes since v1.1:
|
Changes since v1.1:
|
||||||
|
32
README.md
32
README.md
@ -30,23 +30,21 @@ WinFsp consists of a kernel mode FSD (File System Driver) and a user mode DLL (D
|
|||||||
|
|
||||||
The project source code is organized as follows:
|
The project source code is organized as follows:
|
||||||
|
|
||||||
* `build/VStudio`: WinFsp solution and project files.
|
* build/VStudio: WinFsp solution and project files.
|
||||||
* `doc`: The WinFsp design documents and additional documentation can be found here.
|
* doc: The WinFsp design documents and additional documentation can be found here.
|
||||||
* `ext/tlib`: A small test library originally from the secfs (Secure Cloud File System) project.
|
* ext/tlib: A small test library originally from the secfs (Secure Cloud File System) project.
|
||||||
* `ext/test`: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
|
* ext/test: Submodule pointing to the secfs.test project, which contains a number of tools for testing Windows and POSIX file systems.
|
||||||
* `inc/fuse`: Public headers for the FUSE compatibility layer.
|
* inc/winfsp: Public headers for the WinFsp API.
|
||||||
* `inc/winfsp`: Public headers for the WinFsp API.
|
* inc/fuse: Public headers for the FUSE compatibility layer.
|
||||||
* `src/dll`: Source code to the WinFsp DLL.
|
* src/dll: Source code to the WinFsp DLL.
|
||||||
* `src/dll/fuse`: Source code to the FUSE compatibility layer.
|
* src/dll/fuse: Source code to the FUSE compatibility layer.
|
||||||
* `src/dotnet`: Source code to the .NET layer.
|
* src/dotnet: Source code to the .NET layer.
|
||||||
* `src/fsptool`: Source code to fsptool command line utility.
|
* src/launcher: Source code to the launcher service and the launchctl utility.
|
||||||
* `src/launcher`: Source code to the launcher service and the launchctl utility.
|
* src/sys: Source code to the WinFsp FSD.
|
||||||
* `src/sys`: Source code to the WinFsp FSD.
|
* opt/cygfuse: Source code for the Cygwin FUSE package.
|
||||||
* `opt/cygfuse`: Source code for the Cygwin FUSE package.
|
* tst/memfs*: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet).
|
||||||
* `tst/memfs*`: Source code to an example file system written in C/C++ (memfs) or C# (memfs-dotnet).
|
* tst/passthrough*: Source code to additional example file systems.
|
||||||
* `tst/passthrough*`: Source code to additional example file systems.
|
* tst/winfsp-tests: WinFsp test suite.
|
||||||
* `tst/winfsp-tests`: WinFsp test suite.
|
|
||||||
* `tools`: Various tools for building and testing WinFsp.
|
|
||||||
|
|
||||||
## Building and Running
|
## Building and Running
|
||||||
|
|
||||||
|
@ -310,12 +310,12 @@
|
|||||||
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
|
<Directory Id="OPTDIR.cygfuse" Name="cygfuse" FileSource="..\..\..\opt\cygfuse\dist">
|
||||||
<Directory Id="OPTDIR.cygfuse.x64" Name="x64">
|
<Directory Id="OPTDIR.cygfuse.x64" Name="x64">
|
||||||
<Component Id="C.fuse.tar.xz.x64">
|
<Component Id="C.fuse.tar.xz.x64">
|
||||||
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-7.tar.xz" KeyPath="yes" />
|
<File Id="FILE.fuse.tar.xz.x64" Name="fuse-2.8-6.tar.xz" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory Id="OPTDIR.cygfuse.x86" Name="x86">
|
<Directory Id="OPTDIR.cygfuse.x86" Name="x86">
|
||||||
<Component Id="C.fuse.tar.xz.x86">
|
<Component Id="C.fuse.tar.xz.x86">
|
||||||
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-7.tar.xz" KeyPath="yes" />
|
<File Id="FILE.fuse.tar.xz.x86" Name="fuse-2.8-6.tar.xz" KeyPath="yes" />
|
||||||
</Component>
|
</Component>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Component Id="C.fuse.install.sh">
|
<Component Id="C.fuse.install.sh">
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
<MyCanonicalVersion>1.2</MyCanonicalVersion>
|
<MyCanonicalVersion>1.2</MyCanonicalVersion>
|
||||||
|
|
||||||
<MyProductVersion>2017.2</MyProductVersion>
|
<MyProductVersion>2017.2 B3</MyProductVersion>
|
||||||
<MyProductStage>Gold</MyProductStage>
|
<MyProductStage>Beta</MyProductStage>
|
||||||
|
|
||||||
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
<MyVersion>$(MyCanonicalVersion).$(MyBuildNumber)</MyVersion>
|
||||||
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
<MyVersionWithCommas>$(MyVersion.Replace('.',',')),0</MyVersionWithCommas>
|
||||||
|
@ -28,7 +28,7 @@ if ($key.Count -eq 1) {
|
|||||||
-File "$file"
|
-File "$file"
|
||||||
}
|
}
|
||||||
} elseif ($key.Count -eq 0) {
|
} elseif ($key.Count -eq 0) {
|
||||||
# Write-Warning "$packageName is not installed"
|
Write-Warning "$packageName has already been uninstalled by other means."
|
||||||
} elseif ($key.Count -gt 1) {
|
} elseif ($key.Count -gt 1) {
|
||||||
Write-Warning "Too many matching packages found! Package may not be uninstalled."
|
Write-Warning "Too many matching packages found! Package may not be uninstalled."
|
||||||
Write-Warning "Please alert package maintainer the following packages were matched:"
|
Write-Warning "Please alert package maintainer the following packages were matched:"
|
@ -1,14 +1,16 @@
|
|||||||
$ErrorActionPreference = 'Stop';
|
$ErrorActionPreference = 'Stop';
|
||||||
|
|
||||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||||
. "$toolsdir\chocolateyHelper.ps1"
|
$fileLocation = @(Get-ChildItem $toolsDir -filter winfsp-*.msi)[0].FullName
|
||||||
|
|
||||||
$packageArgs = @{
|
$packageArgs = @{
|
||||||
packageName = 'winfsp'
|
packageName = 'winfsp'
|
||||||
fileType = 'msi'
|
fileType = 'msi'
|
||||||
file = @(Get-ChildItem $toolsDir -filter winfsp-*.msi)[0].FullName
|
file = $fileLocation
|
||||||
silentArgs = "/qn /norestart INSTALLLEVEL=1000"
|
silentArgs = "/qn /norestart INSTALLLEVEL=1000"
|
||||||
validExitCodes = @(0, 3010, 1641)
|
validExitCodes = @(0, 3010, 1641)
|
||||||
}
|
}
|
||||||
|
|
||||||
Install-ChocolateyInstallPackage @packageArgs
|
Install-ChocolateyInstallPackage @packageArgs
|
||||||
|
|
||||||
Remove-Item -Force $packageArgs.file
|
Remove-Item -Force $packageArgs.file
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
$ErrorActionPreference = 'Stop';
|
|
||||||
|
|
||||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
|
||||||
. "$toolsdir\chocolateyHelper.ps1"
|
|
@ -50,8 +50,7 @@ To verify installation:
|
|||||||
<file src="LICENSE.txt" target="tools" />
|
<file src="LICENSE.txt" target="tools" />
|
||||||
<file src="VERIFICATION.txt" target="tools" />
|
<file src="VERIFICATION.txt" target="tools" />
|
||||||
<file src="chocolateyInstall.ps1" target="tools" />
|
<file src="chocolateyInstall.ps1" target="tools" />
|
||||||
<file src="chocolateyUninstall.ps1" target="tools" />
|
<file src="chocolateyBeforeModify.ps1" target="tools" />
|
||||||
<file src="chocolateyHelper.ps1" target="tools" />
|
|
||||||
<file src="winfsp-$version$.msi" target="tools" />
|
<file src="winfsp-$version$.msi" target="tools" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
||||||
|
@ -4,8 +4,6 @@ This document contains a list of known file systems and file system libraries th
|
|||||||
|
|
||||||
== File Systems
|
== File Systems
|
||||||
|
|
||||||
- https://github.com/ihaveamac/fuse-3ds[fuse-3ds] - FUSE Filesystem Python scripts for Nintendo 3DS files
|
|
||||||
- https://github.com/FrKaram/KS2.Drive[KS2.Drive] - Mount a webDAV/AOS server as a local drive
|
|
||||||
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
|
- https://github.com/billziss-gh/nfs-win[nfs-win] - NFS for Windows
|
||||||
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage
|
- https://github.com/ncw/rclone[rclone] - rsync for cloud storage
|
||||||
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
|
- https://github.com/hasse69/rar2fs[rar2fs] - FUSE file system for reading RAR archives
|
||||||
|
@ -153,7 +153,8 @@ typedef struct
|
|||||||
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
|
UINT32 PassQueryDirectoryPattern:1; /* pass Pattern during QueryDirectory operations */
|
||||||
UINT32 AlwaysUseDoubleBuffering:1;
|
UINT32 AlwaysUseDoubleBuffering:1;
|
||||||
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */
|
UINT32 PassQueryDirectoryFileName:1; /* pass FileName during QueryDirectory (GetDirInfoByName) */
|
||||||
UINT32 KmReservedFlags:2;
|
UINT32 UserModeFileLocking:1; /* pass file locking requests to user mode */
|
||||||
|
UINT32 KmReservedFlags:1;
|
||||||
/* user-mode flags */
|
/* user-mode flags */
|
||||||
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
UINT32 UmFileContextIsUserContext2:1; /* user mode: FileContext parameter is UserContext2 */
|
||||||
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
|
UINT32 UmFileContextIsFullContext:1; /* user mode: FileContext parameter is FullContext */
|
||||||
@ -259,6 +260,7 @@ typedef struct
|
|||||||
UINT32 SetLastAccessTime:1;
|
UINT32 SetLastAccessTime:1;
|
||||||
UINT32 SetLastWriteTime:1;
|
UINT32 SetLastWriteTime:1;
|
||||||
UINT32 SetChangeTime:1;
|
UINT32 SetChangeTime:1;
|
||||||
|
UINT32 UnlockAll:1;
|
||||||
} Cleanup;
|
} Cleanup;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -273,6 +275,7 @@ typedef struct
|
|||||||
UINT64 Offset;
|
UINT64 Offset;
|
||||||
UINT32 Length;
|
UINT32 Length;
|
||||||
UINT32 Key;
|
UINT32 Key;
|
||||||
|
UINT32 ProcessId;
|
||||||
} Read;
|
} Read;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -283,6 +286,8 @@ typedef struct
|
|||||||
UINT32 Length;
|
UINT32 Length;
|
||||||
UINT32 Key;
|
UINT32 Key;
|
||||||
UINT32 ConstrainedIo:1;
|
UINT32 ConstrainedIo:1;
|
||||||
|
UINT32 ReservedFlags:31;
|
||||||
|
UINT32 ProcessId;
|
||||||
} Write;
|
} Write;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -359,6 +364,18 @@ typedef struct
|
|||||||
UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */
|
UINT16 TargetOnFileSystem; /* the target of the symbolic link is on this file system */
|
||||||
} FileSystemControl;
|
} FileSystemControl;
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
UINT64 UserContext;
|
||||||
|
UINT64 UserContext2;
|
||||||
|
UINT32 LockFunction;
|
||||||
|
UINT64 Offset;
|
||||||
|
UINT64 Length;
|
||||||
|
UINT32 Key;
|
||||||
|
UINT32 ProcessId;
|
||||||
|
UINT32 Exclusive:1;
|
||||||
|
UINT32 FailImmediately:1;
|
||||||
|
} LockControl;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
UINT64 UserContext;
|
UINT64 UserContext;
|
||||||
UINT64 UserContext2;
|
UINT64 UserContext2;
|
||||||
|
@ -133,6 +133,7 @@ enum
|
|||||||
FspCleanupSetLastAccessTime = 0x20,
|
FspCleanupSetLastAccessTime = 0x20,
|
||||||
FspCleanupSetLastWriteTime = 0x40,
|
FspCleanupSetLastWriteTime = 0x40,
|
||||||
FspCleanupSetChangeTime = 0x80,
|
FspCleanupSetChangeTime = 0x80,
|
||||||
|
FspCleanupUnlockAll = 0x0100,
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* @class FSP_FILE_SYSTEM
|
* @class FSP_FILE_SYSTEM
|
||||||
@ -822,12 +823,80 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*GetDirInfoByName)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PVOID FileContext, PWSTR FileName,
|
PVOID FileContext, PWSTR FileName,
|
||||||
FSP_FSCTL_DIR_INFO *DirInfo);
|
FSP_FSCTL_DIR_INFO *DirInfo);
|
||||||
|
/**
|
||||||
|
* Lock a file range.
|
||||||
|
*
|
||||||
|
* At the time of this call the FSD has already done its own locking processing.
|
||||||
|
* Thus the kernel may fail a lock control request or a Read or Write without
|
||||||
|
* informing the user mode file system.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system on which this request is posted.
|
||||||
|
* @param FileContext
|
||||||
|
* The file context of the file to be locked.
|
||||||
|
* @param Offset
|
||||||
|
* Offset within the file to lock.
|
||||||
|
* @param Length
|
||||||
|
* Length of data to lock.
|
||||||
|
* @param Owner
|
||||||
|
* Lock owner. This 64-bit value consists of a PID in the high 32-bits and a "Key"
|
||||||
|
* in the low 32-bits. The PID is that of the process requesting the lock. The Key
|
||||||
|
* is an arbitrary value.
|
||||||
|
*
|
||||||
|
* The triplet (FileDesc,PID,Key) uniquely identifies the lock owner.
|
||||||
|
* @param Exclusive
|
||||||
|
* When TRUE an exclusive lock is requested. Otherwise a shared lock is requested.
|
||||||
|
* @param FailImmediately
|
||||||
|
* When TRUE the function should return immediately if it is unable to acquire the
|
||||||
|
* requested lock. Otherwise the function should wait until the lock can be granted.
|
||||||
|
* In this case the function may also return STATUS_PENDING.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
NTSTATUS (*Lock)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileContext, UINT64 Offset, UINT64 Length, UINT64 Owner,
|
||||||
|
BOOLEAN Exclusive, BOOLEAN FailImmediately);
|
||||||
|
/**
|
||||||
|
* Unlock file ranges.
|
||||||
|
*
|
||||||
|
* At the time of this call the FSD has already done its own locking processing.
|
||||||
|
* Thus the kernel may fail a lock control request or a Read or Write without
|
||||||
|
* informing the user mode file system.
|
||||||
|
*
|
||||||
|
* An Unlock operation with Offset == Length == -1 is a request to remove multiple locks.
|
||||||
|
* The set of possible locks to remove includes all locks made by the process described
|
||||||
|
* by the Owner parameter through the file descriptor described by the FileContext parameter.
|
||||||
|
* If the Key portion of the Owner parameter is 0, all the locks in the set are removed.
|
||||||
|
* If the Key portion of the Owner paramter is non-0, only locks that match the Key are
|
||||||
|
* removed.
|
||||||
|
*
|
||||||
|
* @param FileSystem
|
||||||
|
* The file system on which this request is posted.
|
||||||
|
* @param FileContext
|
||||||
|
* The file context of the file to be unlocked.
|
||||||
|
* @param Offset
|
||||||
|
* Offset within the file to unlock.
|
||||||
|
* @param Length
|
||||||
|
* Length of data to unlock.
|
||||||
|
* @param Owner
|
||||||
|
* Lock owner. This 64-bit value consists of a PID in the high 32-bits and a "Key"
|
||||||
|
* in the low 32-bits. The PID is that of the process requesting the lock. The Key
|
||||||
|
* is an arbitrary value.
|
||||||
|
*
|
||||||
|
* The triplet (FileDesc,PID,Key) uniquely identifies the lock owner.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS or error code. STATUS_PENDING is supported allowing for asynchronous
|
||||||
|
* operation.
|
||||||
|
*/
|
||||||
|
NTSTATUS (*Unlock)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileContext, UINT64 Offset, UINT64 Length, UINT64 Owner);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This ensures that this interface will always contain 64 function pointers.
|
* This ensures that this interface will always contain 64 function pointers.
|
||||||
* Please update when changing the interface as it is important for future compatibility.
|
* Please update when changing the interface as it is important for future compatibility.
|
||||||
*/
|
*/
|
||||||
NTSTATUS (*Reserved[39])();
|
NTSTATUS (*Reserved[37])();
|
||||||
} FSP_FILE_SYSTEM_INTERFACE;
|
} FSP_FILE_SYSTEM_INTERFACE;
|
||||||
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
|
FSP_FSCTL_STATIC_ASSERT(sizeof(FSP_FILE_SYSTEM_INTERFACE) == 64 * sizeof(NTSTATUS (*)()),
|
||||||
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
|
"FSP_FILE_SYSTEM_INTERFACE must have 64 entries.");
|
||||||
@ -1086,7 +1155,7 @@ BOOLEAN FspFileSystemIsOperationCaseSensitive(VOID)
|
|||||||
}
|
}
|
||||||
FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID);
|
FSP_API BOOLEAN FspFileSystemIsOperationCaseSensitiveF(VOID);
|
||||||
/**
|
/**
|
||||||
* Gets the originating process ID.
|
* Get the originating process ID.
|
||||||
*
|
*
|
||||||
* Valid only during Create, Open and Rename requests when the target exists.
|
* Valid only during Create, Open and Rename requests when the target exists.
|
||||||
*/
|
*/
|
||||||
@ -1107,6 +1176,28 @@ UINT32 FspFileSystemOperationProcessId(VOID)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID);
|
FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID);
|
||||||
|
/**
|
||||||
|
* Get the lock owner.
|
||||||
|
*
|
||||||
|
* Valid only during Read, Write, Lock and Unlock requests.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
UINT64 FspFileSystemOperationLockOwner(VOID)
|
||||||
|
{
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspFileSystemGetOperationContext()->Request;
|
||||||
|
switch (Request->Kind)
|
||||||
|
{
|
||||||
|
case FspFsctlTransactReadKind:
|
||||||
|
return ((UINT64)Request->Req.Read.ProcessId << 32) | (UINT64)Request->Req.Read.Key;
|
||||||
|
case FspFsctlTransactWriteKind:
|
||||||
|
return ((UINT64)Request->Req.Write.ProcessId << 32) | (UINT64)Request->Req.Write.Key;
|
||||||
|
case FspFsctlTransactLockControlKind:
|
||||||
|
return ((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FSP_API UINT64 FspFileSystemOperationLockOwnerF(VOID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Operations
|
* Operations
|
||||||
@ -1141,6 +1232,8 @@ FSP_API NTSTATUS FspFileSystemOpQueryDirectory(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
FSP_API NTSTATUS FspFileSystemOpLockControl(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpSetSecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
@ -22,9 +22,7 @@ cygport:
|
|||||||
dist: cygport
|
dist: cygport
|
||||||
case $(shell uname -m) in \
|
case $(shell uname -m) in \
|
||||||
x86_64)\
|
x86_64)\
|
||||||
mkdir -p dist/x64 && \
|
|
||||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\
|
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x64 ;;\
|
||||||
*)\
|
*)\
|
||||||
mkdir -p dist/x86 && \
|
|
||||||
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\
|
cp fuse-*/dist/fuse/fuse-*[0-9].tar.xz dist/x86 ;;\
|
||||||
esac
|
esac
|
||||||
|
BIN
opt/cygfuse/dist/x64/fuse-2.8-6.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x64/fuse-2.8-6.tar.xz
vendored
Normal file
Binary file not shown.
BIN
opt/cygfuse/dist/x64/fuse-2.8-7.tar.xz
vendored
BIN
opt/cygfuse/dist/x64/fuse-2.8-7.tar.xz
vendored
Binary file not shown.
BIN
opt/cygfuse/dist/x86/fuse-2.8-6.tar.xz
vendored
Normal file
BIN
opt/cygfuse/dist/x86/fuse-2.8-6.tar.xz
vendored
Normal file
Binary file not shown.
BIN
opt/cygfuse/dist/x86/fuse-2.8-7.tar.xz
vendored
BIN
opt/cygfuse/dist/x86/fuse-2.8-7.tar.xz
vendored
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
NAME="fuse"
|
NAME="fuse"
|
||||||
VERSION=2.8
|
VERSION=2.8
|
||||||
RELEASE=7
|
RELEASE=6
|
||||||
CATEGORY="Utils"
|
CATEGORY="Utils"
|
||||||
SUMMARY="WinFsp-FUSE compatibility layer"
|
SUMMARY="WinFsp-FUSE compatibility layer"
|
||||||
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin."
|
DESCRIPTION="WinFsp-FUSE enables FUSE file systems to be run on Cygwin."
|
||||||
|
@ -162,6 +162,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
|||||||
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
|
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
|
||||||
FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory;
|
FileSystem->Operations[FspFsctlTransactQueryDirectoryKind] = FspFileSystemOpQueryDirectory;
|
||||||
FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl;
|
FileSystem->Operations[FspFsctlTransactFileSystemControlKind] = FspFileSystemOpFileSystemControl;
|
||||||
|
FileSystem->Operations[FspFsctlTransactLockControlKind] = FspFileSystemOpLockControl;
|
||||||
FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity;
|
FileSystem->Operations[FspFsctlTransactQuerySecurityKind] = FspFileSystemOpQuerySecurity;
|
||||||
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
|
FileSystem->Operations[FspFsctlTransactSetSecurityKind] = FspFileSystemOpSetSecurity;
|
||||||
FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation;
|
FileSystem->Operations[FspFsctlTransactQueryStreamInformationKind] = FspFileSystemOpQueryStreamInformation;
|
||||||
@ -688,3 +689,8 @@ FSP_API UINT32 FspFileSystemOperationProcessIdF(VOID)
|
|||||||
{
|
{
|
||||||
return FspFileSystemOperationProcessId();
|
return FspFileSystemOperationProcessId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API UINT64 FspFileSystemOperationLockOwnerF(VOID)
|
||||||
|
{
|
||||||
|
return FspFileSystemOperationLockOwner();
|
||||||
|
}
|
||||||
|
@ -886,6 +886,7 @@ FSP_API NTSTATUS FspFileSystemOpCleanup(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
|
(0 != Request->Req.Cleanup.SetArchiveBit ? FspCleanupSetArchiveBit : 0) |
|
||||||
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
|
(0 != Request->Req.Cleanup.SetLastAccessTime ? FspCleanupSetLastAccessTime : 0) |
|
||||||
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
|
(0 != Request->Req.Cleanup.SetLastWriteTime ? FspCleanupSetLastWriteTime : 0) |
|
||||||
|
(0 != Request->Req.Cleanup.UnlockAll ? FspCleanupUnlockAll : 0) |
|
||||||
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
|
(0 != Request->Req.Cleanup.SetChangeTime ? FspCleanupSetChangeTime : 0));
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -1247,6 +1248,43 @@ FSP_API NTSTATUS FspFileSystemOpFileSystemControl(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemOpLockControl(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
switch (Request->Req.LockControl.LockFunction)
|
||||||
|
{
|
||||||
|
case 0x01/*IRP_MN_LOCK*/:
|
||||||
|
if (0 != FileSystem->Interface->Lock)
|
||||||
|
Result = FileSystem->Interface->Lock(FileSystem,
|
||||||
|
(PVOID)ValOfFileContext(Request->Req.LockControl),
|
||||||
|
Request->Req.LockControl.Offset, Request->Req.LockControl.Length,
|
||||||
|
((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key,
|
||||||
|
0 != Request->Req.LockControl.Exclusive,
|
||||||
|
0 != Request->Req.LockControl.FailImmediately);
|
||||||
|
break;
|
||||||
|
case 0x02/*IRP_MN_UNLOCK_SINGLE*/:
|
||||||
|
if (0 != FileSystem->Interface->Unlock)
|
||||||
|
Result = FileSystem->Interface->Unlock(FileSystem,
|
||||||
|
(PVOID)ValOfFileContext(Request->Req.LockControl),
|
||||||
|
Request->Req.LockControl.Offset, Request->Req.LockControl.Length,
|
||||||
|
((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key);
|
||||||
|
break;
|
||||||
|
case 0x03/*IRP_MN_UNLOCK_ALL*/:
|
||||||
|
case 0x04/*IRP_MN_UNLOCK_ALL_BY_KEY*/:
|
||||||
|
if (0 != FileSystem->Interface->Unlock)
|
||||||
|
Result = FileSystem->Interface->Unlock(FileSystem,
|
||||||
|
(PVOID)ValOfFileContext(Request->Req.LockControl),
|
||||||
|
(UINT64)-1LL, (UINT64)-1LL,
|
||||||
|
((UINT64)Request->Req.LockControl.ProcessId << 32) | (UINT64)Request->Req.LockControl.Key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQuerySecurity(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
|
@ -765,9 +765,9 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
memset(&fi, 0, sizeof fi);
|
memset(&fi, 0, sizeof fi);
|
||||||
if ('C' == f->env->environment) /* Cygwin */
|
if ('C' == f->env->environment) /* Cygwin */
|
||||||
fi.flags = 0x0200 | 0x0800 | 2 /*O_CREAT|O_EXCL|O_RDWR*/;
|
fi.flags = 0x0200 | 2 /*O_CREAT|O_RDWR*/;
|
||||||
else
|
else
|
||||||
fi.flags = 0x0100 | 0x0400 | 2 /*O_CREAT|O_EXCL|O_RDWR*/;
|
fi.flags = 0x0100 | 2 /*O_CREAT|O_RDWR*/;
|
||||||
|
|
||||||
if (CreateOptions & FILE_DIRECTORY_FILE)
|
if (CreateOptions & FILE_DIRECTORY_FILE)
|
||||||
{
|
{
|
||||||
@ -821,25 +821,16 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
|
|
||||||
Opened = TRUE;
|
Opened = TRUE;
|
||||||
|
|
||||||
if (0 != FileAttributes &&
|
if (Uid != context->uid || Gid != context->gid)
|
||||||
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
if (0 != f->ops.chown)
|
||||||
{
|
{
|
||||||
err = f->ops.chflags(contexthdr->PosixPath,
|
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
|
||||||
fsp_fuse_intf_MapFileAttributesToFlags(CreateOptions & FILE_DIRECTORY_FILE ?
|
if (0 != err)
|
||||||
FileAttributes : FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
|
{
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
||||||
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
goto exit;
|
||||||
goto exit;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Uid != context->uid || Gid != context->gid) &&
|
|
||||||
0 != f->ops.chown)
|
|
||||||
{
|
|
||||||
err = f->ops.chown(contexthdr->PosixPath, Uid, Gid);
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
|
* Ignore fuse_file_info::direct_io, fuse_file_info::keep_cache.
|
||||||
@ -1024,22 +1015,6 @@ static NTSTATUS fsp_fuse_intf_Overwrite(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
if (0 != FileAttributes &&
|
|
||||||
0 != (f->conn_want & FSP_FUSE_CAP_STAT_EX) && 0 != f->ops.chflags)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The code below is not strictly correct. File attributes should be
|
|
||||||
* replaced when ReplaceFileAttributes is TRUE and merged (or'ed) when
|
|
||||||
* ReplaceFileAttributes is FALSE. I am punting on this detail for now.
|
|
||||||
*/
|
|
||||||
|
|
||||||
err = f->ops.chflags(filedesc->PosixPath,
|
|
||||||
fsp_fuse_intf_MapFileAttributesToFlags(FileAttributes | FILE_ATTRIBUTE_ARCHIVE));
|
|
||||||
Result = fsp_fuse_ntstatus_from_errno(f->env, err);
|
|
||||||
if (!NT_SUCCESS(Result) && STATUS_INVALID_DEVICE_REQUEST != Result)
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
return fsp_fuse_intf_GetFileInfoEx(FileSystem, filedesc->PosixPath, &fi,
|
||||||
&Uid, &Gid, &Mode, FileInfo);
|
&Uid, &Gid, &Mode, FileInfo);
|
||||||
}
|
}
|
||||||
|
12
src/dll/np.c
12
src/dll/np.c
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
#include <launcher/launcher.h>
|
#include <launcher/launcher.h>
|
||||||
|
#include <lmcons.h>
|
||||||
#include <npapi.h>
|
#include <npapi.h>
|
||||||
#include <wincred.h>
|
#include <wincred.h>
|
||||||
|
|
||||||
@ -168,6 +169,12 @@ static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOLEAN FspNpGetLocalUserName(
|
||||||
|
PWSTR UserName, ULONG UserNameSize/* in chars */)
|
||||||
|
{
|
||||||
|
return GetUserName(UserName, &UserNameSize);
|
||||||
|
}
|
||||||
|
|
||||||
static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
||||||
{
|
{
|
||||||
DWORD NpResult;
|
DWORD NpResult;
|
||||||
@ -489,6 +496,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
WCHAR LocalNameBuf[3];
|
WCHAR LocalNameBuf[3];
|
||||||
PWSTR ClassName, InstanceName, RemoteName, P;
|
PWSTR ClassName, InstanceName, RemoteName, P;
|
||||||
ULONG ClassNameLen, InstanceNameLen;
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
|
WCHAR LocalUserName[UNLEN + 1];
|
||||||
DWORD CredentialsKind;
|
DWORD CredentialsKind;
|
||||||
PWSTR PipeBuf = 0;
|
PWSTR PipeBuf = 0;
|
||||||
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
||||||
@ -517,6 +525,9 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
return WN_ALREADY_CONNECTED;
|
return WN_ALREADY_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FspNpGetLocalUserName(LocalUserName, sizeof LocalUserName / sizeof LocalUserName[0]))
|
||||||
|
LocalUserName[0] = L'\0';
|
||||||
|
|
||||||
FspNpGetCredentialsKind(lpRemoteName, &CredentialsKind);
|
FspNpGetCredentialsKind(lpRemoteName, &CredentialsKind);
|
||||||
|
|
||||||
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
#if defined(FSP_NP_CREDENTIAL_MANAGER)
|
||||||
@ -571,6 +582,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword,
|
|||||||
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
||||||
lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1;
|
lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1;
|
||||||
lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1;
|
lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1;
|
||||||
|
lstrcpyW(P, LocalUserName); P += lstrlenW(LocalUserName) + 1;
|
||||||
if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
|
if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind)
|
||||||
{
|
{
|
||||||
lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1;
|
lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1;
|
||||||
|
@ -67,76 +67,6 @@ BOOL CreateOverlappedPipe(
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS GetTokenUserName(HANDLE Token, PWSTR *PUserName)
|
|
||||||
{
|
|
||||||
TOKEN_USER *User = 0;
|
|
||||||
WCHAR Name[256], Domn[256];
|
|
||||||
DWORD UserSize, NameSize, DomnSize;
|
|
||||||
SID_NAME_USE Use;
|
|
||||||
PWSTR P;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
*PUserName = 0;
|
|
||||||
|
|
||||||
if (GetTokenInformation(Token, TokenUser, 0, 0, &UserSize))
|
|
||||||
{
|
|
||||||
Result = STATUS_INVALID_PARAMETER;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
User = MemAlloc(UserSize);
|
|
||||||
if (0 == User)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetTokenInformation(Token, TokenUser, User, UserSize, &UserSize))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameSize = sizeof Name / sizeof Name[0];
|
|
||||||
DomnSize = sizeof Domn / sizeof Domn[0];
|
|
||||||
if (!LookupAccountSidW(0, User->User.Sid, Name, &NameSize, Domn, &DomnSize, &Use))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
NameSize = lstrlenW(Name);
|
|
||||||
DomnSize = lstrlenW(Domn);
|
|
||||||
|
|
||||||
P = *PUserName = MemAlloc((DomnSize + 1 + NameSize + 1) * sizeof(WCHAR));
|
|
||||||
if (0 == P)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 < DomnSize)
|
|
||||||
{
|
|
||||||
memcpy(P, Domn, DomnSize * sizeof(WCHAR));
|
|
||||||
P[DomnSize] = L'\\';
|
|
||||||
P += DomnSize + 1;
|
|
||||||
}
|
|
||||||
memcpy(P, Name, NameSize * sizeof(WCHAR));
|
|
||||||
P[NameSize] = L'\0';
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
MemFree(User);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Process;
|
HANDLE Process;
|
||||||
@ -212,17 +142,6 @@ typedef struct
|
|||||||
static CRITICAL_SECTION SvcInstanceLock;
|
static CRITICAL_SECTION SvcInstanceLock;
|
||||||
static HANDLE SvcInstanceEvent;
|
static HANDLE SvcInstanceEvent;
|
||||||
static LIST_ENTRY SvcInstanceList = { &SvcInstanceList, &SvcInstanceList };
|
static LIST_ENTRY SvcInstanceList = { &SvcInstanceList, &SvcInstanceList };
|
||||||
static DWORD SvcInstanceTlsKey = TLS_OUT_OF_INDEXES;
|
|
||||||
|
|
||||||
static inline PWSTR SvcInstanceUserName(VOID)
|
|
||||||
{
|
|
||||||
return TlsGetValue(SvcInstanceTlsKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline VOID SvcInstanceSetUserName(PWSTR UserName)
|
|
||||||
{
|
|
||||||
TlsSetValue(SvcInstanceTlsKey, UserName);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout);
|
static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout);
|
||||||
|
|
||||||
@ -291,14 +210,6 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
else
|
else
|
||||||
Length += SvcInstanceArgumentLength(EmptyArg);
|
Length += SvcInstanceArgumentLength(EmptyArg);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (L'U' == *P)
|
|
||||||
{
|
|
||||||
if (0 != SvcInstanceUserName())
|
|
||||||
Length += SvcInstanceArgumentLength(SvcInstanceUserName());
|
|
||||||
else
|
|
||||||
Length += SvcInstanceArgumentLength(EmptyArg);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
Length++;
|
Length++;
|
||||||
break;
|
break;
|
||||||
@ -325,14 +236,6 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
else
|
else
|
||||||
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (L'U' == *P)
|
|
||||||
{
|
|
||||||
if (0 != SvcInstanceUserName())
|
|
||||||
Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName());
|
|
||||||
else
|
|
||||||
Q = SvcInstanceArgumentCopy(Q, EmptyArg);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
*Q++ = *P;
|
*Q++ = *P;
|
||||||
break;
|
break;
|
||||||
@ -1015,10 +918,6 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
if (0 == SvcInstanceEvent)
|
if (0 == SvcInstanceEvent)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
SvcInstanceTlsKey = TlsAlloc();
|
|
||||||
if (TLS_OUT_OF_INDEXES == SvcInstanceTlsKey)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
SvcJob = CreateJobObjectW(0, 0);
|
SvcJob = CreateJobObjectW(0, 0);
|
||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
{
|
{
|
||||||
@ -1081,9 +980,6 @@ fail:
|
|||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
CloseHandle(SvcJob);
|
CloseHandle(SvcJob);
|
||||||
|
|
||||||
if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey)
|
|
||||||
TlsFree(SvcInstanceTlsKey);
|
|
||||||
|
|
||||||
if (0 != SvcInstanceEvent)
|
if (0 != SvcInstanceEvent)
|
||||||
CloseHandle(SvcInstanceEvent);
|
CloseHandle(SvcInstanceEvent);
|
||||||
|
|
||||||
@ -1127,9 +1023,6 @@ static NTSTATUS SvcStop(FSP_SERVICE *Service)
|
|||||||
if (0 != SvcJob)
|
if (0 != SvcJob)
|
||||||
CloseHandle(SvcJob);
|
CloseHandle(SvcJob);
|
||||||
|
|
||||||
if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey)
|
|
||||||
TlsFree(SvcInstanceTlsKey);
|
|
||||||
|
|
||||||
if (0 != SvcInstanceEvent)
|
if (0 != SvcInstanceEvent)
|
||||||
CloseHandle(SvcInstanceEvent);
|
CloseHandle(SvcInstanceEvent);
|
||||||
|
|
||||||
@ -1301,16 +1194,13 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
||||||
PWSTR ClassName, InstanceName, UserName;
|
PWSTR ClassName, InstanceName;
|
||||||
ULONG Argc; PWSTR Argv[9];
|
ULONG Argc; PWSTR Argv[9];
|
||||||
BOOLEAN HasSecret = FALSE;
|
BOOLEAN HasSecret = FALSE;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
*PSize = 0;
|
*PSize = 0;
|
||||||
|
|
||||||
GetTokenUserName(ClientToken, &UserName);
|
|
||||||
SvcInstanceSetUserName(UserName);
|
|
||||||
|
|
||||||
switch (*P++)
|
switch (*P++)
|
||||||
{
|
{
|
||||||
case LauncherSvcInstanceStartWithSecret:
|
case LauncherSvcInstanceStartWithSecret:
|
||||||
@ -1374,9 +1264,6 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
SvcPipeTransactResult(STATUS_INVALID_PARAMETER, PipeBuf, PSize);
|
SvcPipeTransactResult(STATUS_INVALID_PARAMETER, PipeBuf, PSize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SvcInstanceSetUserName(0);
|
|
||||||
MemFree(UserName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
|
@ -117,6 +117,8 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime;
|
Request->Req.Cleanup.SetLastWriteTime = FileModified && !FileDesc->DidSetLastWriteTime;
|
||||||
Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) &&
|
Request->Req.Cleanup.SetChangeTime = (FileModified || FileDesc->DidSetMetadata) &&
|
||||||
!FileDesc->DidSetChangeTime;
|
!FileDesc->DidSetChangeTime;
|
||||||
|
Request->Req.Cleanup.UnlockAll = FsvolDeviceExtension->VolumeParams.UserModeFileLocking &&
|
||||||
|
FsRtlAreThereCurrentOrInProgressFileLocks(&FileNode->FileLock);
|
||||||
|
|
||||||
FspFileNodeAcquireExclusive(FileNode, Pgio);
|
FspFileNodeAcquireExclusive(FileNode, Pgio);
|
||||||
|
|
||||||
@ -128,6 +130,7 @@ static NTSTATUS FspFsvolCleanup(
|
|||||||
Request->Req.Cleanup.SetArchiveBit ||
|
Request->Req.Cleanup.SetArchiveBit ||
|
||||||
Request->Req.Cleanup.SetLastWriteTime ||
|
Request->Req.Cleanup.SetLastWriteTime ||
|
||||||
Request->Req.Cleanup.SetChangeTime ||
|
Request->Req.Cleanup.SetChangeTime ||
|
||||||
|
Request->Req.Cleanup.UnlockAll ||
|
||||||
!FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly)
|
!FsvolDeviceExtension->VolumeParams.PostCleanupWhenModifiedOnly)
|
||||||
/*
|
/*
|
||||||
* Note that it is still possible for this request to not be delivered,
|
* Note that it is still possible for this request to not be delivered,
|
||||||
|
@ -611,7 +611,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry(
|
|||||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||||
{
|
{
|
||||||
ASSERT(
|
ASSERT(
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
|
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
||||||
FileDesc->DirectoryMarker.Length);
|
FileDesc->DirectoryMarker.Length);
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Marker.Offset =
|
Request->Req.QueryDirectory.Marker.Offset =
|
||||||
@ -921,7 +921,7 @@ NTSTATUS FspFsvolDirectoryControlComplete(
|
|||||||
if (0 != FileDesc->DirectoryMarker.Buffer)
|
if (0 != FileDesc->DirectoryMarker.Buffer)
|
||||||
{
|
{
|
||||||
ASSERT(
|
ASSERT(
|
||||||
FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) >=
|
FsvolDeviceExtension->VolumeParams.MaxComponentLength >=
|
||||||
FileDesc->DirectoryMarker.Length);
|
FileDesc->DirectoryMarker.Length);
|
||||||
|
|
||||||
Request->Req.QueryDirectory.Marker.Offset =
|
Request->Req.QueryDirectory.Marker.Offset =
|
||||||
|
@ -128,6 +128,7 @@ NTSTATUS DriverEntry(
|
|||||||
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
|
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
|
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete;
|
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete;
|
||||||
|
FspFileNodeCompleteLockIrp = FspFsvolLockControlForward;
|
||||||
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
||||||
|
@ -316,6 +316,7 @@ FSP_IOPREP_DISPATCH FspFsvolDirectoryControlPrepare;
|
|||||||
FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolDirectoryControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolFileSystemControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolFlushBuffersComplete;
|
||||||
|
NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolQueryEaComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete;
|
||||||
@ -1564,6 +1565,7 @@ extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
|||||||
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
||||||
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[];
|
||||||
extern ERESOURCE FspDeviceGlobalResource;
|
extern ERESOURCE FspDeviceGlobalResource;
|
||||||
|
extern PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp;
|
||||||
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
|
extern WCHAR FspFileDescDirectoryPatternMatchAll[];
|
||||||
extern const GUID FspMainFileOpenEcpGuid;
|
extern const GUID FspMainFileOpenEcpGuid;
|
||||||
extern ULONG FspProcessorCount;
|
extern ULONG FspProcessorCount;
|
||||||
|
@ -83,7 +83,6 @@ VOID FspFileNodeInvalidateStreamInfo(FSP_FILE_NODE *FileNode);
|
|||||||
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
VOID FspFileNodeNotifyChange(FSP_FILE_NODE *FileNode, ULONG Filter, ULONG Action,
|
||||||
BOOLEAN InvalidateCaches);
|
BOOLEAN InvalidateCaches);
|
||||||
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp);
|
||||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp);
|
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc);
|
||||||
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc);
|
||||||
NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc,
|
NTSTATUS FspFileDescResetDirectory(FSP_FILE_DESC *FileDesc,
|
||||||
@ -149,7 +148,6 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp);
|
|||||||
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateStreamInfo)
|
// !#pragma alloc_text(PAGE, FspFileNodeInvalidateStreamInfo)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeNotifyChange)
|
#pragma alloc_text(PAGE, FspFileNodeNotifyChange)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeProcessLockIrp)
|
#pragma alloc_text(PAGE, FspFileNodeProcessLockIrp)
|
||||||
#pragma alloc_text(PAGE, FspFileNodeCompleteLockIrp)
|
|
||||||
#pragma alloc_text(PAGE, FspFileDescCreate)
|
#pragma alloc_text(PAGE, FspFileDescCreate)
|
||||||
#pragma alloc_text(PAGE, FspFileDescDelete)
|
#pragma alloc_text(PAGE, FspFileDescDelete)
|
||||||
#pragma alloc_text(PAGE, FspFileDescResetDirectory)
|
#pragma alloc_text(PAGE, FspFileDescResetDirectory)
|
||||||
@ -2030,19 +2028,6 @@ NTSTATUS FspFileNodeProcessLockIrp(FSP_FILE_NODE *FileNode, PIRP Irp)
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileNodeCompleteLockIrp(PVOID Context, PIRP Irp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
NTSTATUS Result = Irp->IoStatus.Status;
|
|
||||||
|
|
||||||
DEBUGLOGIRP(Irp, Result);
|
|
||||||
|
|
||||||
FspIopCompleteIrp(Irp, Result);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc)
|
NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
@ -2166,7 +2151,7 @@ NTSTATUS FspFileDescSetDirectoryMarker(FSP_FILE_DESC *FileDesc,
|
|||||||
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
|
FspFsvolDeviceExtension(FileDesc->FileNode->FsvolDeviceObject);
|
||||||
UNICODE_STRING DirectoryMarker;
|
UNICODE_STRING DirectoryMarker;
|
||||||
|
|
||||||
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR) < FileName->Length)
|
if (FsvolDeviceExtension->VolumeParams.MaxComponentLength < FileName->Length)
|
||||||
return STATUS_OBJECT_NAME_INVALID;
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
|
||||||
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;
|
DirectoryMarker.Length = DirectoryMarker.MaximumLength = FileName->Length;
|
||||||
@ -2379,6 +2364,7 @@ VOID FspFileNodeOplockComplete(PVOID Context, PIRP Irp)
|
|||||||
FspIopCompleteIrp(Irp, Irp->IoStatus.Status);
|
FspIopCompleteIrp(Irp, Irp->IoStatus.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PCOMPLETE_LOCK_IRP_ROUTINE FspFileNodeCompleteLockIrp;
|
||||||
WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*";
|
WCHAR FspFileDescDirectoryPatternMatchAll[] = L"*";
|
||||||
|
|
||||||
// {904862B4-EB3F-461E-ACB2-4DF2B3FC898B}
|
// {904862B4-EB3F-461E-ACB2-4DF2B3FC898B}
|
||||||
|
@ -22,12 +22,14 @@ static NTSTATUS FspFsvolLockControlRetry(
|
|||||||
BOOLEAN CanWait);
|
BOOLEAN CanWait);
|
||||||
static NTSTATUS FspFsvolLockControl(
|
static NTSTATUS FspFsvolLockControl(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolLockControlComplete;
|
||||||
FSP_DRIVER_DISPATCH FspLockControl;
|
FSP_DRIVER_DISPATCH FspLockControl;
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspFsvolLockControlRetry)
|
#pragma alloc_text(PAGE, FspFsvolLockControlRetry)
|
||||||
#pragma alloc_text(PAGE, FspFsvolLockControl)
|
#pragma alloc_text(PAGE, FspFsvolLockControl)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolLockControlForward)
|
||||||
#pragma alloc_text(PAGE, FspFsvolLockControlComplete)
|
#pragma alloc_text(PAGE, FspFsvolLockControlComplete)
|
||||||
#pragma alloc_text(PAGE, FspLockControl)
|
#pragma alloc_text(PAGE, FspLockControl)
|
||||||
#endif
|
#endif
|
||||||
@ -94,6 +96,57 @@ static NTSTATUS FspFsvolLockControl(
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspFsvolLockControlForward(PVOID Context, PIRP Irp)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* At this point the FSRTL package has processed the lock IRP.
|
||||||
|
* Either complete the IRP or if we are supposed to forward to
|
||||||
|
* user mode do so now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
NTSTATUS Result = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result) || !FsvolDeviceExtension->VolumeParams.UserModeFileLocking)
|
||||||
|
goto complete;
|
||||||
|
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||||
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
|
ASSERT(FileNode == FileDesc->FileNode);
|
||||||
|
|
||||||
|
Result = FspIopCreateRequest(Irp, 0, 0, &Request);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto complete;
|
||||||
|
|
||||||
|
Request->Kind = FspFsctlTransactLockControlKind;
|
||||||
|
Request->Req.LockControl.UserContext = FileNode->UserContext;
|
||||||
|
Request->Req.LockControl.UserContext2 = FileDesc->UserContext2;
|
||||||
|
Request->Req.LockControl.LockFunction = IrpSp->MinorFunction;
|
||||||
|
Request->Req.LockControl.Offset = IrpSp->Parameters.LockControl.ByteOffset.QuadPart;
|
||||||
|
Request->Req.LockControl.Length = IrpSp->Parameters.LockControl.Length->QuadPart;
|
||||||
|
Request->Req.LockControl.Key = IrpSp->Parameters.LockControl.Key;
|
||||||
|
Request->Req.LockControl.ProcessId = IoGetRequestorProcessId(Irp);
|
||||||
|
Request->Req.LockControl.Exclusive = 0 != (IrpSp->Flags & SL_EXCLUSIVE_LOCK);
|
||||||
|
Request->Req.LockControl.FailImmediately = 0 != (IrpSp->Flags & SL_FAIL_IMMEDIATELY);
|
||||||
|
|
||||||
|
if (!FspIoqPostIrp(FsvolDeviceExtension->Ioq, Irp, &Result))
|
||||||
|
goto complete;
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
complete:
|
||||||
|
DEBUGLOGIRP(Irp, Result);
|
||||||
|
FspIopCompleteIrp(Irp, Result);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolLockControlComplete(
|
NTSTATUS FspFsvolLockControlComplete(
|
||||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
|
@ -228,7 +228,6 @@ static NTSTATUS FspFsvolReadNonCached(
|
|||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset;
|
LARGE_INTEGER ReadOffset = IrpSp->Parameters.Read.ByteOffset;
|
||||||
ULONG ReadLength = IrpSp->Parameters.Read.Length;
|
ULONG ReadLength = IrpSp->Parameters.Read.Length;
|
||||||
ULONG ReadKey = IrpSp->Parameters.Read.Key;
|
|
||||||
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
|
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
@ -321,7 +320,11 @@ static NTSTATUS FspFsvolReadNonCached(
|
|||||||
Request->Req.Read.UserContext2 = FileDesc->UserContext2;
|
Request->Req.Read.UserContext2 = FileDesc->UserContext2;
|
||||||
Request->Req.Read.Offset = ReadOffset.QuadPart;
|
Request->Req.Read.Offset = ReadOffset.QuadPart;
|
||||||
Request->Req.Read.Length = ReadLength;
|
Request->Req.Read.Length = ReadLength;
|
||||||
Request->Req.Read.Key = ReadKey;
|
if (!PagingIo)
|
||||||
|
{
|
||||||
|
Request->Req.Read.Key = IrpSp->Parameters.Read.Key;
|
||||||
|
Request->Req.Read.ProcessId = IoGetRequestorProcessId(Irp);
|
||||||
|
}
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
@ -289,7 +289,6 @@ static NTSTATUS FspFsvolWriteNonCached(
|
|||||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||||
LARGE_INTEGER WriteOffset = IrpSp->Parameters.Write.ByteOffset;
|
LARGE_INTEGER WriteOffset = IrpSp->Parameters.Write.ByteOffset;
|
||||||
ULONG WriteLength = IrpSp->Parameters.Write.Length;
|
ULONG WriteLength = IrpSp->Parameters.Write.Length;
|
||||||
ULONG WriteKey = IrpSp->Parameters.Write.Key;
|
|
||||||
BOOLEAN WriteToEndOfFile =
|
BOOLEAN WriteToEndOfFile =
|
||||||
FILE_WRITE_TO_END_OF_FILE == WriteOffset.LowPart && -1L == WriteOffset.HighPart;
|
FILE_WRITE_TO_END_OF_FILE == WriteOffset.LowPart && -1L == WriteOffset.HighPart;
|
||||||
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
|
BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO);
|
||||||
@ -390,8 +389,13 @@ static NTSTATUS FspFsvolWriteNonCached(
|
|||||||
Request->Req.Write.UserContext2 = FileDesc->UserContext2;
|
Request->Req.Write.UserContext2 = FileDesc->UserContext2;
|
||||||
Request->Req.Write.Offset = WriteOffset.QuadPart;
|
Request->Req.Write.Offset = WriteOffset.QuadPart;
|
||||||
Request->Req.Write.Length = WriteLength;
|
Request->Req.Write.Length = WriteLength;
|
||||||
Request->Req.Write.Key = WriteKey;
|
if (!PagingIo)
|
||||||
Request->Req.Write.ConstrainedIo = !!PagingIo;
|
{
|
||||||
|
Request->Req.Write.Key = IrpSp->Parameters.Write.Key;
|
||||||
|
Request->Req.Write.ProcessId = IoGetRequestorProcessId(Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Request->Req.Write.ConstrainedIo = TRUE;
|
||||||
|
|
||||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||||
FspIopRequestContext(Request, RequestIrp) = Irp;
|
FspIopRequestContext(Request, RequestIrp) = Irp;
|
||||||
|
@ -657,7 +657,7 @@ exit /b 0
|
|||||||
|
|
||||||
:sample-passthrough-dotnet
|
:sample-passthrough-dotnet
|
||||||
call :__run_sample_test passthrough-dotnet anycpu passthrough-dotnet winfsp-tests-x64 ^
|
call :__run_sample_test passthrough-dotnet anycpu passthrough-dotnet winfsp-tests-x64 ^
|
||||||
"-create_backup_test -create_restore_test -create_namelen_test -delete_access_test -querydir_namelen_test"
|
"-create_backup_test -create_restore_test -create_namelen_test -delete_access_test"
|
||||||
if !ERRORLEVEL! neq 0 goto fail
|
if !ERRORLEVEL! neq 0 goto fail
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
@ -725,7 +725,7 @@ L:
|
|||||||
"%ProjRoot%\build\VStudio\build\%Configuration%\%4.exe" ^
|
"%ProjRoot%\build\VStudio\build\%Configuration%\%4.exe" ^
|
||||||
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
|
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
|
||||||
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
|
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
|
||||||
-getfileinfo_name_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -querydir_namelen_test -exec_rename_dir_test ^
|
-getfileinfo_name_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -exec_rename_dir_test ^
|
||||||
-reparse* -stream*
|
-reparse* -stream*
|
||||||
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
|
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
|
||||||
popd
|
popd
|
||||||
@ -784,8 +784,8 @@ cd L: >nul 2>nul || (echo Unable to find drive L: >&2 & goto fail)
|
|||||||
L:
|
L:
|
||||||
"%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^
|
"%ProjRoot%\build\VStudio\build\%Configuration%\%3.exe" ^
|
||||||
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
|
--external --resilient --case-insensitive-cmp --share-prefix="\%1\%TMP::=$%\%1\test" ^
|
||||||
-create_fileattr_test -create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
|
-create_allocation_test -create_notraverse_test -create_backup_test -create_restore_test -create_namelen_test ^
|
||||||
-getfileinfo_name_test -setfileinfo_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -querydir_namelen_test -exec_rename_dir_test ^
|
-getfileinfo_name_test -setfileinfo_test -delete_access_test -delete_mmap_test -rename_flipflop_test -rename_mmap_test -setsecurity_test -exec_rename_dir_test ^
|
||||||
-reparse* -stream*
|
-reparse* -stream*
|
||||||
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
|
if !ERRORLEVEL! neq 0 set RunSampleTestExit=1
|
||||||
popd
|
popd
|
||||||
|
@ -375,7 +375,6 @@ namespace passthrough
|
|||||||
4096,
|
4096,
|
||||||
0,
|
0,
|
||||||
Security));
|
Security));
|
||||||
FileDesc.SetFileAttributes(FileAttributes | (UInt32)System.IO.FileAttributes.Archive);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -389,8 +388,8 @@ namespace passthrough
|
|||||||
}
|
}
|
||||||
FileDesc = new FileDesc(
|
FileDesc = new FileDesc(
|
||||||
Directory.CreateDirectory(FileName, Security));
|
Directory.CreateDirectory(FileName, Security));
|
||||||
FileDesc.SetFileAttributes(FileAttributes);
|
|
||||||
}
|
}
|
||||||
|
FileDesc.SetFileAttributes(FileAttributes);
|
||||||
FileNode = default(Object);
|
FileNode = default(Object);
|
||||||
FileDesc0 = FileDesc;
|
FileDesc0 = FileDesc;
|
||||||
NormalizedName = default(String);
|
NormalizedName = default(String);
|
||||||
@ -454,11 +453,9 @@ namespace passthrough
|
|||||||
{
|
{
|
||||||
FileDesc FileDesc = (FileDesc)FileDesc0;
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
if (ReplaceFileAttributes)
|
if (ReplaceFileAttributes)
|
||||||
FileDesc.SetFileAttributes(FileAttributes |
|
FileDesc.SetFileAttributes(FileAttributes);
|
||||||
(UInt32)System.IO.FileAttributes.Archive);
|
|
||||||
else if (0 != FileAttributes)
|
else if (0 != FileAttributes)
|
||||||
FileDesc.SetFileAttributes(FileDesc.GetFileAttributes() | FileAttributes |
|
FileDesc.SetFileAttributes(FileDesc.GetFileAttributes() | FileAttributes);
|
||||||
(UInt32)System.IO.FileAttributes.Archive);
|
|
||||||
FileDesc.Stream.SetLength(0);
|
FileDesc.Stream.SetLength(0);
|
||||||
return FileDesc.GetFileInfo(out FileInfo);
|
return FileDesc.GetFileInfo(out FileInfo);
|
||||||
}
|
}
|
||||||
@ -640,17 +637,11 @@ namespace passthrough
|
|||||||
FileDesc FileDesc = (FileDesc)FileDesc0;
|
FileDesc FileDesc = (FileDesc)FileDesc0;
|
||||||
if (null == FileDesc.FileSystemInfos)
|
if (null == FileDesc.FileSystemInfos)
|
||||||
{
|
{
|
||||||
if (null != Pattern)
|
IEnumerable Enum = FileDesc.DirInfo.EnumerateFileSystemInfos(
|
||||||
Pattern = Pattern.Replace('<', '*').Replace('>', '?').Replace('"', '.');
|
null != Pattern ? Pattern : "*");
|
||||||
else
|
|
||||||
Pattern = "*";
|
|
||||||
IEnumerable Enum = FileDesc.DirInfo.EnumerateFileSystemInfos(Pattern);
|
|
||||||
SortedList List = new SortedList();
|
SortedList List = new SortedList();
|
||||||
if (null != FileDesc.DirInfo && null != FileDesc.DirInfo.Parent)
|
List.Add(".", FileDesc.DirInfo);
|
||||||
{
|
List.Add("..", FileDesc.DirInfo.Parent);
|
||||||
List.Add(".", FileDesc.DirInfo);
|
|
||||||
List.Add("..", FileDesc.DirInfo.Parent);
|
|
||||||
}
|
|
||||||
foreach (FileSystemInfo Info in Enum)
|
foreach (FileSystemInfo Info in Enum)
|
||||||
List.Add(Info.Name, Info);
|
List.Add(Info.Name, Info);
|
||||||
FileDesc.FileSystemInfos = new DictionaryEntry[List.Count];
|
FileDesc.FileSystemInfos = new DictionaryEntry[List.Count];
|
||||||
|
@ -41,8 +41,8 @@
|
|||||||
#define fi_fh(fi, MASK) ((fi)->fh & (MASK))
|
#define fi_fh(fi, MASK) ((fi)->fh & (MASK))
|
||||||
#define fi_setfh(fi, FH, MASK) ((fi)->fh = (intptr_t)(FH) | (MASK))
|
#define fi_setfh(fi, FH, MASK) ((fi)->fh = (intptr_t)(FH) | (MASK))
|
||||||
#define fi_fd(fi) (fi_fh(fi, fi_dirbit) ? \
|
#define fi_fd(fi) (fi_fh(fi, fi_dirbit) ? \
|
||||||
dirfd((DIR *)(intptr_t)fi_fh(fi, ~fi_dirbit)) : (int)fi_fh(fi, ~fi_dirbit))
|
dirfd((DIR *)fi_fh(fi, ~fi_dirbit)) : (int)fi_fh(fi, ~fi_dirbit))
|
||||||
#define fi_dirp(fi) ((DIR *)(intptr_t)fi_fh(fi, ~fi_dirbit))
|
#define fi_dirp(fi) ((DIR *)fi_fh(fi, ~fi_dirbit))
|
||||||
#define fi_setfd(fi, fd) (fi_setfh(fi, fd, 0))
|
#define fi_setfd(fi, fd) (fi_setfh(fi, fd, 0))
|
||||||
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
|
#define fi_setdirp(fi, dirp) (fi_setfh(fi, dirp, fi_dirbit))
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ static int ptfs_utimens(const char *path, const struct fuse_timespec tv[2])
|
|||||||
{
|
{
|
||||||
ptfs_impl_fullpath(path);
|
ptfs_impl_fullpath(path);
|
||||||
|
|
||||||
return -1 != utimensat(AT_FDCWD, path, tv, AT_SYMLINK_NOFOLLOW) ? 0 : -errno;
|
return -1 != utimensat(AT_FDCWD, path, tv) ? 0 : -errno;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ int truncate(const char *path, fuse_off_t size)
|
|||||||
int utime(const char *path, const struct fuse_utimbuf *timbuf)
|
int utime(const char *path, const struct fuse_utimbuf *timbuf)
|
||||||
{
|
{
|
||||||
if (0 == timbuf)
|
if (0 == timbuf)
|
||||||
return utimensat(AT_FDCWD, path, 0, AT_SYMLINK_NOFOLLOW);
|
return utimensat(AT_FDCWD, path, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct fuse_timespec times[2];
|
struct fuse_timespec times[2];
|
||||||
@ -342,14 +342,13 @@ int utime(const char *path, const struct fuse_utimbuf *timbuf)
|
|||||||
times[0].tv_nsec = 0;
|
times[0].tv_nsec = 0;
|
||||||
times[1].tv_sec = timbuf->modtime;
|
times[1].tv_sec = timbuf->modtime;
|
||||||
times[1].tv_nsec = 0;
|
times[1].tv_nsec = 0;
|
||||||
return utimensat(AT_FDCWD, path, times, AT_SYMLINK_NOFOLLOW);
|
return utimensat(AT_FDCWD, path, times);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2], int flag)
|
int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2])
|
||||||
{
|
{
|
||||||
/* ignore dirfd and assume that it is always AT_FDCWD */
|
/* ignore dirfd and assume that it is always AT_FDCWD */
|
||||||
/* ignore flag and assume that it is always AT_SYMLINK_NOFOLLOW */
|
|
||||||
|
|
||||||
HANDLE h = CreateFileA(path,
|
HANDLE h = CreateFileA(path,
|
||||||
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
#define PATH_MAX 1024
|
#define PATH_MAX 1024
|
||||||
#define AT_FDCWD -2
|
#define AT_FDCWD -2
|
||||||
#define AT_SYMLINK_NOFOLLOW 2
|
|
||||||
|
|
||||||
typedef struct _DIR DIR;
|
typedef struct _DIR DIR;
|
||||||
struct dirent
|
struct dirent
|
||||||
@ -55,7 +54,7 @@ int lchown(const char *path, fuse_uid_t uid, fuse_gid_t gid);
|
|||||||
int lchflags(const char *path, uint32_t flags);
|
int lchflags(const char *path, uint32_t flags);
|
||||||
int truncate(const char *path, fuse_off_t size);
|
int truncate(const char *path, fuse_off_t size);
|
||||||
int utime(const char *path, const struct fuse_utimbuf *timbuf);
|
int utime(const char *path, const struct fuse_utimbuf *timbuf);
|
||||||
int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2], int flag);
|
int utimensat(int dirfd, const char *path, const struct fuse_timespec times[2]);
|
||||||
int setcrtime(const char *path, const struct fuse_timespec *tv);
|
int setcrtime(const char *path, const struct fuse_timespec *tv);
|
||||||
int unlink(const char *path);
|
int unlink(const char *path);
|
||||||
int rename(const char *oldpath, const char *newpath);
|
int rename(const char *oldpath, const char *newpath);
|
||||||
|
@ -39,11 +39,6 @@ void create_dotest(ULONG Flags, PWSTR Prefix)
|
|||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
||||||
CloseHandle(Handle);
|
CloseHandle(Handle);
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle);
|
|
||||||
ASSERT(ERROR_FILE_EXISTS == GetLastError());
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
Handle = CreateFileW(FilePath,
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
||||||
@ -232,122 +227,6 @@ void create_test(void)
|
|||||||
create_dotest(MemfsNet, L"\\\\memfs\\share");
|
create_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_fileattr_dotest(ULONG Flags, PWSTR Prefix)
|
|
||||||
{
|
|
||||||
void *memfs = memfs_start(Flags);
|
|
||||||
|
|
||||||
HANDLE Handle;
|
|
||||||
BOOLEAN Success;
|
|
||||||
DWORD FileAttributes;
|
|
||||||
WCHAR FilePath[MAX_PATH];
|
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT(FILE_ATTRIBUTE_ARCHIVE == FileAttributes);
|
|
||||||
Success = DeleteFileW(FilePath);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_READONLY, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
Success = DeleteFileW(FilePath);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_SYSTEM, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
Success = DeleteFileW(FilePath);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
Success = DeleteFileW(FilePath);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT(FILE_ATTRIBUTE_ARCHIVE == FileAttributes);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
CloseHandle(Handle);
|
|
||||||
|
|
||||||
FileAttributes = GetFileAttributesW(FilePath);
|
|
||||||
ASSERT((FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) == FileAttributes);
|
|
||||||
Success = SetFileAttributesW(FilePath, FILE_ATTRIBUTE_NORMAL);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
Success = DeleteFileW(FilePath);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
memfs_stop(memfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void create_fileattr_test(void)
|
|
||||||
{
|
|
||||||
if (NtfsTests)
|
|
||||||
{
|
|
||||||
WCHAR DirBuf[MAX_PATH];
|
|
||||||
GetTestDirectory(DirBuf);
|
|
||||||
create_fileattr_dotest(-1, DirBuf);
|
|
||||||
}
|
|
||||||
if (WinFspDiskTests)
|
|
||||||
create_fileattr_dotest(MemfsDisk, 0);
|
|
||||||
if (WinFspNetTests)
|
|
||||||
create_fileattr_dotest(MemfsNet, L"\\\\memfs\\share");
|
|
||||||
}
|
|
||||||
|
|
||||||
void create_related_dotest(ULONG Flags, PWSTR Prefix)
|
void create_related_dotest(ULONG Flags, PWSTR Prefix)
|
||||||
{
|
{
|
||||||
void *memfs = memfs_start(Flags);
|
void *memfs = memfs_start(Flags);
|
||||||
@ -1257,7 +1136,6 @@ void create_pid_test(void)
|
|||||||
void create_tests(void)
|
void create_tests(void)
|
||||||
{
|
{
|
||||||
TEST(create_test);
|
TEST(create_test);
|
||||||
TEST(create_fileattr_test);
|
|
||||||
TEST(create_related_test);
|
TEST(create_related_test);
|
||||||
TEST(create_allocation_test);
|
TEST(create_allocation_test);
|
||||||
TEST(create_sd_test);
|
TEST(create_sd_test);
|
||||||
|
@ -416,98 +416,6 @@ void querydir_buffer_overflow_test(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID querydir_namelen_exists(PWSTR FilePath)
|
|
||||||
{
|
|
||||||
HANDLE Handle;
|
|
||||||
WIN32_FIND_DATAW FindData;
|
|
||||||
|
|
||||||
Handle = FindFirstFileW(FilePath, &FindData);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
FindClose(Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void querydir_namelen_dotest(ULONG Flags, PWSTR Prefix, PWSTR Drive)
|
|
||||||
{
|
|
||||||
/* based on create_namelen_dotest */
|
|
||||||
|
|
||||||
void *memfs = memfs_start(Flags);
|
|
||||||
|
|
||||||
WCHAR FilePath[1024];
|
|
||||||
PWSTR FilePathBgn, P, EndP;
|
|
||||||
DWORD MaxComponentLength;
|
|
||||||
HANDLE Handle;
|
|
||||||
BOOL Success;
|
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Drive ? Drive : memfs_volumename(memfs));
|
|
||||||
|
|
||||||
Success = GetVolumeInformationW(FilePath,
|
|
||||||
0, 0,
|
|
||||||
0, &MaxComponentLength, 0,
|
|
||||||
0, 0);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
|
||||||
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
|
||||||
FilePathBgn = FilePath + wcslen(FilePath);
|
|
||||||
|
|
||||||
for (P = FilePathBgn, EndP = P + MaxComponentLength - 1; EndP > P; P++)
|
|
||||||
*P = (P - FilePathBgn) % 10 + '0';
|
|
||||||
*P = L'\0';
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
|
||||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
querydir_namelen_exists(FilePath);
|
|
||||||
Success = CloseHandle(Handle);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
for (P = FilePathBgn, EndP = P + MaxComponentLength; EndP > P; P++)
|
|
||||||
*P = (P - FilePathBgn) % 10 + '0';
|
|
||||||
*P = L'\0';
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
|
||||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE != Handle);
|
|
||||||
querydir_namelen_exists(FilePath);
|
|
||||||
Success = CloseHandle(Handle);
|
|
||||||
ASSERT(Success);
|
|
||||||
|
|
||||||
for (P = FilePathBgn, EndP = P + MaxComponentLength + 1; EndP > P; P++)
|
|
||||||
*P = (P - FilePathBgn) % 10 + '0';
|
|
||||||
*P = L'\0';
|
|
||||||
|
|
||||||
Handle = CreateFileW(FilePath,
|
|
||||||
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
|
|
||||||
CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
|
|
||||||
ASSERT(INVALID_HANDLE_VALUE == Handle);
|
|
||||||
ASSERT(ERROR_INVALID_NAME == GetLastError());
|
|
||||||
|
|
||||||
memfs_stop(memfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void querydir_namelen_test(void)
|
|
||||||
{
|
|
||||||
if (OptShareName || OptMountPoint)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (NtfsTests)
|
|
||||||
{
|
|
||||||
WCHAR DirBuf[MAX_PATH], DriveBuf[3];
|
|
||||||
GetTestDirectoryAndDrive(DirBuf, DriveBuf);
|
|
||||||
querydir_namelen_dotest(-1, DirBuf, DriveBuf);
|
|
||||||
}
|
|
||||||
if (WinFspDiskTests)
|
|
||||||
querydir_namelen_dotest(MemfsDisk, 0, 0);
|
|
||||||
#if 0
|
|
||||||
/* This test does not work when going through the MUP! */
|
|
||||||
if (WinFspNetTests)
|
|
||||||
querydir_namelen_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned __stdcall dirnotify_dotest_thread(void *FilePath)
|
static unsigned __stdcall dirnotify_dotest_thread(void *FilePath)
|
||||||
{
|
{
|
||||||
FspDebugLog(__FUNCTION__ ": \"%S\"\n", FilePath);
|
FspDebugLog(__FUNCTION__ ": \"%S\"\n", FilePath);
|
||||||
@ -644,7 +552,5 @@ void dirctl_tests(void)
|
|||||||
TEST(querydir_expire_cache_test);
|
TEST(querydir_expire_cache_test);
|
||||||
if (!OptShareName)
|
if (!OptShareName)
|
||||||
TEST(querydir_buffer_overflow_test);
|
TEST(querydir_buffer_overflow_test);
|
||||||
if (!OptShareName && !OptMountPoint)
|
|
||||||
TEST(querydir_namelen_test);
|
|
||||||
TEST(dirnotify_test);
|
TEST(dirnotify_test);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user