src: dotnet: ReadDirectory helpers

This commit is contained in:
Bill Zissimopoulos 2017-04-08 18:41:00 -07:00
parent 0d9d8ef5a2
commit a0df9babf9
2 changed files with 181 additions and 1 deletions

View File

@ -26,6 +26,27 @@ namespace Fsp
public partial class FileSystem : IDisposable
{
/* types */
public class DirectoryBuffer : IDisposable
{
~DirectoryBuffer()
{
Dispose(false);
}
public void Dispose()
{
lock (this)
Dispose(true);
GC.SuppressFinalize(true);
}
protected virtual void Dispose(bool disposing)
{
Api.FspFileSystemDeleteDirectoryBuffer(ref DirBuffer);
}
internal IntPtr DirBuffer;
}
/* ctor/dtor */
public FileSystem()
{
@ -177,6 +198,70 @@ namespace Fsp
}
/* helpers */
public Int32 SeekableReadDirectory(
Object FileNode,
Object FileDesc,
String Pattern,
String Marker,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
Object Context = null;
String FileName;
DirInfo DirInfo = default(DirInfo);
PBytesTransferred = default(UInt32);
while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker,
ref Context, out FileName, out DirInfo.FileInfo))
{
DirInfo.SetFileNameBuf(FileName);
if (!Api.FspFileSystemAddDirInfo(ref DirInfo, Buffer, Length,
out PBytesTransferred))
break;
}
return STATUS_SUCCESS;
}
public Int32 BufferedReadDirectory(
DirectoryBuffer DirectoryBuffer,
Object FileNode,
Object FileDesc,
String Pattern,
String Marker,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred)
{
Object Context = null;
String FileName;
DirInfo DirInfo = default(DirInfo);
Int32 DirBufferResult = STATUS_SUCCESS;
PBytesTransferred = default(UInt32);
if (Api.FspFileSystemAcquireDirectoryBuffer(ref DirectoryBuffer.DirBuffer, null == Marker,
out DirBufferResult))
try
{
while (ReadDirectoryEntry(FileNode, FileDesc, Pattern, Marker,
ref Context, out FileName, out DirInfo.FileInfo))
{
DirInfo.SetFileNameBuf(FileName);
if (!Api.FspFileSystemFillDirectoryBuffer(
ref DirectoryBuffer.DirBuffer, ref DirInfo, out DirBufferResult))
break;
}
}
finally
{
Api.FspFileSystemReleaseDirectoryBuffer(ref DirectoryBuffer.DirBuffer);
}
if (0 > DirBufferResult)
{
PBytesTransferred = default(UInt32);
return DirBufferResult;
}
Api.FspFileSystemReadDirectoryBuffer(ref DirectoryBuffer.DirBuffer,
Marker, Buffer, Length, out PBytesTransferred);
return STATUS_SUCCESS;
}
public static Int32 NtStatusFromWin32(UInt32 Error)
{
return Api.FspNtStatusFromWin32(Error);
@ -380,6 +465,19 @@ namespace Fsp
PBytesTransferred = default(UInt32);
return STATUS_INVALID_DEVICE_REQUEST;
}
protected virtual Boolean ReadDirectoryEntry(
Object FileNode,
Object FileDesc,
String Pattern,
String Marker,
ref Object Context,
out String FileName,
out FileInfo FileInfo)
{
FileName = default(String);
FileInfo = default(FileInfo);
return false;
}
protected virtual Int32 ResolveReparsePoints(
String FileName,
UInt32 ReparsePointIndex,

View File

@ -152,10 +152,26 @@ namespace Fsp.Interop
[StructLayout(LayoutKind.Sequential)]
internal struct DirInfo
{
internal const int FileNameBufSize = 255;
internal UInt16 Size;
internal FileInfo FileInfo;
internal unsafe fixed Byte Padding[24];
//internal unsafe fixed UInt16 FileNameBuf[];
internal unsafe fixed UInt16 FileNameBuf[FileNameBufSize];
public unsafe void SetFileNameBuf(String Value)
{
fixed (UInt16 *P = FileNameBuf)
{
int Size = Value.Length;
if (Size > FileNameBufSize)
Size = FileNameBufSize;
for (int I = 0; Size > I; I++)
P[I] = Value[I];
this.Size = (UInt16)(sizeof(DirInfo) + Size);
}
}
}
[StructLayout(LayoutKind.Sequential)]
@ -424,6 +440,12 @@ namespace Fsp.Interop
internal delegate Int32 FspFileSystemStopDispatcher(
IntPtr FileSystem);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Boolean FspFileSystemAddDirInfo(
IntPtr DirInfo,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 FspFileSystemFindReparsePoint(
IntPtr FileSystem,
GetReparsePointByName GetReparsePointByName,
@ -441,6 +463,41 @@ namespace Fsp.Interop
out IoStatusBlock PIoStatus,
IntPtr Buffer,
ref UIntPtr PSize);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Int32 FspFileSystemCanReplaceReparsePoint(
IntPtr CurrentReparseData,
UIntPtr CurrentReparseDataSize,
IntPtr ReplaceReparseData,
UIntPtr ReplaceReparseDataSize);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Boolean FspFileSystemAddStreamInfo(
IntPtr StreamInfo,
IntPtr Buffer,
UInt32 Length,
out UInt32 PBytesTransferred);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate Boolean FspFileSystemAcquireDirectoryBuffer(
ref IntPtr PDirBuffer,
Boolean Reset,
out Int32 PResult);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
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);
/* Service */
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@ -528,9 +585,16 @@ namespace Fsp.Interop
internal static Proto.FspFileSystemRemoveMountPoint FspFileSystemRemoveMountPoint;
internal static Proto.FspFileSystemStartDispatcher FspFileSystemStartDispatcher;
internal static Proto.FspFileSystemStopDispatcher FspFileSystemStopDispatcher;
internal static Proto.FspFileSystemAddDirInfo _FspFileSystemAddDirInfo;
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
internal static Proto.FspVersion FspVersion;
internal static Proto.FspFileSystemCanReplaceReparsePoint FspFileSystemCanReplaceReparsePoint;
internal static Proto.FspFileSystemAddStreamInfo FspFileSystemAddStreamInfo;
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.FspServiceCreate FspServiceCreate;
internal static Proto.FspServiceDelete FspServiceDelete;
internal static Proto.FspServiceAllowConsoleMode FspServiceAllowConsoleMode;
@ -540,6 +604,7 @@ namespace Fsp.Interop
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.FspDebugLogSetHandle FspDebugLogSetHandle;
@ -557,6 +622,15 @@ namespace Fsp.Interop
else
return _FspFileSystemSetMountPointEx(FileSystem, MountPoint, IntPtr.Zero);
}
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 unsafe static Object GetUserContext(
IntPtr NativePtr)
@ -729,8 +803,16 @@ namespace Fsp.Interop
FspFileSystemRemoveMountPoint = GetEntryPoint<Proto.FspFileSystemRemoveMountPoint>(Module);
FspFileSystemStartDispatcher = GetEntryPoint<Proto.FspFileSystemStartDispatcher>(Module);
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(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);
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);
FspServiceCreate = GetEntryPoint<Proto.FspServiceCreate>(Module);
FspServiceDelete = GetEntryPoint<Proto.FspServiceDelete>(Module);
FspServiceAllowConsoleMode = GetEntryPoint<Proto.FspServiceAllowConsoleMode>(Module);