mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dotnet: fix problems with FullContext and GCHandle
This commit is contained in:
parent
8c5d9bda20
commit
bf64bcf9ba
@ -56,7 +56,7 @@ namespace Fsp
|
|||||||
{
|
{
|
||||||
ExceptionHandler(_FileSystem, ex);
|
ExceptionHandler(_FileSystem, ex);
|
||||||
}
|
}
|
||||||
Api.SetUserContext(_FileSystemPtr, null);
|
Api.DisposeUserContext(_FileSystemPtr);
|
||||||
Api.FspFileSystemDelete(_FileSystemPtr);
|
Api.FspFileSystemDelete(_FileSystemPtr);
|
||||||
_FileSystemPtr = IntPtr.Zero;
|
_FileSystemPtr = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ namespace Fsp
|
|||||||
}
|
}
|
||||||
if (0 > Result)
|
if (0 > Result)
|
||||||
{
|
{
|
||||||
Api.SetUserContext(_FileSystemPtr, null);
|
Api.DisposeUserContext(_FileSystemPtr);
|
||||||
Api.FspFileSystemDelete(_FileSystemPtr);
|
Api.FspFileSystemDelete(_FileSystemPtr);
|
||||||
_FileSystemPtr = IntPtr.Zero;
|
_FileSystemPtr = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
@ -457,7 +457,7 @@ namespace Fsp
|
|||||||
FileSystem.Close(
|
FileSystem.Close(
|
||||||
FileNode,
|
FileNode,
|
||||||
FileDesc);
|
FileDesc);
|
||||||
Api.SetFullContext(ref FullContext, null, null);
|
Api.DisposeFullContext(ref FullContext);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -917,8 +917,8 @@ namespace Fsp
|
|||||||
private static FileSystemInterface _FileSystemInterface;
|
private static FileSystemInterface _FileSystemInterface;
|
||||||
private static IntPtr _FileSystemInterfacePtr;
|
private static IntPtr _FileSystemInterfacePtr;
|
||||||
private VolumeParams _VolumeParams;
|
private VolumeParams _VolumeParams;
|
||||||
private IntPtr _FileSystemPtr;
|
|
||||||
private FileSystemBase _FileSystem;
|
private FileSystemBase _FileSystem;
|
||||||
|
private IntPtr _FileSystemPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -721,61 +721,61 @@ namespace Fsp.Interop
|
|||||||
IntPtr NativePtr,
|
IntPtr NativePtr,
|
||||||
Object Obj)
|
Object Obj)
|
||||||
{
|
{
|
||||||
if (null != 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)
|
||||||
{
|
{
|
||||||
Debug.Assert(IntPtr.Zero == *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)));
|
GCHandle.FromIntPtr(UserContext).Free();
|
||||||
GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak);
|
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = IntPtr.Zero;
|
||||||
*(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr)) = (IntPtr)Handle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IntPtr UserContext = *(IntPtr *)((Byte *)NativePtr + sizeof(IntPtr));
|
|
||||||
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,
|
internal static void GetFullContext(ref FullContext FullContext,
|
||||||
out Object FileNode, out Object FileDesc)
|
out Object FileNode, out Object FileDesc)
|
||||||
{
|
{
|
||||||
FileNode = 0 != FullContext.UserContext ?
|
FullContextHolder Holder = 0 != FullContext.UserContext2 ?
|
||||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Target : null;
|
(FullContextHolder)GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Target :
|
||||||
FileDesc = 0 != FullContext.UserContext2 ?
|
null;
|
||||||
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,
|
internal static void SetFullContext(ref FullContext FullContext,
|
||||||
Object FileNode, Object FileDesc)
|
Object FileNode, Object FileDesc)
|
||||||
{
|
{
|
||||||
if (null != FileNode)
|
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)
|
||||||
{
|
{
|
||||||
Debug.Assert(0 == FullContext.UserContext);
|
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free();
|
||||||
GCHandle Handle = GCHandle.Alloc(FileNode, GCHandleType.Normal);
|
FullContext.UserContext2 = 0;
|
||||||
FullContext.UserContext = (UInt64)(IntPtr)Handle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 != FullContext.UserContext)
|
|
||||||
{
|
|
||||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext).Free();
|
|
||||||
FullContext.UserContext = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (null != FileDesc)
|
|
||||||
{
|
|
||||||
Debug.Assert(0 == FullContext.UserContext2);
|
|
||||||
GCHandle Handle = GCHandle.Alloc(FileDesc, GCHandleType.Normal);
|
|
||||||
FullContext.UserContext2 = (UInt64)(IntPtr)Handle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 != FullContext.UserContext2)
|
|
||||||
{
|
|
||||||
GCHandle.FromIntPtr((IntPtr)FullContext.UserContext2).Free();
|
|
||||||
FullContext.UserContext2 = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,23 +33,23 @@ namespace Fsp
|
|||||||
/* ctor/dtor */
|
/* ctor/dtor */
|
||||||
public Service(String ServiceName)
|
public Service(String ServiceName)
|
||||||
{
|
{
|
||||||
Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _Service);
|
Api.FspServiceCreate(ServiceName, _OnStart, _OnStop, null, out _ServicePtr);
|
||||||
if (IntPtr.Zero != _Service)
|
if (IntPtr.Zero != _ServicePtr)
|
||||||
Api.SetUserContext(_Service, this);
|
Api.SetUserContext(_ServicePtr, this);
|
||||||
}
|
}
|
||||||
~Service()
|
~Service()
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero != _Service)
|
if (IntPtr.Zero != _ServicePtr)
|
||||||
{
|
{
|
||||||
Api.SetUserContext(_Service, null);
|
Api.DisposeUserContext(_ServicePtr);
|
||||||
Api.FspServiceDelete(_Service);
|
Api.FspServiceDelete(_ServicePtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* control */
|
/* control */
|
||||||
public int Run()
|
public int Run()
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero == _Service)
|
if (IntPtr.Zero == _ServicePtr)
|
||||||
{
|
{
|
||||||
const Int32 STATUS_INSUFFICIENT_RESOURCES = unchecked((Int32)0xc000009a);
|
const Int32 STATUS_INSUFFICIENT_RESOURCES = unchecked((Int32)0xc000009a);
|
||||||
Log(EVENTLOG_ERROR_TYPE,
|
Log(EVENTLOG_ERROR_TYPE,
|
||||||
@ -57,9 +57,9 @@ namespace Fsp
|
|||||||
GetType().FullName, STATUS_INSUFFICIENT_RESOURCES));
|
GetType().FullName, STATUS_INSUFFICIENT_RESOURCES));
|
||||||
return (int)Api.FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES);
|
return (int)Api.FspWin32FromNtStatus(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
Api.FspServiceAllowConsoleMode(_Service);
|
Api.FspServiceAllowConsoleMode(_ServicePtr);
|
||||||
Int32 Result = Api.FspServiceLoop(_Service);
|
Int32 Result = Api.FspServiceLoop(_ServicePtr);
|
||||||
int ExitCode = (int)Api.FspServiceGetExitCode(_Service);
|
int ExitCode = (int)Api.FspServiceGetExitCode(_ServicePtr);
|
||||||
if (0 > Result)
|
if (0 > Result)
|
||||||
{
|
{
|
||||||
Log(EVENTLOG_ERROR_TYPE,
|
Log(EVENTLOG_ERROR_TYPE,
|
||||||
@ -71,34 +71,34 @@ namespace Fsp
|
|||||||
}
|
}
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero == _Service)
|
if (IntPtr.Zero == _ServicePtr)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
Api.FspServiceStop(_Service);
|
Api.FspServiceStop(_ServicePtr);
|
||||||
}
|
}
|
||||||
public void RequestTime(UInt32 Time)
|
public void RequestTime(UInt32 Time)
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero == _Service)
|
if (IntPtr.Zero == _ServicePtr)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
Api.FspServiceRequestTime(_Service, Time);
|
Api.FspServiceRequestTime(_ServicePtr, Time);
|
||||||
}
|
}
|
||||||
public int ExitCode
|
public int ExitCode
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero == _Service)
|
if (IntPtr.Zero == _ServicePtr)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
return (int)Api.FspServiceGetExitCode(_Service);
|
return (int)Api.FspServiceGetExitCode(_ServicePtr);
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (IntPtr.Zero == _Service)
|
if (IntPtr.Zero == _ServicePtr)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
Api.FspServiceSetExitCode(_Service, (UInt32)value);
|
Api.FspServiceSetExitCode(_ServicePtr, (UInt32)value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public IntPtr ServiceHandle
|
public IntPtr ServiceHandle
|
||||||
{
|
{
|
||||||
get { return _Service; }
|
get { return _ServicePtr; }
|
||||||
}
|
}
|
||||||
public static void Log(UInt32 Type, String Message)
|
public static void Log(UInt32 Type, String Message)
|
||||||
{
|
{
|
||||||
@ -152,7 +152,7 @@ namespace Fsp
|
|||||||
|
|
||||||
private static Api.Proto.ServiceStart _OnStart = OnStart;
|
private static Api.Proto.ServiceStart _OnStart = OnStart;
|
||||||
private static Api.Proto.ServiceStop _OnStop = OnStop;
|
private static Api.Proto.ServiceStop _OnStop = OnStop;
|
||||||
private IntPtr _Service;
|
private IntPtr _ServicePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user