using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Windows.Forms; namespace ScreenConnect; internal class WindowsToolkit : Toolkit { private class WindowsDiskNativeLibrary : DiskNativeLibrary { public WindowsDiskNativeLibrary(string libraryPath) : base(libraryPath) { } protected override IntPtr TryLoadNativeLibrary(string libraryPath) { return WindowsNative.LoadLibrary(libraryPath); } protected override void TryFreeNativeLibrary(IntPtr libraryHandle) { WindowsNative.FreeLibrary(libraryHandle); } protected override IntPtr TryGetProcedureAddress(IntPtr libraryHandle, string procedureName) { return WindowsNative.GetProcAddress(libraryHandle, procedureName); } } private SymmetricAlgorithm symmetricAlgorithm; public override Guid GetMachineGuid() { using HandleMinder handleMinder = WindowsExtensions.OpenRegistryKey(WindowsConstants.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", canRead: true, canWrite: false); StringBuilder stringBuilder = new StringBuilder(256); uint lpcbData = (uint)stringBuilder.Capacity; WindowsNative.RegQueryValueEx(handleMinder, "MachineGuid", 0, out var _, stringBuilder, ref lpcbData); return new Guid(stringBuilder.ToString()); } public override long GetMillisecondCount() { WindowsNative.GetSystemTimeAsFileTime(out var lpSystemTimeAsFileTime); return lpSystemTimeAsFileTime / 10000; } public override void TryFreezeStackForRethrow(Exception ex) { Extensions.Try(delegate { ex.InvokeMethod("PrepForRemoting"); }); } public override ICursorMessageProcessor CreateCursorMessageProcessor() { return new WindowsCursorMessageProcessor(); } public override ICryptoTransform CreateEncryptor(byte[] key, byte[] iv) { EnsureSymmetricAlgorithm(); return symmetricAlgorithm.CreateEncryptor(key, iv); } public override ICryptoTransform CreateDecryptor(byte[] key, byte[] iv) { EnsureSymmetricAlgorithm(); return symmetricAlgorithm.CreateDecryptor(key, iv); } private void EnsureSymmetricAlgorithm() { if (symmetricAlgorithm == null) { try { Type type = Type.GetType("System.Security.Cryptography.AesCryptoServiceProvider, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); symmetricAlgorithm = (SymmetricAlgorithm)Activator.CreateInstance(type); } catch { symmetricAlgorithm = Extensions.CreateCryptographyAlgorithm(); } symmetricAlgorithm.Padding = PaddingMode.None; } } public override ITraceSource GetTraceSource(string name) { TraceSource traceSource = (from it in WindowsExtensions.GetFrameworkTraceSources() where it.Name == name select it).FirstOrDefault(); if (traceSource == null) { traceSource = new TraceSource(name); traceSource.TryRemoveTraceListener(); } return new DiagnosticsTraceSource(traceSource); } public override IEnumerable GetTraceSources() { return (from it in WindowsExtensions.GetFrameworkTraceSources() select new DiagnosticsTraceSource(it)).Cast(); } public override byte[]? ProtectBytes(byte[]? unprotectedBytes, Guid entropy = default(Guid)) { return WindowsExtensions.ProtectBytes(unprotectedBytes, entropy); } public override byte[]? TryUnprotectBytes(byte[]? protectedBytes, Guid entropy = default(Guid)) { return WindowsExtensions.TryUnprotectBytes(protectedBytes, entropy); } public override string[] GetPrivateAssemblyFilePaths() { return AppDomain.CurrentDomain.SetupInformation.PrivateBinPath.IfNotEmpty().Else(() => new string[2] { string.Empty, "Bin" }.Join(";")).Split(new char[1] { ';' }) .TrySelect((string it) => Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, it), "*.dll")) .WhereNotNull() .SelectMany((string[] it) => it) .Distinct() .ToArray(); } public override bool SupportsReflectionEmit() { return true; } public override bool ValidateSystemCredentials(NetworkCredential networkCredential) { IntPtr phToken = default(IntPtr); try { return WindowsNative.LogonUser(networkCredential.UserName, networkCredential.Domain, networkCredential.Password, 3, 0, out phToken) || (networkCredential.Password == string.Empty && Marshal.GetLastWin32Error() == 1327); } finally { WindowsNative.CloseHandle(phToken); } } public unsafe override INativeLibrary LoadNativeLibraryFromResourceStream(string resourceName, Stream resourceStream) { return WindowsMemoryNativeLibrary.Load(((UnmanagedMemoryStream)resourceStream).PositionPointer); } public override INativeLibrary LoadNativeLibraryFromDisk(string libraryPath) { return new WindowsDiskNativeLibrary(libraryPath); } public override void LaunchUrl(string url) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { Process.Start(url); } catch (Win32Exception) { MessageBox.Show(WindowsExtensions.GetTopMostMessageBoxOwner(null), "Unable to launch URL. Do you have a default browser set?"); } } public override ArraySegment EncodeFileIconAsImage(string path, bool isDirectory) { Bitmap fileIcon = WindowsExtensions.GetFileIcon(path); try { return EncodeBitmapAsImage(fileIcon); } finally { ((IDisposable)fileIcon)?.Dispose(); } } public override ArraySegment EncodeTheoreticalDirectoryIconAsImage() { Bitmap theoreticalDirectoryIcon = WindowsExtensions.GetTheoreticalDirectoryIcon(); try { return EncodeBitmapAsImage(theoreticalDirectoryIcon); } finally { ((IDisposable)theoreticalDirectoryIcon)?.Dispose(); } } public override ArraySegment EncodeTheoreticalFileIconAsImage(string fileExtension) { Bitmap theoreticalFileIcon = WindowsExtensions.GetTheoreticalFileIcon(fileExtension); try { return EncodeBitmapAsImage(theoreticalFileIcon); } finally { ((IDisposable)theoreticalFileIcon)?.Dispose(); } } private ArraySegment EncodeBitmapAsImage(Bitmap bitmap) { if (bitmap == null) { return default(ArraySegment); } MemoryStream memoryStream = new MemoryStream(); ((Image)bitmap).Save((Stream)memoryStream, ImageFormat.Png); return memoryStream.GetAllBytes(); } }