mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
1632 lines
70 KiB
C#
1632 lines
70 KiB
C#
/*
|
|
* dotnet/Interop.cs
|
|
*
|
|
* Copyright 2015-2024 Bill Zissimopoulos
|
|
*/
|
|
/*
|
|
* This file is part of WinFsp.
|
|
*
|
|
* You can redistribute it and/or modify it under the terms of the GNU
|
|
* General Public License version 3 as published by the Free Software
|
|
* Foundation.
|
|
*
|
|
* Licensees holding a valid commercial license may use this software
|
|
* in accordance with the commercial license agreement provided in
|
|
* conjunction with the software. The terms and conditions of any such
|
|
* commercial license agreement shall govern, supersede, and render
|
|
* ineffective any application of the GPLv3 license to this software,
|
|
* notwithstanding of any reference thereto in the software or
|
|
* associated repository.
|
|
*/
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security;
|
|
using System.Security.AccessControl;
|
|
|
|
namespace Fsp.Interop
|
|
{
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct VolumeParams
|
|
{
|
|
internal const UInt32 CaseSensitiveSearch = 0x00000001;
|
|
internal const UInt32 CasePreservedNames = 0x00000002;
|
|
internal const UInt32 UnicodeOnDisk = 0x00000004;
|
|
internal const UInt32 PersistentAcls = 0x00000008;
|
|
internal const UInt32 ReparsePoints = 0x00000010;
|
|
internal const UInt32 ReparsePointsAccessCheck = 0x00000020;
|
|
internal const UInt32 NamedStreams = 0x00000040;
|
|
internal const UInt32 HardLinks = 0x00000080;
|
|
internal const UInt32 ExtendedAttributes = 0x00000100;
|
|
internal const UInt32 ReadOnlyVolume = 0x00000200;
|
|
internal const UInt32 PostCleanupWhenModifiedOnly = 0x00000400;
|
|
internal const UInt32 PassQueryDirectoryPattern = 0x00000800;
|
|
internal const UInt32 AlwaysUseDoubleBuffering = 0x00001000;
|
|
internal const UInt32 PassQueryDirectoryFileName = 0x00002000;
|
|
internal const UInt32 FlushAndPurgeOnCleanup = 0x00004000;
|
|
internal const UInt32 DeviceControl = 0x00008000;
|
|
internal const UInt32 UmFileContextIsUserContext2 = 0x00010000;
|
|
internal const UInt32 UmFileContextIsFullContext = 0x00020000;
|
|
internal const UInt32 AllowOpenInKernelMode = 0x01000000;
|
|
internal const UInt32 CasePreservedExtendedAttributes = 0x02000000;
|
|
internal const UInt32 WslFeatures = 0x04000000;
|
|
internal const UInt32 RejectIrpPriorToTransact0 = 0x10000000;
|
|
internal const UInt32 SupportsPosixUnlinkRename = 0x20000000;
|
|
internal const UInt32 PostDispositionWhenNecessaryOnly = 0x40000000;
|
|
internal const int PrefixSize = 192;
|
|
internal const int FileSystemNameSize = 16;
|
|
|
|
internal const UInt32 VolumeInfoTimeoutValid = 0x00000001;
|
|
internal const UInt32 DirInfoTimeoutValid = 0x00000002;
|
|
internal const UInt32 SecurityTimeoutValid = 0x00000004;
|
|
internal const UInt32 StreamInfoTimeoutValid = 0x00000008;
|
|
internal const UInt32 EaTimeoutValid = 0x00000010;
|
|
|
|
internal UInt16 Version;
|
|
internal UInt16 SectorSize;
|
|
internal UInt16 SectorsPerAllocationUnit;
|
|
internal UInt16 MaxComponentLength;
|
|
internal UInt64 VolumeCreationTime;
|
|
internal UInt32 VolumeSerialNumber;
|
|
internal UInt32 TransactTimeout;
|
|
internal UInt32 IrpTimeout;
|
|
internal UInt32 IrpCapacity;
|
|
internal UInt32 FileInfoTimeout;
|
|
internal UInt32 Flags;
|
|
internal unsafe fixed UInt16 Prefix[PrefixSize];
|
|
internal unsafe fixed UInt16 FileSystemName[FileSystemNameSize];
|
|
internal UInt32 AdditionalFlags;
|
|
internal UInt32 VolumeInfoTimeout;
|
|
internal UInt32 DirInfoTimeout;
|
|
internal UInt32 SecurityTimeout;
|
|
internal UInt32 StreamInfoTimeout;
|
|
internal UInt32 EaTimeout;
|
|
internal UInt32 FsextControlCode;
|
|
internal unsafe fixed UInt32 Reserved32[1];
|
|
internal unsafe fixed UInt64 Reserved64[2];
|
|
|
|
internal unsafe String GetPrefix()
|
|
{
|
|
fixed (UInt16 *P = Prefix)
|
|
return Marshal.PtrToStringUni((IntPtr)P);
|
|
}
|
|
internal unsafe void SetPrefix(String Value)
|
|
{
|
|
fixed (UInt16 *P = Prefix)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > PrefixSize - 1)
|
|
Size = PrefixSize - 1;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
P[Size] = 0;
|
|
}
|
|
}
|
|
internal unsafe String GetFileSystemName()
|
|
{
|
|
fixed (UInt16 *P = FileSystemName)
|
|
return Marshal.PtrToStringUni((IntPtr)P);
|
|
}
|
|
internal unsafe void SetFileSystemName(String Value)
|
|
{
|
|
fixed (UInt16 *P = FileSystemName)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > FileSystemNameSize - 1)
|
|
Size = FileSystemNameSize - 1;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
P[Size] = 0;
|
|
}
|
|
}
|
|
internal unsafe Boolean IsPrefixEmpty()
|
|
{
|
|
fixed (UInt16 *P = Prefix)
|
|
return 0 == *P;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contains volume information about a file system.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct VolumeInfo
|
|
{
|
|
internal const int VolumeLabelSize = 32;
|
|
|
|
/// <summary>
|
|
/// Total size of volume in bytes.
|
|
/// </summary>
|
|
public UInt64 TotalSize;
|
|
/// <summary>
|
|
/// Free size of volume in bytes.
|
|
/// </summary>
|
|
public UInt64 FreeSize;
|
|
internal UInt16 VolumeLabelLength;
|
|
internal unsafe fixed UInt16 VolumeLabel[VolumeLabelSize];
|
|
|
|
/// <summary>
|
|
/// Sets the volume label.
|
|
/// </summary>
|
|
public unsafe void SetVolumeLabel(String Value)
|
|
{
|
|
fixed (UInt16 *P = VolumeLabel)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > VolumeLabelSize)
|
|
Size = VolumeLabelSize;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
VolumeLabelLength = (UInt16)(Size * 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contains metadata information about a file or directory.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct FileInfo
|
|
{
|
|
/// <summary>
|
|
/// The file or directory attributes.
|
|
/// </summary>
|
|
public UInt32 FileAttributes;
|
|
/// <summary>
|
|
/// The reparse tag of the file or directory.
|
|
/// This value is 0 if the file or directory is not a reparse point.
|
|
/// </summary>
|
|
public UInt32 ReparseTag;
|
|
/// <summary>
|
|
/// The allocation size of the file.
|
|
/// </summary>
|
|
public UInt64 AllocationSize;
|
|
/// <summary>
|
|
/// The file size of the file (end of file).
|
|
/// </summary>
|
|
public UInt64 FileSize;
|
|
/// <summary>
|
|
/// The time that the file or directory was created.
|
|
/// </summary>
|
|
public UInt64 CreationTime;
|
|
/// <summary>
|
|
/// The time that the file or directory was last accessed.
|
|
/// </summary>
|
|
public UInt64 LastAccessTime;
|
|
/// <summary>
|
|
/// The time that the file or direcotry was last modified.
|
|
/// </summary>
|
|
public UInt64 LastWriteTime;
|
|
/// <summary>
|
|
/// The time that the file or directory metadata was last modified.
|
|
/// </summary>
|
|
public UInt64 ChangeTime;
|
|
/// <summary>
|
|
/// A unique identifier that is associated with the file or directory.
|
|
/// Not all file systems support this value.
|
|
/// </summary>
|
|
public UInt64 IndexNumber;
|
|
/// <summary>
|
|
/// The number of hard links.
|
|
/// Not currently implemented. Set to 0.
|
|
/// </summary>
|
|
public UInt32 HardLinks;
|
|
|
|
/// <summary>
|
|
/// The extended attribute size of the file.
|
|
/// </summary>
|
|
public UInt32 EaSize
|
|
{
|
|
get { return GetEaSize(); }
|
|
set { SetEaSize(value); }
|
|
}
|
|
|
|
internal static int EaSizeOffset =
|
|
(int)Marshal.OffsetOf(typeof(FileInfo), "HardLinks") + 4;
|
|
internal unsafe UInt32 GetEaSize()
|
|
{
|
|
fixed (FileInfo *P = &this)
|
|
return *(UInt32 *)((Int64)(IntPtr)P + EaSizeOffset);
|
|
}
|
|
internal unsafe void SetEaSize(UInt32 value)
|
|
{
|
|
fixed (FileInfo *P = &this)
|
|
*(UInt32 *)((Int64)(IntPtr)P + EaSizeOffset) = value;
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct OpenFileInfo
|
|
{
|
|
internal FileInfo FileInfo;
|
|
internal IntPtr NormalizedName;
|
|
internal UInt16 NormalizedNameSize;
|
|
|
|
internal unsafe void SetNormalizedName(String Value)
|
|
{
|
|
UInt16 *P = (UInt16 *)NormalizedName;
|
|
int Size = Value.Length;
|
|
if (Size > NormalizedNameSize)
|
|
Size = NormalizedNameSize;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
NormalizedNameSize = (UInt16)(Size * 2);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct DirInfo
|
|
{
|
|
internal const int FileNameBufSize = 255;
|
|
internal static int FileNameBufOffset =
|
|
(int)Marshal.OffsetOf(typeof(DirInfo), "FileNameBuf");
|
|
|
|
internal UInt16 Size;
|
|
internal FileInfo FileInfo;
|
|
internal unsafe fixed Byte Padding[24];
|
|
//internal unsafe fixed UInt16 FileNameBuf[];
|
|
internal unsafe fixed UInt16 FileNameBuf[FileNameBufSize];
|
|
|
|
internal unsafe void SetFileNameBuf(String Value)
|
|
{
|
|
fixed (UInt16 *P = FileNameBuf)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > FileNameBufSize)
|
|
Size = FileNameBufSize;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
this.Size = (UInt16)(FileNameBufOffset + Size * 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct StreamInfo
|
|
{
|
|
internal const int StreamNameBufSize = 255;
|
|
internal static int StreamNameBufOffset =
|
|
(int)Marshal.OffsetOf(typeof(StreamInfo), "StreamNameBuf");
|
|
|
|
internal UInt16 Size;
|
|
internal UInt64 StreamSize;
|
|
internal UInt64 StreamAllocationSize;
|
|
//internal unsafe fixed UInt16 StreamNameBuf[];
|
|
internal unsafe fixed UInt16 StreamNameBuf[StreamNameBufSize];
|
|
|
|
internal unsafe void SetStreamNameBuf(String Value)
|
|
{
|
|
fixed (UInt16 *P = StreamNameBuf)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > StreamNameBufSize)
|
|
Size = StreamNameBufSize;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
this.Size = (UInt16)(StreamNameBufOffset + Size * 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct NotifyInfoInternal
|
|
{
|
|
internal const int FileNameBufSize = 1024 * 2/*FSP_FSCTL_TRANSACT_PATH_SIZEMAX*/;
|
|
internal static int FileNameBufOffset =
|
|
(int)Marshal.OffsetOf(typeof(NotifyInfoInternal), "FileNameBuf");
|
|
|
|
internal UInt16 Size;
|
|
internal UInt32 Filter;
|
|
internal UInt32 Action;
|
|
//internal unsafe fixed UInt16 FileNameBuf[];
|
|
internal unsafe fixed UInt16 FileNameBuf[FileNameBufSize];
|
|
|
|
internal unsafe void SetFileNameBuf(String Value)
|
|
{
|
|
fixed (UInt16 *P = FileNameBuf)
|
|
{
|
|
int Size = null != Value ? Value.Length : 0;
|
|
if (Size > FileNameBufSize)
|
|
Size = FileNameBufSize;
|
|
for (int I = 0; Size > I; I++)
|
|
P[I] = Value[I];
|
|
this.Size = (UInt16)(FileNameBufOffset + Size * 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enumeration of all the possible values for NotifyInfo.Action
|
|
/// </summary>
|
|
public enum NotifyAction : UInt32
|
|
{
|
|
Added = 1,
|
|
Removed = 2,
|
|
Modified = 3,
|
|
RenamedOldName = 4,
|
|
RenamedNewName = 5,
|
|
AddedStream = 6,
|
|
RemovedStream = 7,
|
|
ModifiedStream = 8,
|
|
RemovedByDelete = 9,
|
|
IdNotTunnelled = 10,
|
|
TunnelledIdCollision = 11,
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Enumeration of all the possible values for NotifyInfo.Filter
|
|
/// </summary>
|
|
[Flags]
|
|
public enum NotifyFilter : UInt32
|
|
{
|
|
None = 0x00000,
|
|
ChangeFileName = 0x00001,
|
|
ChangeDirName = 0x00002,
|
|
ChangeName = ChangeFileName | ChangeDirName,
|
|
ChangeAttributes = 0x00004,
|
|
ChangeSize = 0x00008,
|
|
ChangeLastWrite = 0x00010,
|
|
ChangeLastAccess = 0x00020,
|
|
ChangeCreation = 0x00040,
|
|
ChangeEa = 0x00080,
|
|
ChangeSecurity = 0x00100,
|
|
ChangeStreamName = 0x00200,
|
|
ChangeStreamSize = 0x00400,
|
|
ChangeStreamWrite = 0x00800,
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contains file change notification information.
|
|
/// </summary>
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NotifyInfo
|
|
{
|
|
public String FileName;
|
|
public NotifyAction Action;
|
|
public NotifyFilter Filter;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct FullEaInformation
|
|
{
|
|
internal const int EaNameSize = 15 * 1024;
|
|
/* Set this to a value smaller than 16384 with sufficient space for additional data.
|
|
* This should really be:
|
|
* FSP_FSCTL_TRANSACT_RSP_BUFFER_SIZEMAX - FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName)
|
|
*/
|
|
|
|
internal UInt32 NextEntryOffset;
|
|
internal Byte Flags;
|
|
internal Byte EaNameLength;
|
|
internal UInt16 EaValueLength;
|
|
internal unsafe fixed Byte EaName[EaNameSize];
|
|
|
|
internal unsafe void Set(String Name, Byte[] Value, Boolean NeedEa)
|
|
{
|
|
int NameLength = 254 < Name.Length ? 254 : Name.Length;
|
|
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
|
|
EaNameSize - Name.Length - 1 : Value.Length;
|
|
|
|
NextEntryOffset = 0;
|
|
Flags = NeedEa ? (Byte)0x80/*FILE_NEED_EA*/ : (Byte)0;
|
|
EaNameLength = (Byte)NameLength;
|
|
EaValueLength = (UInt16)ValueLength;
|
|
|
|
fixed (Byte *P = EaName)
|
|
{
|
|
int I = 0, J = 0;
|
|
for (; NameLength > I; I++)
|
|
P[I] = (Byte)Name[I];
|
|
P[I++] = 0;
|
|
for (; ValueLength > J; J++)
|
|
P[I + J] = Value[J];
|
|
}
|
|
}
|
|
internal static UInt32 PackedSize(String Name, Byte[] Value, Boolean NeedEa)
|
|
{
|
|
int NameLength = 254 < Name.Length ? 254 : Name.Length;
|
|
int ValueLength = EaNameSize - Name.Length - 1 < Value.Length ?
|
|
EaNameSize - Name.Length - 1 : Value.Length;
|
|
|
|
/* magic computations are courtesy of NTFS */
|
|
return (UInt32)(5 + NameLength + ValueLength);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct FullContext
|
|
{
|
|
internal UInt64 UserContext;
|
|
internal UInt64 UserContext2;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct IoStatusBlock
|
|
{
|
|
public IntPtr Status;
|
|
public IntPtr Information;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct IoStatus
|
|
{
|
|
internal UInt32 Information;
|
|
internal UInt32 Status;
|
|
}
|
|
|
|
internal enum FspFsctlTransact
|
|
{
|
|
ReadKind = 5,
|
|
WriteKind = 6,
|
|
QueryDirectoryKind = 14
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
internal struct FspFsctlTransactReq
|
|
{
|
|
[FieldOffset(0)]
|
|
internal UInt16 Version;
|
|
[FieldOffset(2)]
|
|
internal UInt16 Size;
|
|
[FieldOffset(4)]
|
|
internal UInt32 Kind;
|
|
[FieldOffset(8)]
|
|
internal UInt64 Hint;
|
|
|
|
[FieldOffset(0)]
|
|
internal unsafe fixed Byte Padding[88];
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
internal struct FspFsctlTransactRsp
|
|
{
|
|
[FieldOffset(0)]
|
|
internal UInt16 Version;
|
|
[FieldOffset(2)]
|
|
internal UInt16 Size;
|
|
[FieldOffset(4)]
|
|
internal UInt32 Kind;
|
|
[FieldOffset(8)]
|
|
internal UInt64 Hint;
|
|
|
|
[FieldOffset(16)]
|
|
internal IoStatus IoStatus;
|
|
|
|
[FieldOffset(24)]
|
|
internal FileInfo WriteFileInfo;
|
|
|
|
[FieldOffset(0)]
|
|
internal unsafe fixed Byte Padding[128];
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal unsafe struct FspFileSystemOperationContext
|
|
{
|
|
internal FspFsctlTransactReq *Request;
|
|
internal FspFsctlTransactRsp *Response;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
internal struct FileSystemInterface
|
|
{
|
|
internal struct Proto
|
|
{
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetVolumeInfo(
|
|
IntPtr FileSystem,
|
|
out VolumeInfo VolumeInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetVolumeLabel(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String VolumeLabel,
|
|
out VolumeInfo VolumeInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetSecurityByName(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
IntPtr PFileAttributes/* or ReparsePointIndex */,
|
|
IntPtr SecurityDescriptor,
|
|
IntPtr PSecurityDescriptorSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Create(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 CreateOptions,
|
|
UInt32 GrantedAccess,
|
|
UInt32 FileAttributes,
|
|
IntPtr SecurityDescriptor,
|
|
UInt64 AllocationSize,
|
|
ref FullContext FullContext,
|
|
ref OpenFileInfo OpenFileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Open(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 CreateOptions,
|
|
UInt32 GrantedAccess,
|
|
ref FullContext FullContext,
|
|
ref OpenFileInfo OpenFileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Overwrite(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt32 FileAttributes,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ReplaceFileAttributes,
|
|
UInt64 AllocationSize,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void Cleanup(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 Flags);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void Close(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Read(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr Buffer,
|
|
UInt64 Offset,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Write(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr Buffer,
|
|
UInt64 Offset,
|
|
UInt32 Length,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean WriteToEndOfFile,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ConstrainedIo,
|
|
out UInt32 PBytesTransferred,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Flush(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetFileInfo(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetBasicInfo(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt32 FileAttributes,
|
|
UInt64 CreationTime,
|
|
UInt64 LastAccessTime,
|
|
UInt64 LastWriteTime,
|
|
UInt64 ChangeTime,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetFileSize(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt64 NewSize,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean SetAllocationSize,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 CanDelete(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Rename(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String NewFileName,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ReplaceIfExists);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetSecurity(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr SecurityDescriptor,
|
|
IntPtr PSecurityDescriptorSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetSecurity(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt32 SecurityInformation,
|
|
IntPtr ModificationDescriptor);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 ReadDirectory(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String Pattern,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String Marker,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 ResolveReparsePoints(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 ReparsePointIndex,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent,
|
|
out IoStatusBlock PIoStatus,
|
|
IntPtr Buffer,
|
|
IntPtr PSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetReparsePoint(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
IntPtr Buffer,
|
|
IntPtr PSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetReparsePoint(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
IntPtr Buffer,
|
|
UIntPtr Size);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 DeleteReparsePoint(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
IntPtr Buffer,
|
|
UIntPtr Size);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetStreamInfo(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetDirInfoByName(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
out DirInfo DirInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Control(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt32 ControlCode,
|
|
IntPtr InputBuffer, UInt32 InputBufferLength,
|
|
IntPtr OutputBuffer, UInt32 OutputBufferLength,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetDelete(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean DeleteFile);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 CreateEx(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 CreateOptions,
|
|
UInt32 GrantedAccess,
|
|
UInt32 FileAttributes,
|
|
IntPtr SecurityDescriptor,
|
|
UInt64 AllocationSize,
|
|
IntPtr ExtraBuffer,
|
|
UInt32 ExtraLength,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ExtraBufferIsReparsePoint,
|
|
ref FullContext FullContext,
|
|
ref OpenFileInfo OpenFileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 OverwriteEx(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
UInt32 FileAttributes,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ReplaceFileAttributes,
|
|
UInt64 AllocationSize,
|
|
IntPtr Ea,
|
|
UInt32 EaLength,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetEa(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr Ea,
|
|
UInt32 EaLength,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 SetEa(
|
|
IntPtr FileSystem,
|
|
ref FullContext FullContext,
|
|
IntPtr Ea,
|
|
UInt32 EaLength,
|
|
out FileInfo FileInfo);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 Obsolete0();
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void DispatcherStopped(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
|
|
}
|
|
|
|
internal static int Size = IntPtr.Size * 64;
|
|
|
|
internal Proto.GetVolumeInfo GetVolumeInfo;
|
|
internal Proto.SetVolumeLabel SetVolumeLabel;
|
|
internal Proto.GetSecurityByName GetSecurityByName;
|
|
internal Proto.Create Create;
|
|
internal Proto.Open Open;
|
|
internal Proto.Overwrite Overwrite;
|
|
internal Proto.Cleanup Cleanup;
|
|
internal Proto.Close Close;
|
|
internal Proto.Read Read;
|
|
internal Proto.Write Write;
|
|
internal Proto.Flush Flush;
|
|
internal Proto.GetFileInfo GetFileInfo;
|
|
internal Proto.SetBasicInfo SetBasicInfo;
|
|
internal Proto.SetFileSize SetFileSize;
|
|
internal Proto.CanDelete CanDelete;
|
|
internal Proto.Rename Rename;
|
|
internal Proto.GetSecurity GetSecurity;
|
|
internal Proto.SetSecurity SetSecurity;
|
|
internal Proto.ReadDirectory ReadDirectory;
|
|
internal Proto.ResolveReparsePoints ResolveReparsePoints;
|
|
internal Proto.GetReparsePoint GetReparsePoint;
|
|
internal Proto.SetReparsePoint SetReparsePoint;
|
|
internal Proto.DeleteReparsePoint DeleteReparsePoint;
|
|
internal Proto.GetStreamInfo GetStreamInfo;
|
|
internal Proto.GetDirInfoByName GetDirInfoByName;
|
|
internal Proto.Control Control;
|
|
internal Proto.SetDelete SetDelete;
|
|
internal Proto.CreateEx CreateEx;
|
|
internal Proto.OverwriteEx OverwriteEx;
|
|
internal Proto.GetEa GetEa;
|
|
internal Proto.SetEa SetEa;
|
|
internal Proto.Obsolete0 Obsolete0;
|
|
internal Proto.DispatcherStopped DispatcherStopped;
|
|
/* NTSTATUS (*Reserved[33])(); */
|
|
}
|
|
|
|
[SuppressUnmanagedCodeSecurity]
|
|
internal static class Api
|
|
{
|
|
internal struct Proto
|
|
{
|
|
/* FileSystem */
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemPreflight(
|
|
[MarshalAs(UnmanagedType.LPWStr)] String DevicePath,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String MountPoint);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemCreate(
|
|
[MarshalAs(UnmanagedType.LPWStr)] String DevicePath,
|
|
ref VolumeParams VolumeParams,
|
|
IntPtr Interface,
|
|
out IntPtr PFileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemDelete(
|
|
IntPtr FileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemSetMountPoint(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String MountPoint);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemSetMountPointEx(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String MountPoint,
|
|
IntPtr SecurityDescriptor);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemRemoveMountPoint(
|
|
IntPtr FileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemStartDispatcher(
|
|
IntPtr FileSystem,
|
|
UInt32 ThreadCount);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemStopDispatcher(
|
|
IntPtr FileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemSendResponse(
|
|
IntPtr FileSystem,
|
|
ref FspFsctlTransactRsp Response);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemNotifyBegin(
|
|
IntPtr FileSystem,
|
|
UInt32 Timeout);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemNotifyEnd(
|
|
IntPtr FileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemNotify(
|
|
IntPtr FileSystem,
|
|
IntPtr NotifyInfo,
|
|
UIntPtr Size);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal unsafe delegate FspFileSystemOperationContext *FspFileSystemGetOperationContext();
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate IntPtr FspFileSystemMountPointF(
|
|
IntPtr FileSystem);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemSetOperationGuardStrategyF(
|
|
IntPtr FileSystem,
|
|
Int32 GuardStrategy);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemSetDebugLogF(
|
|
IntPtr FileSystem,
|
|
UInt32 DebugLog);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate UInt32 FspFileSystemOperationProcessIdF();
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemAddDirInfo(
|
|
IntPtr DirInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemFindReparsePoint(
|
|
IntPtr FileSystem,
|
|
GetReparsePointByName GetReparsePointByName,
|
|
IntPtr Context,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
out UInt32 PReparsePointIndex);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemResolveReparsePoints(
|
|
IntPtr FileSystem,
|
|
GetReparsePointByName GetReparsePointByName,
|
|
IntPtr Context,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
UInt32 ReparsePointIndex,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean ResolveLastPathComponent,
|
|
out IoStatusBlock PIoStatus,
|
|
IntPtr Buffer,
|
|
IntPtr PSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspFileSystemCanReplaceReparsePoint(
|
|
IntPtr CurrentReparseData,
|
|
UIntPtr CurrentReparseDataSize,
|
|
IntPtr ReplaceReparseData,
|
|
UIntPtr ReplaceReparseDataSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemAddStreamInfo(
|
|
IntPtr StreamInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemAddEa(
|
|
IntPtr SingleEa,
|
|
IntPtr Ea,
|
|
UInt32 EaLength,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemAddNotifyInfo(
|
|
IntPtr NotifyInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemStopServiceIfNecessary(
|
|
IntPtr FileSystem,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean Normally);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
|
|
ref IntPtr PDirBuffer,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean Reset,
|
|
out Int32 PResult);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
internal delegate Boolean FspFileSystemFillDirectoryBuffer(
|
|
ref IntPtr PDirBuffer,
|
|
ref DirInfo DirInfo,
|
|
out Int32 PResult);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemReleaseDirectoryBuffer(
|
|
ref IntPtr PDirBuffer);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemReadDirectoryBuffer(
|
|
ref IntPtr PDirBuffer,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String Marker,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspFileSystemDeleteDirectoryBuffer(
|
|
ref IntPtr PDirBuffer);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspSetSecurityDescriptor(
|
|
IntPtr InputDescriptor,
|
|
UInt32 SecurityInformation,
|
|
IntPtr ModificationDescriptor,
|
|
out IntPtr PSecurityDescriptor);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspDeleteSecurityDescriptor(
|
|
IntPtr SecurityDescriptor,
|
|
IntPtr CreateFunc);
|
|
|
|
/* Service */
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspServiceCreate(
|
|
[MarshalAs(UnmanagedType.LPWStr)] String ServiceName,
|
|
ServiceStart OnStart,
|
|
ServiceStop OnStop,
|
|
ServiceControl OnControl,
|
|
out IntPtr PService);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceDelete(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceAllowConsoleMode(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceRequestTime(
|
|
IntPtr Service,
|
|
UInt32 Time);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceSetExitCode(
|
|
IntPtr Service,
|
|
UInt32 ExitCode);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate UInt32 FspServiceGetExitCode(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspServiceLoop(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceStop(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspServiceLog(
|
|
UInt32 Type,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String Format,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String Message);
|
|
|
|
/* utility */
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspVersion(
|
|
out UInt32 PVersion);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 FspNtStatusFromWin32(
|
|
UInt32 Error);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate UInt32 FspWin32FromNtStatus(
|
|
Int32 Status);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspDebugLog(
|
|
[MarshalAs(UnmanagedType.LPStr)] String Format,
|
|
[MarshalAs(UnmanagedType.LPStr)] String Message);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate void FspDebugLogSetHandle(
|
|
IntPtr Handle);
|
|
|
|
/* callbacks */
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 GetReparsePointByName(
|
|
IntPtr FileSystem,
|
|
IntPtr Context,
|
|
[MarshalAs(UnmanagedType.LPWStr)] String FileName,
|
|
[MarshalAs(UnmanagedType.U1)] Boolean IsDirectory,
|
|
IntPtr Buffer,
|
|
IntPtr PSize);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 ServiceStart(
|
|
IntPtr Service,
|
|
UInt32 Argc,
|
|
[MarshalAs(UnmanagedType.LPArray,
|
|
ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)]
|
|
String[] Argv);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 ServiceStop(
|
|
IntPtr Service);
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
internal delegate Int32 ServiceControl(
|
|
IntPtr Service,
|
|
UInt32 Control,
|
|
UInt32 EventType,
|
|
IntPtr EventData);
|
|
}
|
|
|
|
internal static Proto.FspFileSystemPreflight FspFileSystemPreflight;
|
|
internal static Proto.FspFileSystemCreate FspFileSystemCreate;
|
|
internal static Proto.FspFileSystemDelete FspFileSystemDelete;
|
|
internal static Proto.FspFileSystemSetMountPoint FspFileSystemSetMountPoint;
|
|
internal static Proto.FspFileSystemSetMountPointEx _FspFileSystemSetMountPointEx;
|
|
internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint;
|
|
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
|
|
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
|
|
internal static Proto.FspFileSystemSendResponse FspFileSystemSendResponse;
|
|
internal static Proto.FspFileSystemNotifyBegin FspFileSystemNotifyBegin;
|
|
internal static Proto.FspFileSystemNotifyEnd FspFileSystemNotifyEnd;
|
|
internal static Proto.FspFileSystemNotify _FspFileSystemNotify;
|
|
internal static Proto.FspFileSystemGetOperationContext FspFileSystemGetOperationContext;
|
|
internal static Proto.FspFileSystemMountPointF FspFileSystemMountPoint;
|
|
internal static Proto.FspFileSystemSetOperationGuardStrategyF FspFileSystemSetOperationGuardStrategy;
|
|
internal static Proto.FspFileSystemSetDebugLogF FspFileSystemSetDebugLog;
|
|
internal static Proto.FspFileSystemOperationProcessIdF FspFileSystemOperationProcessId;
|
|
internal static Proto.FspFileSystemAddDirInfo _FspFileSystemAddDirInfo;
|
|
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
|
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
|
internal static Proto.FspFileSystemCanReplaceReparsePoint _FspFileSystemCanReplaceReparsePoint;
|
|
internal static Proto.FspFileSystemAddStreamInfo _FspFileSystemAddStreamInfo;
|
|
internal static Proto.FspFileSystemAddEa _FspFileSystemAddEa;
|
|
internal static Proto.FspFileSystemAddNotifyInfo _FspFileSystemAddNotifyInfo;
|
|
internal static Proto.FspFileSystemStopServiceIfNecessary FspFileSystemStopServiceIfNecessary;
|
|
internal static Proto.FspFileSystemAcquireDirectoryBuffer FspFileSystemAcquireDirectoryBuffer;
|
|
internal static Proto.FspFileSystemFillDirectoryBuffer FspFileSystemFillDirectoryBuffer;
|
|
internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer;
|
|
internal static Proto.FspFileSystemReadDirectoryBuffer FspFileSystemReadDirectoryBuffer;
|
|
internal static Proto.FspFileSystemDeleteDirectoryBuffer FspFileSystemDeleteDirectoryBuffer;
|
|
internal static Proto.FspSetSecurityDescriptor FspSetSecurityDescriptor;
|
|
internal static IntPtr _FspSetSecurityDescriptorPtr;
|
|
internal static Proto.FspDeleteSecurityDescriptor FspDeleteSecurityDescriptor;
|
|
internal static Proto.FspServiceCreate FspServiceCreate;
|
|
internal static Proto.FspServiceDelete FspServiceDelete;
|
|
internal static Proto.FspServiceAllowConsoleMode FspServiceAllowConsoleMode;
|
|
internal static Proto.FspServiceRequestTime FspServiceRequestTime;
|
|
internal static Proto.FspServiceSetExitCode FspServiceSetExitCode;
|
|
internal static Proto.FspServiceGetExitCode FspServiceGetExitCode;
|
|
internal static Proto.FspServiceLoop FspServiceLoop;
|
|
internal static Proto.FspServiceStop FspServiceStop;
|
|
internal static Proto.FspServiceLog FspServiceLog;
|
|
internal static Proto.FspVersion FspVersion;
|
|
internal static Proto.FspNtStatusFromWin32 FspNtStatusFromWin32;
|
|
internal static Proto.FspWin32FromNtStatus FspWin32FromNtStatus;
|
|
internal static Proto.FspDebugLog FspDebugLog;
|
|
internal static Proto.FspDebugLogSetHandle FspDebugLogSetHandle;
|
|
|
|
internal static unsafe Int32 FspFileSystemSetMountPointEx(
|
|
IntPtr FileSystem,
|
|
String MountPoint,
|
|
Byte[] SecurityDescriptor)
|
|
{
|
|
if (null != SecurityDescriptor)
|
|
{
|
|
fixed (Byte *P = SecurityDescriptor)
|
|
return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, (IntPtr)P);
|
|
}
|
|
else
|
|
return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero);
|
|
}
|
|
internal static unsafe UInt64 FspFileSystemGetOperationRequestHint()
|
|
{
|
|
return FspFileSystemGetOperationContext()->Request->Hint;
|
|
}
|
|
internal static unsafe Boolean FspFileSystemAddDirInfo(
|
|
ref DirInfo DirInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
fixed (DirInfo *P = &DirInfo)
|
|
return _FspFileSystemAddDirInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
internal static unsafe Boolean FspFileSystemEndDirInfo(
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
return _FspFileSystemAddDirInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
internal static unsafe Boolean FspFileSystemAddStreamInfo(
|
|
ref StreamInfo StreamInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
fixed (StreamInfo *P = &StreamInfo)
|
|
return _FspFileSystemAddStreamInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
internal static unsafe Boolean FspFileSystemEndStreamInfo(
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
return _FspFileSystemAddStreamInfo(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
internal static unsafe Boolean FspFileSystemAddNotifyInfo(
|
|
ref NotifyInfoInternal NotifyInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
fixed (NotifyInfoInternal *P = &NotifyInfo)
|
|
return _FspFileSystemAddNotifyInfo((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
|
|
internal delegate Int32 EnumerateEa(
|
|
Object FileNode,
|
|
Object FileDesc,
|
|
ref Object Context,
|
|
String EaName,
|
|
Byte[] EaValue,
|
|
Boolean NeedEa);
|
|
internal static unsafe Int32 FspFileSystemEnumerateEa(
|
|
Object FileNode,
|
|
Object FileDesc,
|
|
EnumerateEa EnumerateEa,
|
|
IntPtr Ea,
|
|
UInt32 EaLength)
|
|
{
|
|
Object Context = null;
|
|
FullEaInformation *P = (FullEaInformation *)Ea;
|
|
FullEaInformation *EndP = (FullEaInformation *)(Ea.ToInt64() + EaLength);
|
|
Int32 Result;
|
|
Result = 0/*STATUS_SUCCESS*/;
|
|
for (; EndP > P;
|
|
P = 0 != P->NextEntryOffset ?
|
|
(FullEaInformation *)(((IntPtr)P).ToInt64() + P->NextEntryOffset) :
|
|
EndP)
|
|
{
|
|
String EaName = Marshal.PtrToStringAnsi((IntPtr)P->EaName, P->EaNameLength);
|
|
Byte[] EaValue = null;
|
|
if (0 != P->EaValueLength)
|
|
{
|
|
EaValue = new Byte[P->EaValueLength];
|
|
Marshal.Copy((IntPtr)(((IntPtr)P->EaName).ToInt64() + P->EaNameLength + 1),
|
|
EaValue, 0, P->EaValueLength);
|
|
}
|
|
Boolean NeedEa = 0 != (0x80/*FILE_NEED_EA*/ & P->Flags);
|
|
Result = EnumerateEa(FileNode, FileDesc, ref Context, EaName, EaValue, NeedEa);
|
|
if (0 > Result)
|
|
break;
|
|
}
|
|
return Result;
|
|
}
|
|
internal static unsafe Boolean FspFileSystemAddEa(
|
|
ref FullEaInformation EaInfo,
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
fixed (FullEaInformation *P = &EaInfo)
|
|
return _FspFileSystemAddEa((IntPtr)P, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
internal static unsafe Boolean FspFileSystemEndEa(
|
|
IntPtr Buffer,
|
|
UInt32 Length,
|
|
out UInt32 PBytesTransferred)
|
|
{
|
|
return _FspFileSystemAddEa(IntPtr.Zero, Buffer, Length, out PBytesTransferred);
|
|
}
|
|
|
|
internal static unsafe Int32 FspFileSystemNotify(
|
|
IntPtr FileSystem,
|
|
NotifyInfo[] NotifyInfoArray)
|
|
{
|
|
int Length = 0;
|
|
for (int I = 0; NotifyInfoArray.Length > I; I++)
|
|
{
|
|
Length += NotifyInfoInternal.FileNameBufOffset +
|
|
NotifyInfoArray[I].FileName.Length * 2;
|
|
Length = (Length + 7) & ~7; // align to next qword boundary
|
|
}
|
|
|
|
Byte[] Buffer = new Byte[Length];
|
|
UInt32 BytesTransferred = default(UInt32);
|
|
fixed (Byte *P = Buffer)
|
|
{
|
|
for (int I = 0; NotifyInfoArray.Length > I; I++)
|
|
{
|
|
NotifyInfoInternal Internal = default(NotifyInfoInternal);
|
|
Internal.Action = (UInt32)NotifyInfoArray[I].Action;
|
|
Internal.Filter = (UInt32)NotifyInfoArray[I].Filter;
|
|
Internal.SetFileNameBuf(NotifyInfoArray[I].FileName);
|
|
FspFileSystemAddNotifyInfo(
|
|
ref Internal, (IntPtr)P, (UInt32)Length, out BytesTransferred);
|
|
}
|
|
return _FspFileSystemNotify(FileSystem, (IntPtr)P, (UIntPtr)BytesTransferred);
|
|
}
|
|
}
|
|
|
|
internal unsafe static Object GetUserContext(
|
|
IntPtr NativePtr)
|
|
{
|
|
IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr));
|
|
return IntPtr.Zero != UserContext ? GCHandle.FromIntPtr(UserContext).Target : null;
|
|
}
|
|
internal unsafe static void SetUserContext(
|
|
IntPtr NativePtr,
|
|
Object Obj)
|
|
{
|
|
Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)));
|
|
GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak);
|
|
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle;
|
|
}
|
|
internal unsafe static void DisposeUserContext(
|
|
IntPtr NativePtr)
|
|
{
|
|
IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr));
|
|
Debug.Assert(IntPtr.Zero != UserContext);
|
|
if (IntPtr.Zero != UserContext)
|
|
{
|
|
GCHandle.FromIntPtr(UserContext).Free();
|
|
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
private class FullContextHolder
|
|
{
|
|
public Object FileNode;
|
|
public Object FileDesc;
|
|
}
|
|
internal static void GetFullContext(ref FullContext FullContext,
|
|
out Object FileNode, out Object FileDesc)
|
|
{
|
|
FullContextHolder Holder = 0 != FullContext.UserContext2 ?
|
|
(FullContextHolder)GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target :
|
|
null;
|
|
if (null != Holder)
|
|
{
|
|
FileNode = Holder.FileNode;
|
|
FileDesc = Holder.FileDesc;
|
|
}
|
|
else
|
|
{
|
|
FileNode = null;
|
|
FileDesc = null;
|
|
}
|
|
}
|
|
internal static void SetFullContext(ref FullContext FullContext,
|
|
Object FileNode, Object FileDesc)
|
|
{
|
|
Debug.Assert(0 == FullContext.UserContext && 0 == FullContext.UserContext2);
|
|
FullContextHolder Holder = new FullContextHolder();
|
|
Holder.FileNode = FileNode;
|
|
Holder.FileDesc = FileDesc;
|
|
GCHandle Handle = GCHandle.Alloc(Holder, GCHandleType.Normal);
|
|
FullContext.UserContext2 = (UInt64)(IntPtr)Handle;
|
|
}
|
|
internal static void DisposeFullContext(ref FullContext FullContext)
|
|
{
|
|
Debug.Assert(0 == FullContext.UserContext && 0 != FullContext.UserContext2);
|
|
if (0 != FullContext.UserContext2)
|
|
{
|
|
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free();
|
|
FullContext.UserContext2 = 0;
|
|
}
|
|
}
|
|
|
|
internal unsafe static Int32 CopySecurityDescriptor(
|
|
Byte[] SecurityDescriptorBytes,
|
|
IntPtr SecurityDescriptor,
|
|
IntPtr PSecurityDescriptorSize)
|
|
{
|
|
if (IntPtr.Zero != PSecurityDescriptorSize)
|
|
{
|
|
if (null != SecurityDescriptorBytes)
|
|
{
|
|
if (SecurityDescriptorBytes.Length > (int)*(IntPtr *)PSecurityDescriptorSize)
|
|
{
|
|
*(IntPtr *)PSecurityDescriptorSize = (IntPtr)SecurityDescriptorBytes.Length;
|
|
return unchecked((Int32)0x80000005)/*STATUS_BUFFER_OVERFLOW*/;
|
|
}
|
|
*(IntPtr *)PSecurityDescriptorSize = (IntPtr)SecurityDescriptorBytes.Length;
|
|
if (IntPtr.Zero != SecurityDescriptor)
|
|
Marshal.Copy(SecurityDescriptorBytes, 0,
|
|
SecurityDescriptor, SecurityDescriptorBytes.Length);
|
|
}
|
|
else
|
|
*(IntPtr *)PSecurityDescriptorSize = IntPtr.Zero;
|
|
}
|
|
return 0/*STATUS_SUCCESS*/;
|
|
}
|
|
internal static Byte[] MakeSecurityDescriptor(
|
|
IntPtr SecurityDescriptor)
|
|
{
|
|
if (IntPtr.Zero != SecurityDescriptor)
|
|
{
|
|
Byte[] SecurityDescriptorBytes = new Byte[GetSecurityDescriptorLength(SecurityDescriptor)];
|
|
Marshal.Copy(SecurityDescriptor,
|
|
SecurityDescriptorBytes, 0, SecurityDescriptorBytes.Length);
|
|
return SecurityDescriptorBytes;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
internal unsafe static byte[] ModifySecurityDescriptor(
|
|
Byte[] SecurityDescriptorBytes,
|
|
UInt32 SecurityInformation,
|
|
Byte[] ModificationDescriptorBytes)
|
|
{
|
|
fixed (Byte *S = SecurityDescriptorBytes)
|
|
fixed (Byte *M = ModificationDescriptorBytes)
|
|
{
|
|
IntPtr SecurityDescriptor;
|
|
Int32 Result = FspSetSecurityDescriptor(
|
|
(IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
|
|
if (0 > Result)
|
|
return null;
|
|
SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
|
|
FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
|
|
return SecurityDescriptorBytes;
|
|
}
|
|
}
|
|
internal unsafe static Int32 ModifySecurityDescriptorEx(
|
|
Byte[] SecurityDescriptorBytes,
|
|
UInt32 SecurityInformation,
|
|
Byte[] ModificationDescriptorBytes,
|
|
ref Byte[] ModifiedDescriptorBytes)
|
|
{
|
|
fixed (Byte *S = SecurityDescriptorBytes)
|
|
fixed (Byte *M = ModificationDescriptorBytes)
|
|
{
|
|
IntPtr SecurityDescriptor;
|
|
Int32 Result = FspSetSecurityDescriptor(
|
|
(IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor);
|
|
if (0 > Result)
|
|
return Result;
|
|
SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor);
|
|
FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr);
|
|
ModifiedDescriptorBytes = SecurityDescriptorBytes;
|
|
return 0/*STATUS_SUCCESS*/;
|
|
}
|
|
}
|
|
|
|
internal unsafe static Int32 CopyReparsePoint(
|
|
Byte[] ReparseData,
|
|
IntPtr Buffer,
|
|
IntPtr PSize)
|
|
{
|
|
if (IntPtr.Zero != Buffer)
|
|
{
|
|
if (null != ReparseData)
|
|
{
|
|
if (ReparseData.Length > (int)*(UIntPtr *)PSize)
|
|
return unchecked((Int32)0xc0000023)/*STATUS_BUFFER_TOO_SMALL*/;
|
|
*(UIntPtr *)PSize = (UIntPtr)ReparseData.Length;
|
|
Marshal.Copy(ReparseData, 0, Buffer, ReparseData.Length);
|
|
}
|
|
else
|
|
*(UIntPtr *)PSize = UIntPtr.Zero;
|
|
}
|
|
return 0/*STATUS_SUCCESS*/;
|
|
}
|
|
internal static Byte[] MakeReparsePoint(
|
|
IntPtr Buffer,
|
|
UIntPtr Size)
|
|
{
|
|
if (IntPtr.Zero != Buffer)
|
|
{
|
|
Byte[] ReparseData = new Byte[(int)Size];
|
|
Marshal.Copy(Buffer, ReparseData, 0, ReparseData.Length);
|
|
return ReparseData;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
internal unsafe static Int32 FspFileSystemCanReplaceReparsePoint(
|
|
Byte[] CurrentReparseData,
|
|
Byte[] ReplaceReparseData)
|
|
{
|
|
fixed (Byte *C = CurrentReparseData)
|
|
fixed (Byte *R = ReplaceReparseData)
|
|
return _FspFileSystemCanReplaceReparsePoint(
|
|
(IntPtr)C, (UIntPtr)CurrentReparseData.Length,
|
|
(IntPtr)R, (UIntPtr)ReplaceReparseData.Length);
|
|
}
|
|
|
|
internal static Int32 SetDebugLogFile(String FileName)
|
|
{
|
|
IntPtr Handle;
|
|
if ("-" == FileName)
|
|
Handle = GetStdHandle(unchecked((UInt32)(-12))/*STD_ERROR_HANDLE*/);
|
|
else
|
|
Handle = CreateFileW(
|
|
FileName,
|
|
(UInt32)FileSystemRights.AppendData,
|
|
(UInt32)(FileShare.Read | FileShare.Write),
|
|
IntPtr.Zero,
|
|
(UInt32)FileMode.OpenOrCreate,
|
|
(UInt32)FileAttributes.Normal,
|
|
IntPtr.Zero);
|
|
if ((IntPtr)(-1) == Handle)
|
|
return FspNtStatusFromWin32((UInt32)Marshal.GetLastWin32Error());
|
|
Api.FspDebugLogSetHandle(Handle);
|
|
return 0/*STATUS_SUCCESS*/;
|
|
}
|
|
|
|
internal static Version GetVersion()
|
|
{
|
|
UInt32 Version = 0;
|
|
FspVersion(out Version);
|
|
return new System.Version((Int32)Version >> 16, (Int32)Version & 0xFFFF);
|
|
}
|
|
|
|
/* initialization */
|
|
internal static String ProductName = "WinFsp";
|
|
internal static String ProductFileName = "winfsp";
|
|
private static IntPtr LoadDll()
|
|
{
|
|
String RegPath, DllName, DllPath;
|
|
SYSTEM_INFO SystemInfo;
|
|
GetSystemInfo(out SystemInfo);
|
|
switch ((UInt32)SystemInfo.wProcessorArchitecture)
|
|
{
|
|
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_ARM64:
|
|
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName;
|
|
DllName = ProductFileName + "-a64.dll";
|
|
break;
|
|
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_AMD64:
|
|
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\" + ProductName;
|
|
DllName = ProductFileName + "-x64.dll";
|
|
break;
|
|
case SYSTEM_INFO.PROCESSOR_ARCHITECTURE_INTEL:
|
|
default:
|
|
RegPath = "HKEY_LOCAL_MACHINE\\SOFTWARE\\" + ProductName;
|
|
DllName = ProductFileName + "-x86.dll";
|
|
break;
|
|
}
|
|
IntPtr Module;
|
|
Module = LoadLibraryW(DllName);
|
|
if (IntPtr.Zero == Module)
|
|
{
|
|
DllPath = Microsoft.Win32.Registry.GetValue(RegPath, "InstallDir", null) as String;
|
|
if (null != DllPath)
|
|
{
|
|
DllPath = Path.Combine(DllPath, Path.Combine("bin", DllName));
|
|
Module = LoadLibraryW(DllPath);
|
|
}
|
|
if (IntPtr.Zero == Module)
|
|
throw new DllNotFoundException("cannot load " + DllName);
|
|
}
|
|
return Module;
|
|
}
|
|
private static IntPtr GetEntryPointPtr(IntPtr Module, String Name)
|
|
{
|
|
IntPtr Proc = GetProcAddress(Module, Name);
|
|
if (IntPtr.Zero == Proc)
|
|
throw new EntryPointNotFoundException("cannot get entry point " + Name);
|
|
return Proc;
|
|
}
|
|
private static T GetEntryPoint<T>(IntPtr Module)
|
|
{
|
|
return (T)(object)Marshal.GetDelegateForFunctionPointer(
|
|
GetEntryPointPtr(Module, typeof(T).Name), typeof(T));
|
|
}
|
|
private static void LoadProto(IntPtr Module)
|
|
{
|
|
FspFileSystemPreflight = GetEntryPoint<Proto.FspFileSystemPreflight>(Module);
|
|
FspFileSystemCreate = GetEntryPoint<Proto.FspFileSystemCreate>(Module);
|
|
FspFileSystemDelete = GetEntryPoint<Proto.FspFileSystemDelete>(Module);
|
|
FspFileSystemSetMountPoint = GetEntryPoint<Proto.FspFileSystemSetMountPoint>(Module);
|
|
_FspFileSystemSetMountPointEx = GetEntryPoint<Proto.FspFileSystemSetMountPointEx>(Module);
|
|
FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module);
|
|
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
|
|
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
|
|
FspFileSystemSendResponse = GetEntryPoint<Proto.FspFileSystemSendResponse>(Module);
|
|
FspFileSystemNotifyBegin = GetEntryPoint<Proto.FspFileSystemNotifyBegin>(Module);
|
|
FspFileSystemNotifyEnd = GetEntryPoint<Proto.FspFileSystemNotifyEnd>(Module);
|
|
_FspFileSystemNotify = GetEntryPoint<Proto.FspFileSystemNotify>(Module);
|
|
FspFileSystemGetOperationContext = GetEntryPoint<Proto.FspFileSystemGetOperationContext>(Module);
|
|
FspFileSystemMountPoint = GetEntryPoint<Proto.FspFileSystemMountPointF>(Module);
|
|
FspFileSystemSetOperationGuardStrategy = GetEntryPoint<Proto.FspFileSystemSetOperationGuardStrategyF>(Module);
|
|
FspFileSystemSetDebugLog = GetEntryPoint<Proto.FspFileSystemSetDebugLogF>(Module);
|
|
FspFileSystemOperationProcessId = GetEntryPoint<Proto.FspFileSystemOperationProcessIdF>(Module);
|
|
_FspFileSystemAddDirInfo = GetEntryPoint<Proto.FspFileSystemAddDirInfo>(Module);
|
|
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
|
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
|
_FspFileSystemCanReplaceReparsePoint = GetEntryPoint<Proto.FspFileSystemCanReplaceReparsePoint>(Module);
|
|
_FspFileSystemAddStreamInfo = GetEntryPoint<Proto.FspFileSystemAddStreamInfo>(Module);
|
|
_FspFileSystemAddEa = GetEntryPoint<Proto.FspFileSystemAddEa>(Module);
|
|
_FspFileSystemAddNotifyInfo = GetEntryPoint<Proto.FspFileSystemAddNotifyInfo>(Module);
|
|
FspFileSystemStopServiceIfNecessary = GetEntryPoint<Proto.FspFileSystemStopServiceIfNecessary>(Module);
|
|
FspFileSystemAcquireDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemAcquireDirectoryBuffer>(Module);
|
|
FspFileSystemFillDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemFillDirectoryBuffer>(Module);
|
|
FspFileSystemReleaseDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReleaseDirectoryBuffer>(Module);
|
|
FspFileSystemReadDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemReadDirectoryBuffer>(Module);
|
|
FspFileSystemDeleteDirectoryBuffer = GetEntryPoint<Proto.FspFileSystemDeleteDirectoryBuffer>(Module);
|
|
FspSetSecurityDescriptor = GetEntryPoint<Proto.FspSetSecurityDescriptor>(Module);
|
|
_FspSetSecurityDescriptorPtr = GetEntryPointPtr(Module, "FspSetSecurityDescriptor");
|
|
FspDeleteSecurityDescriptor = GetEntryPoint<Proto.FspDeleteSecurityDescriptor>(Module);
|
|
FspServiceCreate = GetEntryPoint<Proto.FspServiceCreate>(Module);
|
|
FspServiceDelete = GetEntryPoint<Proto.FspServiceDelete>(Module);
|
|
FspServiceAllowConsoleMode = GetEntryPoint<Proto.FspServiceAllowConsoleMode>(Module);
|
|
FspServiceRequestTime = GetEntryPoint<Proto.FspServiceRequestTime>(Module);
|
|
FspServiceSetExitCode = GetEntryPoint<Proto.FspServiceSetExitCode>(Module);
|
|
FspServiceGetExitCode = GetEntryPoint<Proto.FspServiceGetExitCode>(Module);
|
|
FspServiceLoop = GetEntryPoint<Proto.FspServiceLoop>(Module);
|
|
FspServiceStop = GetEntryPoint<Proto.FspServiceStop>(Module);
|
|
FspServiceLog = GetEntryPoint<Proto.FspServiceLog>(Module);
|
|
FspVersion = GetEntryPoint<Proto.FspVersion>(Module);
|
|
FspNtStatusFromWin32 = GetEntryPoint<Proto.FspNtStatusFromWin32>(Module);
|
|
FspWin32FromNtStatus = GetEntryPoint<Proto.FspWin32FromNtStatus>(Module);
|
|
FspDebugLog = GetEntryPoint<Proto.FspDebugLog>(Module);
|
|
FspDebugLogSetHandle = GetEntryPoint<Proto.FspDebugLogSetHandle>(Module);
|
|
}
|
|
private static void CheckVersion()
|
|
{
|
|
FileVersionInfo Info;
|
|
UInt32 Version = 0, VersionMajor, VersionMinor;
|
|
Info = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
|
|
FspVersion(out Version); VersionMajor = Version >> 16; VersionMinor = Version & 0xFFFF;
|
|
if (Info.FileMajorPart != VersionMajor || Info.FileMinorPart > VersionMinor)
|
|
throw new TypeLoadException(String.Format(
|
|
"incorrect dll version (need {0}.{1}, have {2}.{3})",
|
|
Info.FileMajorPart, Info.FileMinorPart, VersionMajor, VersionMinor));
|
|
}
|
|
static Api()
|
|
{
|
|
#if false //DEBUG
|
|
if (Debugger.IsAttached)
|
|
Debugger.Break();
|
|
#endif
|
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(
|
|
typeof(AssemblyProductAttribute), false);
|
|
if (null != attributes &&
|
|
0 < attributes.Length &&
|
|
null != attributes[0] as AssemblyProductAttribute)
|
|
{
|
|
ProductName = (attributes[0] as AssemblyProductAttribute).Product;
|
|
ProductFileName = ProductName.ToLowerInvariant();
|
|
}
|
|
LoadProto(LoadDll());
|
|
CheckVersion();
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct SYSTEM_INFO
|
|
{
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_INTEL = 0;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_MIPS = 1;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_ALPHA = 2;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_PPC = 3;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_SHX = 4;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM = 5;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_IA64 = 6;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_ALPHA64 = 7;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_MSIL = 8;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_AMD64 = 9;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_NEUTRAL = 11;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM64 = 12;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 = 13;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_IA32_ON_ARM64 = 14;
|
|
internal const UInt32 PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF;
|
|
|
|
internal UInt16 wProcessorArchitecture;
|
|
internal UInt16 wReserved;
|
|
internal UInt32 dwPageSize;
|
|
internal IntPtr lpMinimumApplicationAddress;
|
|
internal IntPtr lpMaximumApplicationAddress;
|
|
internal IntPtr dwActiveProcessorMask;
|
|
internal UInt32 dwNumberOfProcessors;
|
|
internal UInt32 dwProcessorType;
|
|
internal UInt32 dwAllocationGranularity;
|
|
internal UInt16 wProcessorLevel;
|
|
internal UInt16 wProcessorRevision;
|
|
}
|
|
|
|
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
|
private static extern IntPtr LoadLibraryW(
|
|
[MarshalAs(UnmanagedType.LPWStr)] String DllName);
|
|
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
|
private static extern IntPtr GetProcAddress(
|
|
IntPtr hModule,
|
|
[MarshalAs(UnmanagedType.LPStr)] String lpProcName);
|
|
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = false)]
|
|
private static extern void GetSystemInfo(
|
|
out SYSTEM_INFO SystemInfo);
|
|
[DllImport("advapi32.dll", CallingConvention = CallingConvention.StdCall)]
|
|
private static extern UInt32 GetSecurityDescriptorLength(IntPtr SecurityDescriptor);
|
|
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
|
private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
|
|
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
|
private static extern IntPtr CreateFileW(
|
|
[MarshalAs(UnmanagedType.LPWStr)] String lpFileName,
|
|
UInt32 dwDesiredAccess,
|
|
UInt32 dwShareMode,
|
|
IntPtr lpSecurityAttributes,
|
|
UInt32 dwCreationDisposition,
|
|
UInt32 dwFlagsAndAttributes,
|
|
IntPtr hTemplateFile);
|
|
}
|
|
|
|
}
|