mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
src: dotnet: add Service class
This commit is contained in:
parent
d545b8df26
commit
c782c4d668
@ -50,6 +50,9 @@
|
|||||||
<Compile Include="..\..\src\dotnet\Interop.cs">
|
<Compile Include="..\..\src\dotnet\Interop.cs">
|
||||||
<Link>Interop.cs</Link>
|
<Link>Interop.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\..\src\dotnet\Service.cs">
|
||||||
|
<Link>Service.cs</Link>
|
||||||
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
@ -440,6 +440,33 @@ namespace Fsp.Interop
|
|||||||
IntPtr Buffer,
|
IntPtr Buffer,
|
||||||
ref UIntPtr PSize);
|
ref UIntPtr PSize);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[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 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);
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
internal delegate Int32 FspVersion(
|
internal delegate Int32 FspVersion(
|
||||||
out UInt32 PVersion);
|
out UInt32 PVersion);
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
@ -449,7 +476,7 @@ namespace Fsp.Interop
|
|||||||
internal delegate UInt32 FspWin32FromNtStatus(
|
internal delegate UInt32 FspWin32FromNtStatus(
|
||||||
Int32 Status);
|
Int32 Status);
|
||||||
|
|
||||||
/* callback */
|
/* callbacks */
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
internal delegate Int32 GetReparsePointByName(
|
internal delegate Int32 GetReparsePointByName(
|
||||||
IntPtr FileSystem,
|
IntPtr FileSystem,
|
||||||
@ -458,6 +485,22 @@ namespace Fsp.Interop
|
|||||||
Boolean IsDirectory,
|
Boolean IsDirectory,
|
||||||
IntPtr Buffer,
|
IntPtr Buffer,
|
||||||
ref UIntPtr PSize);
|
ref UIntPtr 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.FspFileSystemPreflight FspFileSystemPreflight;
|
||||||
@ -471,6 +514,13 @@ namespace Fsp.Interop
|
|||||||
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
internal static Proto.FspFileSystemFindReparsePoint FspFileSystemFindReparsePoint;
|
||||||
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
internal static Proto.FspFileSystemResolveReparsePoints FspFileSystemResolveReparsePoints;
|
||||||
internal static Proto.FspVersion FspVersion;
|
internal static Proto.FspVersion FspVersion;
|
||||||
|
internal static Proto.FspServiceCreate FspServiceCreate;
|
||||||
|
internal static Proto.FspServiceDelete FspServiceDelete;
|
||||||
|
internal static Proto.FspServiceAllowConsoleMode FspServiceAllowConsoleMode;
|
||||||
|
internal static Proto.FspServiceGetExitCode FspServiceGetExitCode;
|
||||||
|
internal static Proto.FspServiceLoop FspServiceLoop;
|
||||||
|
internal static Proto.FspServiceStop FspServiceStop;
|
||||||
|
internal static Proto.FspServiceLog FspServiceLog;
|
||||||
internal static Proto.FspNtStatusFromWin32 FspNtStatusFromWin32;
|
internal static Proto.FspNtStatusFromWin32 FspNtStatusFromWin32;
|
||||||
internal static Proto.FspWin32FromNtStatus FspWin32FromNtStatus;
|
internal static Proto.FspWin32FromNtStatus FspWin32FromNtStatus;
|
||||||
|
|
||||||
@ -599,6 +649,33 @@ namespace Fsp.Interop
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal unsafe static Object FspServiceGetUserContext(
|
||||||
|
IntPtr Service)
|
||||||
|
{
|
||||||
|
IntPtr UserContext = *(IntPtr *)((byte *)Service + sizeof(IntPtr));
|
||||||
|
return IntPtr.Zero != UserContext ? GCHandle.FromIntPtr(UserContext).Target : null;
|
||||||
|
}
|
||||||
|
internal unsafe static void FspServiceSetUserContext(
|
||||||
|
IntPtr Service,
|
||||||
|
Object Obj)
|
||||||
|
{
|
||||||
|
if (null != Obj)
|
||||||
|
{
|
||||||
|
Debug.Assert(IntPtr.Zero == *(IntPtr *)((byte *)Service + sizeof(IntPtr)));
|
||||||
|
GCHandle Handle = GCHandle.Alloc(Obj, GCHandleType.Weak);
|
||||||
|
*(IntPtr *)((byte *)Service + sizeof(IntPtr)) = (IntPtr)Handle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntPtr UserContext = *(IntPtr *)((byte *)Service + sizeof(IntPtr));
|
||||||
|
if (IntPtr.Zero != UserContext)
|
||||||
|
{
|
||||||
|
GCHandle.FromIntPtr(UserContext).Free();
|
||||||
|
*(IntPtr *)((byte *)Service + sizeof(IntPtr)) = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* initialization */
|
/* initialization */
|
||||||
private static IntPtr LoadDll()
|
private static IntPtr LoadDll()
|
||||||
{
|
{
|
||||||
@ -643,6 +720,13 @@ namespace Fsp.Interop
|
|||||||
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
|
FspFileSystemStopDispatcher = GetEntryPoint<Proto.FspFileSystemStopDispatcher>(Module);
|
||||||
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
FspFileSystemFindReparsePoint = GetEntryPoint<Proto.FspFileSystemFindReparsePoint>(Module);
|
||||||
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
FspFileSystemResolveReparsePoints = GetEntryPoint<Proto.FspFileSystemResolveReparsePoints>(Module);
|
||||||
|
FspServiceCreate = GetEntryPoint<Proto.FspServiceCreate>(Module);
|
||||||
|
FspServiceDelete = GetEntryPoint<Proto.FspServiceDelete>(Module);
|
||||||
|
FspServiceAllowConsoleMode = GetEntryPoint<Proto.FspServiceAllowConsoleMode>(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);
|
FspVersion = GetEntryPoint<Proto.FspVersion>(Module);
|
||||||
FspNtStatusFromWin32 = GetEntryPoint<Proto.FspNtStatusFromWin32>(Module);
|
FspNtStatusFromWin32 = GetEntryPoint<Proto.FspNtStatusFromWin32>(Module);
|
||||||
FspWin32FromNtStatus = GetEntryPoint<Proto.FspWin32FromNtStatus>(Module);
|
FspWin32FromNtStatus = GetEntryPoint<Proto.FspWin32FromNtStatus>(Module);
|
||||||
|
128
src/dotnet/Service.cs
Normal file
128
src/dotnet/Service.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/**
|
||||||
|
* @file dotnet/Service.cs
|
||||||
|
*
|
||||||
|
* @copyright 2015-2017 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 file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using Fsp.Interop;
|
||||||
|
|
||||||
|
namespace Fsp
|
||||||
|
{
|
||||||
|
|
||||||
|
public class Service
|
||||||
|
{
|
||||||
|
/* const */
|
||||||
|
public const UInt32 EVENTLOG_ERROR_TYPE = 0x0001;
|
||||||
|
public const UInt32 EVENTLOG_WARNING_TYPE = 0x0002;
|
||||||
|
public const UInt32 EVENTLOG_INFORMATION_TYPE = 0x0004;
|
||||||
|
|
||||||
|
/* ctor/dtor */
|
||||||
|
Service(String ServiceName)
|
||||||
|
{
|
||||||
|
_CreateResult = Api.FspServiceCreate(ServiceName, OnStart, OnStop, null, out _Service);
|
||||||
|
Api.FspServiceSetUserContext(_Service, this);
|
||||||
|
}
|
||||||
|
~Service()
|
||||||
|
{
|
||||||
|
if (IntPtr.Zero != _Service)
|
||||||
|
{
|
||||||
|
Api.FspServiceSetUserContext(_Service, null);
|
||||||
|
Api.FspServiceDelete(_Service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* control */
|
||||||
|
public int Run()
|
||||||
|
{
|
||||||
|
if (0 > _CreateResult)
|
||||||
|
{
|
||||||
|
Log(EVENTLOG_ERROR_TYPE,
|
||||||
|
String.Format("The service cannot be created (Status={0:X}).", _CreateResult));
|
||||||
|
return (int)Api.FspWin32FromNtStatus(_CreateResult);
|
||||||
|
}
|
||||||
|
Api.FspServiceAllowConsoleMode(_Service);
|
||||||
|
Int32 Result = Api.FspServiceLoop(_Service);
|
||||||
|
UInt32 ExitCode = Api.FspServiceGetExitCode(_Service);
|
||||||
|
if (0 > _CreateResult)
|
||||||
|
{
|
||||||
|
Log(EVENTLOG_ERROR_TYPE,
|
||||||
|
String.Format("The service has failed to run (Status={0:X}).", Result));
|
||||||
|
return (int)Api.FspWin32FromNtStatus(Result);
|
||||||
|
}
|
||||||
|
return (int)ExitCode;
|
||||||
|
}
|
||||||
|
void Stop()
|
||||||
|
{
|
||||||
|
if (0 > _CreateResult)
|
||||||
|
return;
|
||||||
|
Api.FspServiceStop(_Service);
|
||||||
|
}
|
||||||
|
public static void Log(UInt32 Type, String Message)
|
||||||
|
{
|
||||||
|
Api.FspServiceLog(Type, "%s", Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start/stop */
|
||||||
|
protected virtual Int32 ExceptionHandler(Exception ex)
|
||||||
|
{
|
||||||
|
return unchecked((Int32)0xE0434f4D)/*STATUS_CLR_EXCEPTION*/;
|
||||||
|
}
|
||||||
|
protected virtual Int32 OnStart(String[] Args)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
protected virtual Int32 OnStop()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* callbacks */
|
||||||
|
private static Int32 OnStart(
|
||||||
|
IntPtr Service,
|
||||||
|
UInt32 Argc,
|
||||||
|
String[] Argv)
|
||||||
|
{
|
||||||
|
Service self = (Service)Api.FspServiceGetUserContext(Service);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return self.OnStart(
|
||||||
|
Argv);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return self.ExceptionHandler(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Int32 OnStop(
|
||||||
|
IntPtr Service)
|
||||||
|
{
|
||||||
|
Service self = (Service)Api.FspServiceGetUserContext(Service);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return self.OnStop();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return self.ExceptionHandler(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntPtr _Service;
|
||||||
|
private Int32 _CreateResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user