This commit is contained in:
Meik
2025-11-11 11:03:42 +01:00
commit dc3e8a2e4c
582 changed files with 191465 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
using System.IO.Pipes;
using System.Diagnostics;
using System.Text;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Microsoft.Win32;
using C4IT.Logging;
using System.Threading;
using System.Windows;
using static C4IT.Logging.cLogManager;
using System.Collections.Generic;
namespace FasdDesktopUi.Basics
{
static public class cF4sdPipeClient
{
static public bool Send(string SendStr, string PipeName, int TimeOut = 1000)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (DefaultLogger.IsDebug)
{
var _msg = new List<string>() { $"send to pipe {PipeName}", SendStr };
DefaultLogger.LogList(LogLevels.Debug, _msg);
}
NamedPipeClientStream pipeStream = new NamedPipeClientStream
(".", PipeName, PipeDirection.Out, PipeOptions.WriteThrough);
// The connect function will indefinitely wait for the pipe to become available
// If that is not acceptable specify a maximum waiting time (in ms)
pipeStream.Connect(TimeOut);
byte[] _buffer = Encoding.UTF8.GetBytes(SendStr);
pipeStream.Write(_buffer, 0, _buffer.Length);
pipeStream.Flush();
pipeStream.Close();
pipeStream.Dispose();
return true;
}
catch (TimeoutException oEX)
{
if (cLogManager.DefaultLogger.IsDebug)
cLogManager.DefaultLogger.LogException(oEX);
}
catch { }
finally
{
LogMethodEnd(CM);
}
return false;
}
static public void RegisterProtocol(string protocolString, string urlCommand)
{
try
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
var u = new Uri(codeBase);
var Path = u.LocalPath;
var RegBase = Registry.CurrentUser.OpenSubKey("Software\\Classes", true);
var RegHandler = RegBase.CreateSubKey(protocolString.ToUpperInvariant());
RegHandler.SetValue("", $"URL: {protocolString.ToUpperInvariant()} Protocol Handler");
RegHandler.SetValue("URL Protocol", "");
var RegHandler2 = RegHandler.CreateSubKey("DefaultIcon");
RegHandler2.SetValue("", Path);
var RegHandler3 = RegHandler.CreateSubKey("shell\\open\\command");
RegHandler3.SetValue("", $"\"{Path}\" {urlCommand.ToLowerInvariant()} \"%1\"");
RegHandler = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\Microsoft\\Internet Explorer\\ProtocolExecute\\{protocolString.ToLowerInvariant()}");
RegHandler.SetValue("WarnOnOpen", 0,RegistryValueKind.DWord);
}
catch { }
}
}
public delegate void DelegateMessage(string Reply);
public class cF4sdPipeServer : IDisposable
{
public event DelegateMessage PipeMessage;
string _pipeName;
NamedPipeServerStream pipeServer;
bool _LowerIntegrity;
int _MaxSize;
public void Listen(string PipeName, int MaxSize = 255, bool LowerIntegrity = false, int Timeout = 10000)
{
try
{
// Set to class level var so we can re-use in the async callback method
_pipeName = PipeName;
_MaxSize = MaxSize;
_LowerIntegrity = LowerIntegrity;
if (pipeServer != null )
{
try
{
pipeServer.Close();
pipeServer.Dispose();
pipeServer = null;
} catch { }
}
bool _connected = false;
bool _firstTry = true;
var _startTime = DateTime.UtcNow;
while ((DateTime.UtcNow - _startTime).TotalMilliseconds < Timeout && !_connected)
{
try
{
if (!_firstTry)
Thread.Sleep(200);
_firstTry = false;
// Create the new async pipe
if (pipeServer == null)
pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
if (_LowerIntegrity)
InterProcessSecurity.SetLowIntegrityLevel(pipeServer.SafePipeHandle);
// Wait for a connection
var _res = pipeServer.BeginWaitForConnection(new AsyncCallback(WaitForConnectionCallBack), pipeServer);
_connected = _res != null;
} catch { }
}
if (!_connected)
{
cLogManager.DefaultLogger.LogEntry(LogLevels.Error, $"The pipe '{PipeName}' could not be opened in listen mode.");
}
}
catch (Exception oEX)
{
cLogManager.DefaultLogger.LogException(oEX);
}
}
private void WaitForConnectionCallBack(IAsyncResult iar)
{
try
{
// Get the pipe
NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState;
// End waiting for the connection
pipeServer.EndWaitForConnection(iar);
byte[] buffer = new byte[_MaxSize];
// Read the incoming message
int count = pipeServer.Read(buffer, 0, _MaxSize);
// Convert byte buffer to string
string stringData = Encoding.UTF8.GetString(buffer, 0, count);
// Pass message back to calling form
PipeMessage.Invoke(stringData);
// Kill original sever and create new wait server
pipeServer.Close();
pipeServer = null;
pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In,
1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
if (_LowerIntegrity)
InterProcessSecurity.SetLowIntegrityLevel(pipeServer.SafePipeHandle);
// Recursively wait for the connection again and again....
pipeServer.BeginWaitForConnection(
new AsyncCallback(WaitForConnectionCallBack), pipeServer);
}
catch
{
return;
}
}
public void Stop()
{
if (pipeServer != null)
{
pipeServer.Close();
pipeServer.Dispose();
pipeServer = null;
}
}
public void Dispose()
{
Stop();
}
}
public static class InterProcessSecurity
{
public const string LOW_INTEGRITY_SSL_SACL = "S:(ML;;NW;;;LW)";
public static int ERROR_SUCCESS = 0x0;
public const int LABEL_SECURITY_INFORMATION = 0x00000010;
public enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY
}
[DllImport("advapi32.dll", EntryPoint = "ConvertStringSecurityDescriptorToSecurityDescriptorW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern Boolean ConvertStringSecurityDescriptorToSecurityDescriptor(
[MarshalAs(UnmanagedType.LPWStr)] String strSecurityDescriptor,
UInt32 sDRevision,
ref IntPtr securityDescriptor,
ref UInt32 securityDescriptorSize);
[DllImport("kernel32.dll", EntryPoint = "LocalFree")]
public static extern UInt32 LocalFree(IntPtr hMem);
[DllImport("Advapi32.dll", EntryPoint = "SetSecurityInfo")]
public static extern int SetSecurityInfo(SafeHandle hFileMappingObject,
SE_OBJECT_TYPE objectType,
Int32 securityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
IntPtr pDacl,
IntPtr pSacl);
[DllImport("advapi32.dll", EntryPoint = "GetSecurityDescriptorSacl")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern Boolean GetSecurityDescriptorSacl(
IntPtr pSecurityDescriptor,
out IntPtr lpbSaclPresent,
out IntPtr pSacl,
out IntPtr lpbSaclDefaulted);
public static void SetLowIntegrityLevel(SafeHandle hObject)
{
IntPtr pSD = IntPtr.Zero;
uint securityDescriptorSize = 0;
if (ConvertStringSecurityDescriptorToSecurityDescriptor(LOW_INTEGRITY_SSL_SACL, 1, ref pSD, ref securityDescriptorSize))
{
try
{
if (GetSecurityDescriptorSacl(pSD, out IntPtr lpbSaclPresent, out IntPtr pSacl, out IntPtr lpbSaclDefaulted))
{
var err = SetSecurityInfo(hObject,
SE_OBJECT_TYPE.SE_KERNEL_OBJECT,
LABEL_SECURITY_INFORMATION,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
pSacl);
if (err != ERROR_SUCCESS)
{
throw new Win32Exception(err);
}
}
}
finally
{
LocalFree(pSD);
}
}
}
}
}