123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- using System.IO.Pipes;
- using System.Security.Principal;
- using H.Pipes;
- using H.Pipes.AccessControl;
- using InABox.Core;
- namespace InABox.IPC
- {
- public class RPCServerTransport : IDisposable
- {
- PipeServer<RPCMessage> Server;
- private Dictionary<String, IRPCCommandHandler> _commands = new Dictionary<String, IRPCCommandHandler>();
- public void AddCommandHandler<TSender, TCommand, TProperties, TResult>(RPCCommandHandler<TSender,TProperties,TResult> commandHandler)
- where TCommand : IRPCCommand<TProperties, TResult>
- where TSender : class
- {
- _commands[typeof(TCommand).Name] = commandHandler;
- }
-
- public event LogFunction? OnLog;
- private void SetPipeSecurity()
- {
- #pragma warning disable CA1416
-
- var pipeSecurity = new PipeSecurity();
- pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
- pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
- pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
- Server.SetPipeSecurity(pipeSecurity);
-
- #pragma warning restore CA1416
- }
- public RPCServerTransport(string name)
- {
- Server = new PipeServer<RPCMessage>(name);
- #if WINDOWS
- SetPipeSecurity();
- #endif
-
- Server.ClientConnected += Server_ClientConnected;
- Server.ClientDisconnected += Server_ClientDisconnected;
- Server.MessageReceived += Server_MessageReceived;
- Server.ExceptionOccurred += Server_ExceptionOccurred;
- }
- private void Server_ExceptionOccurred(object? sender, H.Pipes.Args.ExceptionEventArgs e)
- {
- OnLog?.Invoke(LogType.Error, "", $"Exception Occurred: {e.Exception.Message}");
- }
- public void Start()
- {
- Server.StartAsync().Wait();
- }
-
- private void Server_MessageReceived(object? sender, H.Pipes.Args.ConnectionMessageEventArgs<RPCMessage?> e)
- {
- Task.Run(() =>
- {
- if (e.Message != null)
- {
- RPCMessage message = new RPCMessage(e.Message.RequestID, e.Message.Command, "");
-
- if (!_commands.TryGetValue(e.Message.Command, out var command))
- message.Error = RPCError.COMMANDNOTFOUND;
- else
- {
- try
- {
- message.Payload = command.Execute(sender!, e.Message.Payload) ?? "";
- }
- catch (Exception err)
- {
- OnLog?.Invoke(LogType.Error, "", err.Message);
- message.Error = RPCError.SERVERERROR;
- }
- }
- e.Connection.WriteAsync(message);
-
- }
- else
- OnLog?.Invoke(LogType.Error, "", "Null Message Received");
- }
- );
- }
- private void Server_ClientDisconnected(object? sender, H.Pipes.Args.ConnectionEventArgs<RPCMessage> e)
- {
- OnLog?.Invoke(LogType.Information, "", "Client Disconnected");
- e.Connection.DisposeAsync();
- }
- private void Server_ClientConnected(object? sender, H.Pipes.Args.ConnectionEventArgs<RPCMessage> e)
- {
- OnLog?.Invoke(LogType.Information, "", "Client Connected");
- }
- public void Dispose()
- {
- Server.DisposeAsync().AsTask().Wait();
- }
-
- ~RPCServerTransport()
- {
- Dispose();
- }
- }
- }
|