CVE-2017-16806 (C#, published 2017-11-13T21:29Z)
Description: value: The Process function in RemoteTaskServer/WebServer/HttpServer.cs in Ulterius before 1.9.5.0 allows HTTP server directory traversal.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/Ulterius/server
Files changed:
.gitignore
RemoteTaskServer/Api/Network/Messages/MessageBuilder.cs
RemoteTaskServer/Api/Network/Models/SystemInformation.cs
RemoteTaskServer/Api/Network/PacketHandlers/AccountPacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/DisplayPacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/FilePacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/GpuPacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/ProcessPacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/ScreenSharePacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/ServerPacketHandler.cs
RemoteTaskServer/Api/Network/PacketHandlers/SettingsPacketHandler.cs
RemoteTaskServer/Api/Services/LocalSystem/SystemService.cs
RemoteTaskServer/Api/Services/Network/NetworkService.cs
RemoteTaskServer/Api/Services/Update/UpdateService.cs
RemoteTaskServer/Api/SystemData.cs
RemoteTaskServer/Api/UlteriusApiServer.cs
RemoteTaskServer/Api/Win32/Desktop.cs
RemoteTaskServer/Api/Win32/DesktopWatcher.cs
RemoteTaskServer/Api/Win32/Display.cs
RemoteTaskServer/Api/Win32/ScreenShare/DesktopDuplication/DesktopDuplicationException.cs
RemoteTaskServer/Api/Win32/ScreenShare/DesktopDuplication/DesktopDuplicator.cs
RemoteTaskServer/Api/Win32/ScreenShare/DesktopDuplication/DesktopFrame.cs
RemoteTaskServer/Api/Win32/ScreenShare/DesktopDuplication/FinishedRegions.cs
RemoteTaskServer/Api/Win32/ScreenShare/DesktopDuplication/MovedRegion.cs
RemoteTaskServer/Api/Win32/ScreenShare/Models/DisplayInformation.cs
RemoteTaskServer/Api/Win32/ScreenShare/Models/FrameInformation.cs
RemoteTaskServer/Api/Win32/ScreenShare/Models/ResolutionInformation.cs
RemoteTaskServer/Api/Win32/ScreenShare/ScreenData.cs
RemoteTaskServer/Api/Win32/SessionInfo.cs
RemoteTaskServer/Api/Win32/Win32Exception.cs
RemoteTaskServer/Api/Win32/WinApi.cs
RemoteTaskServer/Api/Win32/WindowsIdentityImpersonator.cs
RemoteTaskServer/App.config
RemoteTaskServer/Forms/Utilities/UlteriusTray.cs
RemoteTaskServer/Program.cs
RemoteTaskServer/Properties/AssemblyInfo.cs
RemoteTaskServer/TerminalServer/Messaging/TerminalControl/Handlers/InputTerminalRequestHandler.cs
RemoteTaskServer/TerminalServer/Messaging/WebSocketHandler.cs
RemoteTaskServer/TerminalServer/Messaging/WebSocketQueueServer.cs
RemoteTaskServer/Ulterius.cs
RemoteTaskServer/UlteriusServer.csproj
RemoteTaskServer/UlteriusServer.csproj.DotSettings
RemoteTaskServer/Utilities/AppEnvironment.cs
RemoteTaskServer/Utilities/Config.cs
RemoteTaskServer/Utilities/ExceptionHandler.cs
RemoteTaskServer/Utilities/Extensions/ProcessExtensions.cs
RemoteTaskServer/Utilities/Extensions/StringExtensions.cs
RemoteTaskServer/Utilities/Security/AuthUtils.cs
RemoteTaskServer/Utilities/Tools.cs
RemoteTaskServer/Utilities/Trace.cs
RemoteTaskServer/WebCams/WebCamManager.cs
RemoteTaskServer/WebServer/HttpServer.cs
RemoteTaskServer/WebSocketAPI/WebSocketEventListener.cs
RemoteTaskServer/packages.config
UlteriusAgent/App.config
UlteriusAgent/Program.cs
UlteriusAgent/UlteriusAgent.cs
UlteriusAgent/UlteriusAgent.csproj
UlteriusAgent/packages.config
UlteriusServer.sln
Commit message: Stability patch, fixes broken GPU detection code, updates the websocket framework to be real-time, removes crappy agent spawning system, removes IPC, fixes HTTP server traversal,


Vulnerable code:
﻿<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>AgentInterface</RootNamespace>
    <AssemblyName>AgentInterface</AssemblyName>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup>
    <SignAssembly>true</SignAssembly>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Cassia, Version=2.0.0.60, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\Cassia.2.0.0.60\lib\2.0\Cassia.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.10.0.1-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="OpenHardwareMonitorLib, Version=0.7.1.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\OpenHardwareMonitor.0.7.1\lib\net40\OpenHardwareMonitorLib.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
    <Reference Include="SharpDX, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.3.1.1\lib\net45\SharpDX.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="SharpDX.Direct3D11, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.Direct3D11.3.1.1\lib\net45\SharpDX.Direct3D11.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="SharpDX.DXGI, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.DXGI.3.1.1\lib\net45\SharpDX.DXGI.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="SharpDX.Mathematics, Version=3.1.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.Mathematics.3.1.1\lib\net45\SharpDX.Mathematics.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="TurboJpegWrapper, Version=1.4.2.19498, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\TurboJpegWrapper.1.4.2.6\lib\net35\TurboJpegWrapper.dll</HintPath>
    </Reference>
    <Reference Include="WindowsBase" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Api\Models\DisplayInformation.cs" />
    <Compile Include="Api\Models\FrameInformation.cs" />
    <Compile Include="Api\Models\ResolutionInformation.cs" />
    <Compile Include="Api\ScreenShare\DesktopDuplication\DesktopDuplicationException.cs" />
    <Compile Include="Api\ScreenShare\DesktopDuplication\DesktopDuplicator.cs" />
    <Compile Include="Api\ScreenShare\DesktopDuplication\DesktopFrame.cs" />
    <Compile Include="Api\ScreenShare\DesktopDuplication\MovedRegion.cs" />
    <Compile Include="Api\ScreenShare\DesktopDuplication\FinishedRegions.cs" />
    <Compile Include="Api\ScreenShare\ScreenData.cs" />
    <Compile Include="Api\System\SystemData.cs" />
    <Compile Include="Api\Win32\Desktop.cs" />
    <Compile Include="Api\Win32\Display.cs" />
    <Compile Include="Api\Win32\ProcessStarter.cs" />
    <Compile Include="Api\Win32\SessionInfo.cs" />
    <Compile Include="Api\Win32\Win32Exception.cs" />
    <Compile Include="Api\Win32\WinApi.cs" />
    <Compile Include="Api\Win32\WindowsIdentityImpersonator.cs" />
    <Compile Include="FrameContract.cs" />
    <Compile Include="InputContract.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Settings\AppEnvironment.cs" />
    <Compile Include="Settings\Config.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <None Include="FodyWeavers.xml">
      <SubType>Designer</SubType>
    </None>
  </ItemGroup>
  <ItemGroup />
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory">
    <ParameterGroup>
      <Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" />
      <Files Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
    </ParameterGroup>
    <Task Evaluate="true">
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml" />
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml.Linq" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" />
      <Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault();

if (config == null) return true;

var excludedAssemblies = new List<string>();
var attribute = config.Attribute("ExcludeAssemblies");
if (attribute != null)
    foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);
var element = config.Element("ExcludeAssemblies");
if (element != null)
    foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);

var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));

foreach (var item in filesToCleanup)
  File.Delete(item);
]]></Code>
    </Task>
  </UsingTask>
  <Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget">
    <CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
  </Target>
  <Import Project="..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets" Condition="Exists('..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets')" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets'))" />
  </Target>
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>
﻿#region

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using AgentInterface.Api.Models;
using AgentInterface.Api.ScreenShare;

#endregion

namespace AgentInterface.Api.Win32
{
    public class Display
    {
       
       
        [Flags]
        public enum ChangeDisplaySettingsFlags : uint
        {
            CDS_NONE = 0,
            CDS_UPDATEREGISTRY = 0x00000001,
            CDS_TEST = 0x00000002,
            CDS_FULLSCREEN = 0x00000004,
            CDS_GLOBAL = 0x00000008,
            CDS_SET_PRIMARY = 0x00000010,
            CDS_VIDEOPARAMETERS = 0x00000020,
            CDS_ENABLE_UNSAFE_MODES = 0x00000100,
            CDS_DISABLE_UNSAFE_MODES = 0x00000200,
            CDS_RESET = 0x40000000,
            CDS_RESET_EX = 0x20000000,
            CDS_NORESET = 0x10000000
        }

        [Flags]
        public enum DisplayDeviceStateFlags
        {
            /// <summary>The device is part of the desktop.</summary>
            AttachedToDesktop = 0x1,
            MultiDriver = 0x2,

            /// <summary>The device is part of the desktop.</summary>
            PrimaryDevice = 0x4,

            /// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
            MirroringDriver = 0x8,

            /// <summary>The device is VGA compatible.</summary>
            VgaCompatible = 0x10,

            /// <summary>The device is removable; it cannot be the primary display.</summary>
            Removable = 0x20,

            /// <summary>The device has more display modes than its output devices support.</summary>
            ModesPruned = 0x8000000,
            Remote = 0x4000000,
            Disconnect = 0x2000000
        }

        public const int DMDO_DEFAULT = 0;
        public const int DMDO_90 = 1;
        public const int DMDO_180 = 2;
        public const int DMDO_270 = 3;

        public const int ErrorSuccess = 0;

        public const int ENUM_CURRENT_SETTINGS = -1;
        public const int CDS_UPDATEREGISTRY = 0x01;
        public const int CDS_TEST = 0x02;


        private const int ENUM_REGISTRY_SETTINGS = -2;

        public static int EnumCurrentSettings { get; } = -1;

        public static int EnumRegistrySettings { get; } = -2;

        private static string MonitorFriendlyName(Luid adapterId, uint targetId)
        {
            var deviceName = new DisplayconfigTargetDeviceName
            {
                header =
                {
                    size = (uint) Marshal.SizeOf(typeof(DisplayconfigTargetDeviceName)),
                    adapterId = adapterId,
                    id = targetId,
                    type = DisplayconfigDeviceInfoType.DisplayconfigDeviceInfoGetTargetName
                }
            };
            var error = DisplayConfigGetDeviceInfo(ref deviceName);
            if (error != ErrorSuccess)
                throw new Win32Exception(error);
            return deviceName.monitorFriendlyDeviceName;
        }

        private static IEnumerable<string> GetAllMonitorsFriendlyNames()
        {
            uint pathCount, modeCount;
            var error = GetDisplayConfigBufferSizes(QueryDeviceConfigFlags.QdcOnlyActivePaths, out pathCount,
                out modeCount);
            if (error != ErrorSuccess)
                throw new Win32Exception(error);

            var displayPaths = new DisplayconfigPathInfo[pathCount];
            var displayModes = new DisplayconfigModeInfo[modeCount];
            error = QueryDisplayConfig(QueryDeviceConfigFlags.QdcOnlyActivePaths,
                ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
            if (error != ErrorSuccess)
                throw new Win32Exception(error);

            for (var i = 0; i < modeCount; i++)
                if (displayModes[i].infoType == DisplayconfigModeInfoType.DisplayconfigModeInfoTypeTarget)
                    yield return MonitorFriendlyName(displayModes[i].adapterId, displayModes[i].id);
        }

        public static List<string> DeviceFriendlyName()
        {
            return GetAllMonitorsFriendlyNames().ToList();
        }

        [DllImport("user32.dll")]
        public static extern int ChangeDisplaySettings(
            ref Devmode devMode, int flags);

        [DllImport("user32.dll")]
        public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, ref Devmode lpDevMode,
            IntPtr hwnd, ChangeDisplaySettingsFlags dwflags, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern DISP_CHANGE ChangeDisplaySettingsEx(string lpszDeviceName, IntPtr lpDevMode, IntPtr hwnd,
            ChangeDisplaySettingsFlags dwflags, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern bool EnumDisplaySettings(
            string deviceName, int modeNum, ref Devmode devMode);

        private static List<DisplayInformation> UpdateDisplays()
        {
            var monitors = new List<DisplayInformation>();
            var d = new DisplayDevice();
            d.cb = Marshal.SizeOf(d);
            try
            {
                for (uint id = 0; EnumDisplayDevices(null, id, ref d, 0); id++)
                {
                    if (d.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop))
                    {
                        var device = d.DeviceName;

                        var vDevMode = new Devmode();
                        var i = 0;
                        var supportedResolutions = new Dictionary<string, List<ResolutionInformation>>();
                        while (EnumDisplaySettings(device, i, ref vDevMode))
                        {
                            var width = vDevMode.dmPelsWidth;
                            var height = vDevMode.dmPelsHeight;
                            var bpp = vDevMode.dmBitsPerPel;
                            var orientation = vDevMode.dmDisplayOrientation.ToString();
                            var freq = vDevMode.dmDisplayFrequency;
                            var resolutionKey = $"{width}x{height}";
                            var resolution = new ResolutionInformation
                            {
                                BitsPerPixel = bpp,
                                Frequency = freq,
                                Height = height,
                                Width = width,
                                Orientation = orientation
                            };
                            if (supportedResolutions.ContainsKey(resolutionKey))
                            {
                                supportedResolutions[resolutionKey].Add(resolution);
                            }
                            else
                            {
                                supportedResolutions.Add(resolutionKey, new List<ResolutionInformation>());
                                supportedResolutions[resolutionKey].Add(resolution);
                            }
                            i++;
                        }
                        var cDevMode = new Devmode();
                        EnumDisplaySettings(device, ENUM_CURRENT_SETTINGS, ref cDevMode);

                        var currentResolution = new ResolutionInformation
                        {
                            BitsPerPixel = cDevMode.dmBitsPerPel,
                            Frequency = cDevMode.dmDisplayFrequency,
                            Height = cDevMode.dmPelsHeight,
                            Width = cDevMode.dmPelsWidth,
                            Orientation = cDevMode.dmDisplayOrientation.ToString(),
                            X = cDevMode.dmPositionX,
                            Y = cDevMode.dmPositionY
                        };
                        var monitor = new DisplayInformation
                        {
                            Primary = d.StateFlags.HasFlag(DisplayDeviceStateFlags.PrimaryDevice),
                            Attached = d.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop),
                            Removable = d.StateFlags.HasFlag(DisplayDeviceStateFlags.Removable),
                            VgaCompatible = d.StateFlags.HasFlag(DisplayDeviceStateFlags.VgaCompatible),
                            MirroringDriver = d.StateFlags.HasFlag(DisplayDeviceStateFlags.MirroringDriver),
                            MultiDriver = d.StateFlags.HasFlag(DisplayDeviceStateFlags.MultiDriver),
                            ModesPruned = d.StateFlags.HasFlag(DisplayDeviceStateFlags.ModesPruned),
                            Remote = d.StateFlags.HasFlag(DisplayDeviceStateFlags.Remote),
                            Disconnect = d.StateFlags.HasFlag(DisplayDeviceStateFlags.Disconnect),
                            FriendlyName = $"{GetAllMonitorsFriendlyNames().ElementAt((int)id)} on {d.DeviceString}",
                            SupportedResolutions = supportedResolutions,
                            CurrentResolution = currentResolution,
                            DeviceName = device
                        };
                        monitors.Add(monitor);
                        d.cb = Marshal.SizeOf(d);
                        EnumDisplayDevices(d.DeviceName, 0, ref d, 0);
                    }
                    d.cb = Marshal.SizeOf(d);
                }
                return monitors;
            }
            catch
            {

            }
            string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
            Console.WriteLine(errorMessage);
            return monitors;
        }

        public static List<DisplayInformation> DisplayInformation()
        { 
            return UpdateDisplays();
        }

        public static string SetPrimary(string deviceName)
        {
            var id = int.Parse(Regex.Match(deviceName, @"\d+").Value) - 1;
            var originalMode = new Devmode();
            originalMode.dmSize = (short) Marshal.SizeOf(originalMode);
            EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, ref originalMode);
            var offsetx = originalMode.dmPositionX;
            var offsety = originalMode.dmPositionY;
            originalMode.dmPositionX = 0;
            originalMode.dmPositionY = 0;

            ChangeDisplaySettingsEx(deviceName, ref originalMode, (IntPtr) null,
                ChangeDisplaySettingsFlags.CDS_SET_PRIMARY | ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY |
                ChangeDisplaySettingsFlags.CDS_NORESET, IntPtr.Zero);
            var device = new DisplayDevice();
            device.cb = Marshal.SizeOf(device);

            // Update remaining devices
            for (uint otherid = 0; EnumDisplayDevices(null, otherid, ref device, 0); otherid++)
            {
                if (device.StateFlags.HasFlag(DisplayDeviceStateFlags.AttachedToDesktop) && otherid != id)
                {
                    device.cb = Marshal.SizeOf(device);
                    var otherDeviceMode = new Devmode();

                    EnumDisplaySettings(device.DeviceName, -1, ref otherDeviceMode);

                    otherDeviceMode.dmPositionX -= offsetx;
                    otherDeviceMode.dmPositionY -= offsety;

                    ChangeDisplaySettingsEx(
                        device.DeviceName,
                        ref otherDeviceMode,
                        (IntPtr) null,
                        ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | ChangeDisplaySettingsFlags.CDS_NORESET,
                        IntPtr.Zero);
                }

                device.cb = Marshal.SizeOf(device);
            }

            // Apply settings
            return
                GetMessageForCode(ChangeDisplaySettingsEx(null, IntPtr.Zero, (IntPtr) null,
                    ChangeDisplaySettingsFlags.CDS_NONE, (IntPtr) null));
        }
        [DllImport("kernel32.dll")]
        public static extern uint GetLastError();

        public static string Rotate(int angle, int width, int height, string deviceName)
        {
            var originalMode = new Devmode();
            originalMode.dmSize = (short) Marshal.SizeOf(originalMode);
            EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, ref originalMode);

            // swap height and width
            var temp = originalMode.dmPelsHeight;
            originalMode.dmPelsHeight = originalMode.dmPelsWidth;
            originalMode.dmPelsWidth = temp;

            originalMode.dmPelsWidth = width;
            originalMode.dmPelsHeight = height;
            switch (angle)
            {
                case 0:
                    originalMode.dmDisplayOrientation = ScreenOrientation.Angle0;
                    break;
                case 90:
                    originalMode.dmDisplayOrientation = ScreenOrientation.Angle90;
                    break;
                case 180:
                    originalMode.dmDisplayOrientation = ScreenOrientation.Angle180;
                    break;
                case 270:
                    originalMode.dmDisplayOrientation = ScreenOrientation.Angle270;
                    break;
            }
            return GetMessageForCode(ChangeDisplaySettingsEx(deviceName, ref originalMode, IntPtr.Zero,
                ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero));
        }

        public static string ChangeResolution(string deviceName, int width, int height, int bbp, int freq)
        {
            var originalMode = new Devmode();
            originalMode.dmSize = (short) Marshal.SizeOf(originalMode);
            EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, ref originalMode);
            var newMode = originalMode;
            newMode.dmDeviceName = deviceName;
            newMode.dmPelsWidth = width;
            newMode.dmPelsHeight = height;
            newMode.dmBitsPerPel = bbp;
            newMode.dmDisplayFrequency = freq;
            return GetMessageForCode(ChangeDisplaySettingsEx(deviceName, ref newMode, IntPtr.Zero,
                ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY, IntPtr.Zero));
        }

        private static string GetMessageForCode(DISP_CHANGE code)
        {
            string message;
            switch (code)
            {
                case DISP_CHANGE.Successful:
                    message = "Resolution updated.";
                    break;
                case DISP_CHANGE.Restart:
                    message = "A restart is required for this resolution to take effect.";
                    break;
                case DISP_CHANGE.BadMode:
                    message = $"resolution is not valid.";
                    break;
                case DISP_CHANGE.BadDualView:
                    message = "The settings change was unsuccessful because system is DualView capable.";
                    break;
                case DISP_CHANGE.BadFlags:
                    message = "An invalid set of flags was passed in.";
                    break;
                case DISP_CHANGE.BadParam:
                    message =
                        "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
                    break;
                case DISP_CHANGE.Failed:
                    message = "Resolution failed to update.";
                    break;
                case DISP_CHANGE.NotUpdated:
                    message = "Unable to write settings to the registry.";
                    break;
                default:
                    message = "Unknown return value from ChangeDisplaySettings API.";
                    break;
            }
            return message;
        }

        [DllImport("user32.dll")]
        private static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DisplayDevice lpDisplayDevice,
            uint dwFlags);

        public enum DISP_CHANGE
        {
            Successful = 0,
            Restart = 1,
            Failed = -1,
            BadMode = -2,
            NotUpdated = -3,
            BadFlags = -4,
            BadParam = -5,
            BadDualView = -6
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Devmode
        {
            private const int Cchdevicename = 0x20;
            private const int Cchformname = 0x20;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] public string dmDeviceName;
            public short dmSpecVersion;
            public short dmDriverVersion;
            public short dmSize;
            public short dmDriverExtra;
            public int dmFields;
            public int dmPositionX;
            public int dmPositionY;
            public ScreenOrientation dmDisplayOrientation;
            public int dmDisplayFixedOutput;
            public short dmColor;
            public short dmDuplex;
            public short dmYResolution;
            public short dmTTOption;
            public short dmCollate;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] public string dmFormName;
            public short dmLogPixels;
            public int dmBitsPerPel;
            public int dmPelsWidth;
            public int dmPelsHeight;
            public int dmDisplayFlags;
            public int dmDisplayFrequency;
            public int dmICMMethod;
            public int dmICMIntent;
            public int dmMediaType;
            public int dmDitherType;
            public int dmReserved1;
            public int dmReserved2;
            public int dmPanningWidth;
            public int dmPanningHeight;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct DisplayDevice
        {
            [MarshalAs(UnmanagedType.U4)] public int cb;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string DeviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceString;
            [MarshalAs(UnmanagedType.U4)] public DisplayDeviceStateFlags StateFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceID;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceKey;
        }

        #region enums

        public enum QueryDeviceConfigFlags : uint
        {
            QdcAllPaths = 0x00000001,
            QdcOnlyActivePaths = 0x00000002,
            QdcDatabaseCurrent = 0x00000004
        }

        public enum DisplayconfigVideoOutputTechnology : uint
        {
            DisplayconfigOutputTechnologyOther = 0xFFFFFFFF,
            DisplayconfigOutputTechnologyHd15 = 0,
            DisplayconfigOutputTechnologySvideo = 1,
            DisplayconfigOutputTechnologyCompositeVideo = 2,
            DisplayconfigOutputTechnologyComponentVideo = 3,
            DisplayconfigOutputTechnologyDvi = 4,
            DisplayconfigOutputTechnologyHdmi = 5,
            DisplayconfigOutputTechnologyLvds = 6,
            DisplayconfigOutputTechnologyDJpn = 8,
            DisplayconfigOutputTechnologySdi = 9,
            DisplayconfigOutputTechnologyDisplayportExternal = 10,
            DisplayconfigOutputTechnologyDisplayportEmbedded = 11,
            DisplayconfigOutputTechnologyUdiExternal = 12,
            DisplayconfigOutputTechnologyUdiEmbedded = 13,
            DisplayconfigOutputTechnologySdtvdongle = 14,
            DisplayconfigOutputTechnologyMiracast = 15,
            DisplayconfigOutputTechnologyInternal = 0x80000000,
            DisplayconfigOutputTechnologyForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigScanlineOrdering : uint
        {
            DisplayconfigScanlineOrderingUnspecified = 0,
            DisplayconfigScanlineOrderingProgressive = 1,
            DisplayconfigScanlineOrderingInterlaced = 2,
            DisplayconfigScanlineOrderingInterlacedUpperfieldfirst = DisplayconfigScanlineOrderingInterlaced,
            DisplayconfigScanlineOrderingInterlacedLowerfieldfirst = 3,
            DisplayconfigScanlineOrderingForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigRotation : uint
        {
            DisplayconfigRotationIdentity = 1,
            DisplayconfigRotationRotate90 = 2,
            DisplayconfigRotationRotate180 = 3,
            DisplayconfigRotationRotate270 = 4,
            DisplayconfigRotationForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigScaling : uint
        {
            DisplayconfigScalingIdentity = 1,
            DisplayconfigScalingCentered = 2,
            DisplayconfigScalingStretched = 3,
            DisplayconfigScalingAspectratiocenteredmax = 4,
            DisplayconfigScalingCustom = 5,
            DisplayconfigScalingPreferred = 128,
            DisplayconfigScalingForceUint32 = 0xFFFFFFFF
        }
        [DllImport("user32")]
        private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);

        private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);

        [StructLayout(LayoutKind.Sequential)]
        private struct Rect
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        public enum DisplayconfigPixelformat : uint
        {
            DisplayconfigPixelformat8Bpp = 1,
            DisplayconfigPixelformat16Bpp = 2,
            DisplayconfigPixelformat24Bpp = 3,
            DisplayconfigPixelformat32Bpp = 4,
            DisplayconfigPixelformatNongdi = 5,
            DisplayconfigPixelformatForceUint32 = 0xffffffff
        }

        public enum DisplayconfigModeInfoType : uint
        {
            DisplayconfigModeInfoTypeSource = 1,
            DisplayconfigModeInfoTypeTarget = 2,
            DisplayconfigModeInfoTypeForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigDeviceInfoType : uint
        {
            DisplayconfigDeviceInfoGetSourceName = 1,
            DisplayconfigDeviceInfoGetTargetName = 2,
            DisplayconfigDeviceInfoGetTargetPreferredMode = 3,
            DisplayconfigDeviceInfoGetAdapterName = 4,
            DisplayconfigDeviceInfoSetTargetPersistence = 5,
            DisplayconfigDeviceInfoGetTargetBaseType = 6,
            DisplayconfigDeviceInfoForceUint32 = 0xFFFFFFFF
        }

        #endregion

        #region structs

        [StructLayout(LayoutKind.Sequential)]
        public struct Luid
        {
            public uint LowPart;
            public int HighPart;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathSourceInfo
        {
            public Luid adapterId;
            public uint id;
            public uint modeInfoIdx;
            public uint statusFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathTargetInfo
        {
            public Luid adapterId;
            public uint id;
            public uint modeInfoIdx;
            private readonly DisplayconfigVideoOutputTechnology outputTechnology;
            private readonly DisplayconfigRotation rotation;
            private readonly DisplayconfigScaling scaling;
            private readonly DisplayconfigRational refreshRate;
            private readonly DisplayconfigScanlineOrdering scanLineOrdering;
            public bool targetAvailable;
            public uint statusFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigRational
        {
            public uint Numerator;
            public uint Denominator;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathInfo
        {
            public DisplayconfigPathSourceInfo sourceInfo;
            public DisplayconfigPathTargetInfo targetInfo;
            public uint flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Displayconfig2Dregion
        {
            public uint cx;
            public uint cy;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigVideoSignalInfo
        {
            public ulong pixelRate;
            public DisplayconfigRational hSyncFreq;
            public DisplayconfigRational vSyncFreq;
            public Displayconfig2Dregion activeSize;
            public Displayconfig2Dregion totalSize;
            public uint videoStandard;
            public DisplayconfigScanlineOrdering scanLineOrdering;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigTargetMode
        {
            public DisplayconfigVideoSignalInfo targetVideoSignalInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Pointl
        {
            private readonly int x;
            private readonly int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigSourceMode
        {
            public uint width;
            public uint height;
            public DisplayconfigPixelformat pixelFormat;
            public Pointl position;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct DisplayconfigModeInfoUnion
        {
            [FieldOffset(0)] public DisplayconfigTargetMode targetMode;

            [FieldOffset(0)] public DisplayconfigSourceMode sourceMode;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigModeInfo
        {
            public DisplayconfigModeInfoType infoType;
            public uint id;
            public Luid adapterId;
            public DisplayconfigModeInfoUnion modeInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigTargetDeviceNameFlags
        {
            public uint value;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigDeviceInfoHeader
        {
            public DisplayconfigDeviceInfoType type;
            public uint size;
            public Luid adapterId;
            public uint id;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct DisplayconfigTargetDeviceName
        {
            public DisplayconfigDeviceInfoHeader header;
            public DisplayconfigTargetDeviceNameFlags flags;
            public DisplayconfigVideoOutputTechnology outputTechnology;
            public ushort edidManufactureId;
            public ushort edidProductCodeId;
            public uint connectorInstance;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string monitorFriendlyDeviceName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string monitorDevicePath;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left, Top, Right, Bottom;

            public RECT(int left, int top, int right, int bottom)
            {
                Left = left;
                Top = top;
                Right = right;
                Bottom = bottom;
            }

            public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }

            public int X
            {
                get { return Left; }
                set { Right -= (Left - value); Left = value; }
            }

            public int Y
            {
                get { return Top; }
                set { Bottom -= (Top - value); Top = value; }
            }

            public int Height
            {
                get { return Bottom - Top; }
                set { Bottom = value + Top; }
            }

            public int Width
            {
                get { return Right - Left; }
                set { Right = value + Left; }
            }

            

            public Size Size
            {
                get { return new Size(Width, Height); }
                set { Width = value.Width; Height = value.Height; }
            }

            public static implicit operator Rectangle(RECT r)
            {
                return new Rectangle(r.Left, r.Top, r.Width, r.Height);
            }

            public static implicit operator RECT(Rectangle r)
            {
                return new RECT(r);
            }

            public static bool operator ==(RECT r1, RECT r2)
            {
                return r1.Equals(r2);
            }

            public static bool operator !=(RECT r1, RECT r2)
            {
                return !r1.Equals(r2);
            }

            public bool Equals(RECT r)
            {
                return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
            }

            public override bool Equals(object obj)
            {
                if (obj is RECT)
                    return Equals((RECT)obj);
                else if (obj is Rectangle)
                    return Equals(new RECT((Rectangle)obj));
                return false;
            }

            public override int GetHashCode()
            {
                return ((Rectangle)this).GetHashCode();
            }

            public override string ToString()
            {
                return string.Format(CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top, Right, Bottom);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CURSORINFO
        {
            public Int32 cbSize;        // Specifies the size, in bytes, of the structure. 
            public Int32 flags;         // Specifies the cursor state. This parameter can be one of the following values:
            public IntPtr hCursor;          // Handle to the cursor. 
            public POINT ptScreenPos;       // A POINT structure that receives the screen coordinates of the cursor. 
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ICONINFO
        {
            public bool fIcon;         // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies 
            public Int32 xHotspot;     // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot 
            public Int32 yHotspot;     // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot 
            public IntPtr hbmMask;     // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, 
            public IntPtr hbmColor;    // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this 
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public Int32 x;
            public Int32 y;
        }
        public const int Width = 0;
        public const int Height = 1;
        public struct ScreenSize
        {
            public int Width;
            public int Height;
        }
        public const Int32 CURSOR_SHOWING = 0x00000001;

        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll", EntryPoint = "GetDC")]
        public static extern IntPtr GetDesktopContext(IntPtr ptr);

        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int abc);

        [DllImport("user32.dll", EntryPoint = "GetWindowDC")]
        public static extern IntPtr GetWindowDesktopContext(Int32 ptr);

        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        public static extern IntPtr ReleaseDesktopContext(IntPtr hWnd, IntPtr hDc);

        [DllImport("user32.dll", EntryPoint = "GetCursorInfo")]
        public static extern bool GetCursorInfo(out CursorInfo pci);

        [DllImport("user32.dll", EntryPoint = "CopyIcon")]
        public static extern IntPtr CopyIcon(IntPtr hIcon);

        [DllImport("user32.dll", EntryPoint = "GetIconInfo")]
        public static extern bool GetIconInfo(IntPtr hIcon, out IconInfo piconinfo);

        [DllImport("user32.dll", EntryPoint = "DestroyIcon")]
        public static extern bool DestroyIcon(IntPtr hIcon);
        #endregion
        [StructLayout(LayoutKind.Sequential)]
        public struct IconInfo
        {
            public bool IsIcon;         // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies 
            public Int32 Xcoord;     // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot 
            public Int32 Ycoord;     // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot 
            public IntPtr Bitmask;     // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, 
            public IntPtr Color;    // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this 
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Point
        {
            public Int32 X;
            public Int32 Y;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CursorInfo
        {
            public Int32 Size;        // Specifies the size, in bytes, of the structure. 
            public Int32 State;         // Specifies the cursor state. This parameter can be one of the following values:
            public IntPtr Handle;          // Handle to the cursor. 
            public Point Coordinates;       // A POINT structure that receives the screen coordinates of the cursor. 
        }

        #region DLL-Imports

        [DllImport("user32.dll")]
        public static extern int GetDisplayConfigBufferSizes(
            QueryDeviceConfigFlags flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);

        [DllImport("user32.dll")]
        public static extern int QueryDisplayConfig(
            QueryDeviceConfigFlags flags,
            ref uint numPathArrayElements, [Out] DisplayconfigPathInfo[] pathInfoArray,
            ref uint numModeInfoArrayElements, [Out] DisplayconfigModeInfo[] modeInfoArray,
            IntPtr currentTopologyId
            );

        [DllImport("user32.dll")]
        public static extern int DisplayConfigGetDeviceInfo(ref DisplayconfigTargetDeviceName deviceName);

      
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
       public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

       public static Rectangle GetWindowRectangle()
        {
            RECT scBounds = new RECT();
            GetWindowRect(GetDesktopWindow(), ref scBounds);
            return scBounds;
        }

        public const int SRCCOPY = 13369376;

        [DllImport("gdi32.dll", EntryPoint = "CreateDC")]
        public static extern IntPtr CreateDesktopContext(IntPtr lpszDriver, string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData);

        [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
        public static extern IntPtr DeleteDesktopContext(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
        public static extern IntPtr DeleteObject(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
        public static extern bool BitBlt(IntPtr hdcDest, int xDest,
                                         int yDest, int wDest,
                                         int hDest, IntPtr hdcSource,
                                         int xSrc, int ySrc, int rasterOp);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
        public static extern IntPtr CreateCompatibleBitmap
                                    (IntPtr hdc, int nWidth, int nHeight);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
        public static extern IntPtr CreateCompatibleDesktopContext(IntPtr hdc);

        [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);

        #endregion
    }

    
}
﻿#region

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using Cassia;

#endregion

namespace AgentInterface.Api.Win32
{
    /// <summary>
    ///     Class that allows running applications with full admin rights. In
    ///     addition the application launched will bypass the Vista UAC prompt.
    /// </summary>
    public class ProcessStarter
    {



        private static int GetUserSessionId(string username)
        {
            try
            {
                ITerminalServicesManager manager = new TerminalServicesManager();
                using (ITerminalServer server = manager.GetLocalServer())
                {
                    server.Open();
                    foreach (ITerminalServicesSession session in server.GetSessions())
                    {

                        NTAccount account = session.UserAccount;
                        if (account == null) continue;
                        var userName = account.Value.Split('\\')[1];
                        if (userName.ToLower().Equals(username.ToLower())) return session.SessionId;
                    }
                }
                return -1;
            }
            catch (Exception)
            {

                return -1;
            }
        }


        /// <summary>
        ///     Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt
        /// </summary>
        /// <param name="applicationName">The name of the application to launch</param>
        /// <param name="procInfo">Process information regarding the launched application that gets returned to the caller</param>
        /// <returns></returns>
        public static bool  StartProcessAndBypassUAC(string applicationName, out PROCESS_INFORMATION procInfo)
        {
            uint winlogonPid = 0;
            IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;
            procInfo = new PROCESS_INFORMATION();


            // obtain the currently active session id; every logged on user in the system has a unique session id
            var dwSessionId = -1;

                dwSessionId = (int) WTSGetActiveConsoleSessionId();
            
            // obtain the process id of the winlogon process that is running within the currently active session
            var processes = Process.GetProcessesByName("winlogon");
            foreach (var p in processes)
            {
                if ((uint) p.SessionId == dwSessionId)
                {
                    winlogonPid = (uint) p.Id;
                }
            }

            // obtain a handle to the winlogon process
            hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);

            // obtain a handle to the access token of the winlogon process
            if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
            {
                CloseHandle(hProcess);
                return false;
            }

            // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
            // I would prefer to not have to use a security attribute variable and to just 
            // simply pass null and inherit (by default) the security attributes
            // of the existing token. However, in C# structures are value types and therefore
            // cannot be assigned the null value.
            var sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);

            // copy the access token of the winlogon process; the newly created token will be a primary token
            if (
                !DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa,
                    (int) SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int) TOKEN_TYPE.TokenPrimary,
                    ref hUserTokenDup))
            {
                CloseHandle(hProcess);
                CloseHandle(hPToken);
                return false;
            }

            // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
            // the window station has a desktop that is invisible and the process is incapable of receiving
            // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user 
            // interaction with the new process.
            var si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);
            si.lpDesktop = @"winsta0\default";
                // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop

            // flags that specify the priority and creation method of the process
            var dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;

            // create a new process in the current user's logon session
            var result = CreateProcessAsUser(hUserTokenDup, // client's access token
                null, // file to execute
                applicationName, // command line
                ref sa, // pointer to process SECURITY_ATTRIBUTES
                ref sa, // pointer to thread SECURITY_ATTRIBUTES
                false, // handles are not inheritable
                dwCreationFlags, // creation flags
                IntPtr.Zero, // pointer to new environment block 
                null, // name of current directory 
                ref si, // pointer to STARTUPINFO structure
                out procInfo // receives information about new process
                );

            // invalidate the handles
            CloseHandle(hProcess);
            CloseHandle(hPToken);
            CloseHandle(hUserTokenDup);

            return result; // return the result
        }

        #region Structures

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public int cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public uint dwX;
            public uint dwY;
            public uint dwXSize;
            public uint dwYSize;
            public uint dwXCountChars;
            public uint dwYCountChars;
            public uint dwFillAttribute;
            public uint dwFlags;
            public short wShowWindow;
            public short cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public uint dwProcessId;
            public uint dwThreadId;
        }

        #endregion

        #region Enumerations

        private enum TOKEN_TYPE
        {
            TokenPrimary = 1,
            TokenImpersonation = 2
        }

        private enum SECURITY_IMPERSONATION_LEVEL
        {
            SecurityAnonymous = 0,
            SecurityIdentification = 1,
            SecurityImpersonation = 2,
            SecurityDelegation = 3
        }

        #endregion

        #region Constants

        public const int TOKEN_DUPLICATE = 0x0002;
        public const uint MAXIMUM_ALLOWED = 0x2000000;
        public const int CREATE_NEW_CONSOLE = 0x00000010;

        public const int IDLE_PRIORITY_CLASS = 0x40;
        public const int NORMAL_PRIORITY_CLASS = 0x20;
        public const int HIGH_PRIORITY_CLASS = 0x80;
        public const int REALTIME_PRIORITY_CLASS = 0x100;

        #endregion

        #region Win32 API Imports

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(IntPtr hSnapshot);

        [DllImport("kernel32.dll")]
        private static extern uint WTSGetActiveConsoleSessionId();

        [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi,
            CallingConvention = CallingConvention.StdCall)]
        public static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine,
            ref SECURITY_ATTRIBUTES lpProcessAttributes,
            ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,
            string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

        [DllImport("kernel32.dll")]
        private static extern bool ProcessIdToSessionId(uint dwProcessId, ref uint pSessionId);

        [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
        public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,
            ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
            int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);

        [DllImport("kernel32.dll")]
        private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

        [DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurity]
        private static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);

        #endregion
    }
}
﻿<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  
</Weavers>
﻿using System.ServiceModel;
using AgentInterface.Api.Models;

namespace AgentInterface
{
    [ServiceContract(Namespace = "https://ulterius.io/")]
    public interface IFrameContract
    {

        [OperationContract]
        FrameInformation GetCleanFrame();

        [OperationContract]
        FrameInformation GetFullFrame();

        [OperationContract]
        bool KeepAlive();

    }
}
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using AgentInterface.Api.Models;

namespace AgentInterface
{
    [ServiceContract(Namespace = "https://ulterius.io/")]
    public interface IInputContract
    {

        [OperationContract(IsOneWay = true)]
        void HandleRightMouseDown();

        [OperationContract(IsOneWay = true)]
        void HandleRightMouseUp();

        [OperationContract(IsOneWay = true)]
        void MoveMouse(int x, int y);

        [OperationContract(IsOneWay = true)]
        void MouseScroll(bool positive);

        [OperationContract(IsOneWay = true)]
        void HandleLeftMouseDown();

        [OperationContract(IsOneWay = true)]
        void HandleLeftMouseUp();

        [OperationContract(IsOneWay = true)]
        void HandleKeyDown(List<int> keyCodes);

        [OperationContract(IsOneWay = true)]
        void HandleKeyUp(List<int> keyCodes);

        [OperationContract(IsOneWay = true)]
        void HandleRightClick();

        [OperationContract]
        float GetGpuTemp(string gpuName);

        [OperationContract]
        List<DisplayInformation> GetDisplayInformation();

        [OperationContract]
        List<float> GetCpuTemps();

    }
}
﻿using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("AgentInterface")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Octopodal Solutions")]
[assembly: AssemblyProduct("Ulterius")]
[assembly: AssemblyCopyright("Copyright ©  2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5c3b0b17-cbb7-4b4b-b527-1fab2bb96466")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
﻿<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Cassia" version="2.0.0.60" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="10.0.1-beta1" targetFramework="net452" />
  <package id="OpenHardwareMonitor" version="0.7.1" targetFramework="net452" />
  <package id="SharpDX" version="3.1.1" targetFramework="net452" />
  <package id="SharpDX.Direct3D11" version="3.1.1" targetFramework="net452" />
  <package id="SharpDX.DXGI" version="3.1.1" targetFramework="net452" />
  <package id="SharpDX.Mathematics" version="3.1.1" targetFramework="net452" />
  <package id="TurboJpegWrapper" version="1.4.2.6" targetFramework="net452" />
</packages>
                                var targetPort = _client.LocalEndpoint.Port;
                    var targetPort = _client.LocalEndpoint.Port;
                    var targetPort = _client.LocalEndpoint.Port;
using AgentInterface.Api.Models;
using AgentInterface.Settings;
using AgentInterface.Api.Win32;
            var device = _packet.Args[0].ToString();
            _builder.WriteMessage(formThread);
            var width = int.Parse(_packet.Args[0].ToString());
            _builder.WriteMessage(formThread);
            var width = int.Parse(_packet.Args[0].ToString());
            _builder.WriteMessage(formThread);
using AgentInterface.Settings;
using AgentInterface.Api.System;
            return UlteriusApiServer.RunningAsService
                ? UlteriusApiServer.AgentClient.GetGpuTemp(gpuName)
                : SystemData.GetGpuTemp(gpuName);
using AgentInterface.Api.Win32;
                if (Environment.UserName.Equals("SYSTEM") && Tools.RunningPlatform() == Tools.Platform.Windows)
                {
                    var task = Task.Run(() =>
                    {
                        try
                        {
                            ProcessStarter.PROCESS_INFORMATION procInfo;
                            ProcessStarter.StartProcessAndBypassUAC(path,  out procInfo);
                        }
                        catch (Exception)
                        {
                            //continue
                        }
                    });
                    processStarted = task.Wait(TimeSpan.FromSeconds(5));
                }
                else
                {
                    var processStartInfo = new ProcessStartInfo(path);
                    var process = new Process {StartInfo = processStartInfo};
                    processStarted = process.Start();
                    processId = process.Id;
                }
using AgentInterface.Api.ScreenShare;
using AgentInterface.Api.ScreenShare.DesktopDuplication;
using AgentInterface.Api.Win32;
                var stream = RunningAsService
                    ? new Thread(GetScreenAgentFrame) { IsBackground = true }
                    : new Thread(GetScreenFrame) { IsBackground = true };

        private void GetScreenAgentFrame()
        {
            try
            {
                while (_client != null && _client.IsConnected && _authClient != null &&
                       !_authClient.ShutDownScreenShare)
                {
                    try
                    {
                        var image = AgentClient.GetCleanFrame();
                        if (image != null)
                        {
                            if (image.UsingGpu)
                            {
                                SendGpuFrame(image.FinishedRegions);
                            }
                            else
                            {
                                SendPolledFrame(image.ScreenImage, image.Bounds);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        //  Console.WriteLine(e.Message + " " + e.StackTrace);
                    }
                }
                Console.WriteLine("Screen Share Died");
            }
            catch (Exception)
            {
            }
        }

                    if (RunningAsService)
                    {
                        HandleAgentFullFrame();
                    }
                    else
                    {
                        HandleFullFrame();
                    }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;
            if (RunningAsService)
            {
                AgentClient.HandleRightMouseUp();
            }
            else
            {
                new InputSimulator().Mouse.RightButtonUp();
            }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;
            if (RunningAsService)
            {
                AgentClient.HandleRightMouseDown();
            }
            else
            {
                new InputSimulator().Mouse.RightButtonDown();
            }
        }

        private void HandleAgentFullFrame()
        {
            try
            {
                var fullFrameData = AgentClient.GetFullFrame();
                if (fullFrameData?.ScreenImage == null) throw new InvalidOperationException("Frame was null");
                var bounds = fullFrameData.Bounds;
                var image = ScreenData.ImageToByteArray(fullFrameData.ScreenImage);
                var frameData = new
                {
                    screenBounds = new
                    {
                        top = bounds.Top,
                        bottom = bounds.Bottom,
                        left = bounds.Left,
                        right = bounds.Right,
                        height = bounds.Height,
                        width = bounds.Width,
                        x = bounds.X,
                        y = bounds.Y,
                        empty = bounds.IsEmpty,
                        location = bounds.Location,
                        size = bounds.Size
                    },
                    frameData = image.Select(b => (int)b).ToArray()
                };
                _builder.WriteMessage(frameData);
            }
            catch (Exception ex)
            {
                var data = new
                {
                    frameFailed = true,
                    message = ex.Message
                };
                Console.WriteLine(ex.Message + "Fuck");
                _builder.WriteMessage(data);
            }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;
            if (RunningAsService)
            {
                AgentClient.HandleKeyUp(codes);
            }
            else
                foreach (var code in codes)
                {
                    var virtualKey = (VirtualKeyCode)code;
                    new InputSimulator().Keyboard.KeyUp(virtualKey);
                }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;
            if (RunningAsService)
                AgentClient.HandleKeyDown(codes);
            }
            else
            {
                foreach (var code in codes)
                {
                    var virtualKey = (VirtualKeyCode)code;
                    new InputSimulator().Keyboard.KeyDown(virtualKey);
                }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;
            if (RunningAsService)
            {
                AgentClient.ScrollMouse(positive);
            }
            else
            {
                new InputSimulator().Mouse.VerticalScroll(direction);
            }
            if (!ScreenShareService.Streams.ContainsKey(_authClient)) return;

                if (RunningAsService)
                {

                    AgentClient.MoveMouse(x, y);
                }
                else
                {
                    var bounds = Display.GetWindowRectangle();
                    x = checked((int)Math.Round(x * (65535 / (double)bounds.Width)));
                    y = checked((int)Math.Round(y * (65535 / (double)bounds.Height)));
                    new InputSimulator().Mouse.MoveMouseTo(x, y);
                }
                Console.WriteLine("Error moving mouse");
            if (ScreenShareService.Streams.ContainsKey(_authClient))
            {
                if (RunningAsService)
                {
                    AgentClient.HandleRightClick();
                }
                else
                {
                    new InputSimulator().Mouse.RightButtonClick();
                }
            }
            if (ScreenShareService.Streams.ContainsKey(_authClient))
            {
                if (RunningAsService)
                {
                    AgentClient.HandleLeftMouseUp();
                }
                else
                {
                    new InputSimulator().Mouse.LeftButtonUp();
                }
            }
            if (ScreenShareService.Streams.ContainsKey(_authClient))
            {
                if (RunningAsService)
                {
                    AgentClient.HandleLeftMouseDown();
                }
                else

                {
                    new InputSimulator().Mouse.LeftButtonDown();
                }
            }
using AgentInterface.Settings;
using AgentInterface.Settings;
﻿#region

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Security;
using System.ServiceModel;
using System.Threading;
using System.Threading.Tasks;
using AgentInterface;
using AgentInterface.Api.Models;
using UlteriusServer.Utilities;

#endregion

namespace UlteriusServer.Api.Network
{
    public class UlteriusAgentClient
    {
        private IInputContract InputChannel { get; set; }

        private IFrameContract FrameChannel { get; set; }

        public void Start(bool keepAlive = true)
        {
            var inputAddress = "net.tcp://localhost/ulterius/agent/input/";
            var frameAddress = "net.pipe://localhost/ulterius/agent/frames/";

            var inputBinding = new NetTcpBinding
            {
                Security = new NetTcpSecurity
                {
                    Transport = { ProtectionLevel = ProtectionLevel.None },
                    Mode = SecurityMode.None
                },
                MaxReceivedMessageSize = int.MaxValue
            };
            var ep = new EndpointAddress(inputAddress);
            
            InputChannel = ChannelFactory<IInputContract>.CreateChannel(inputBinding, ep);
         

            var frameBinding = new NetNamedPipeBinding
            {
                Security = new NetNamedPipeSecurity
                {
                    Transport = { ProtectionLevel = ProtectionLevel.None },
                    Mode = NetNamedPipeSecurityMode.None
                },
                MaxReceivedMessageSize = int.MaxValue
            };
            var epf = new EndpointAddress(frameAddress);
            FrameChannel = ChannelFactory<IFrameContract>.CreateChannel(frameBinding, epf);


            if (!keepAlive) return;
            var task = new Task(KeepAlive);
            task.Start();
        }

        private void KeepAlive()
        {
            while (true)
            {
                Tools.RestartDaemon();
                var alive = ChannelActive();
                if (!alive)
                {
                    var agentList = Process.GetProcessesByName("UlteriusAgent");
                    if (agentList.Length == 0)
                    {
                        Tools.RestartAgent();
                    }
                    Start(false);
                }
                Thread.Sleep(1000);
            }
        }

        public void ScrollMouse(bool positive)
        {
            try
            {
                InputChannel?.MouseScroll(positive);
            }
            catch (EndpointNotFoundException)
            {
                //
            }
            catch (CommunicationException)
            {
                //
            }
        }

        public bool ChannelActive()
        {
            try
            {
                return FrameChannel != null && FrameChannel.KeepAlive();
            }
            catch (EndpointNotFoundException)
            {
                return false;
            }
            catch (CommunicationException)
            {
                return false;
            }
        }

        public FrameInformation GetCleanFrame()
        {
            try
            {
                return FrameChannel.GetCleanFrame();
            }
            catch (EndpointNotFoundException)
            {
                return null;
            }
            catch (TimeoutException)
            {
                return null;
            }
            catch (CommunicationException)
            {
                return null;
            }
        }

        public FrameInformation GetFullFrame()
        {
            try
            {
                return FrameChannel.GetFullFrame();
            }
            catch (EndpointNotFoundException)
            {
                return null;
            }
            catch (CommunicationException)
            {
                return null;
            }
        }

        public void HandleRightMouseDown()
        {
            try
            {
                InputChannel.HandleRightMouseDown();
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void HandleRightMouseUp()
        {
            try
            {
                InputChannel.HandleRightMouseUp();
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void MoveMouse(int x, int y)
        {
            try
            {
                InputChannel.MoveMouse(x, y);
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException ex)
            {
                Console.WriteLine(ex.Message);
                Console.Write(ex.StackTrace);
            }
        }

        public void HandleLeftMouseDown()
        {
            try
            {
                InputChannel.HandleLeftMouseDown();
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void HandleLeftMouseUp()
        {
            try
            {
                InputChannel.HandleLeftMouseUp();
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void HandleKeyDown(List<int> keyCodes)
        {
            try
            {
                InputChannel.HandleKeyDown(keyCodes);
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void HandleKeyUp(List<int> keyCodes)
        {
            try
            {
                InputChannel.HandleKeyUp(keyCodes);
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public void HandleRightClick()
        {
            try
            {
                InputChannel.HandleRightClick();
            }
            catch (EndpointNotFoundException)
            {
            }
            catch (CommunicationException)
            {
            }
        }

        public float GetGpuTemp(string gpuName)
        {
            try
            {
                var temp = InputChannel.GetGpuTemp(gpuName);
                return temp;
            }
            catch (EndpointNotFoundException)
            {
                return -1;
            }
            catch (CommunicationException)
            {
                return -1;
            }
        }

        public List<DisplayInformation> GetDisplayInformation()
        {
            try
            {
                return InputChannel.GetDisplayInformation();
            }
            catch (EndpointNotFoundException)
            {
                return null;
            }
            catch (CommunicationException)
            {
                return null;
            }
        }

        public List<float> GetCpuTemps()
        {
            try
            {
                return InputChannel.GetCpuTemps();
            }
            catch (EndpointNotFoundException)
            {
                return null;
            }
            catch (CommunicationException)
            {
                return null;
            }
        }


    }
}
using AgentInterface.Api.Models;
using AgentInterface.Api.System;
using static AgentInterface.Api.Win32.Display;
            var displayList = DisplayInformation();
            if (!UlteriusApiServer.RunningAsService) return displayList;
            var displayInfo = UlteriusApiServer.AgentClient.GetDisplayInformation();
            return displayInfo ?? displayList;
            return UlteriusApiServer.RunningAsService
                ? UlteriusApiServer.AgentClient.GetCpuTemps()
                : SystemData.GetCpuTemps();
            return _motherBoard;
                totalBytesReceived += networkInterface.GetIPv4Statistics().BytesReceived;
                totalBytesSent += networkInterface.GetIPv4Statistics().BytesSent;
                totalNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Length,
using AgentInterface.Settings;
using AgentInterface.Api.Win32;
            var file = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                 "Ulterius Updater.exe /silentall -nofreqcheck");
            ProcessStarter.PROCESS_INFORMATION procInfo;
            ProcessStarter.StartProcessAndBypassUAC(file,  out procInfo);
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using OpenHardwareMonitor.Hardware;

namespace AgentInterface.Api.System
{
   public  class SystemData
    {

        [HandleProcessCorruptedStateExceptions]
        public static float GetGpuTemp(string gpuName)
        {
            try
            {
                var myComputer = new Computer();
                myComputer.Open();
                //possible fix for gpu temps on laptops
                myComputer.GPUEnabled = true;
                float temp = -1;
                foreach (var hardwareItem in myComputer.Hardware)
                {
                    hardwareItem.Update();
                    switch (hardwareItem.HardwareType)
                    {
                        case HardwareType.GpuNvidia:
                            foreach (
                                var sensor in
                                    hardwareItem.Sensors.Where(
                                        sensor =>
                                            sensor.SensorType == SensorType.Temperature &&
                                            hardwareItem.Name.Contains(gpuName)))
                            {
                                if (sensor.Value != null)
                                {
                                    temp = (float)sensor.Value;
                                }
                            }
                            break;
                        case HardwareType.GpuAti:
                            foreach (
                                var sensor in
                                    hardwareItem.Sensors.Where(
                                        sensor =>
                                            sensor.SensorType == SensorType.Temperature &&
                                            hardwareItem.Name.Contains(gpuName)))
                            {
                                if (sensor.Value != null)
                                {
                                    temp = (float)sensor.Value;
                                }
                            }
                            break;
                    }
                }
                myComputer.Close();
                return temp;
            }
            catch (AccessViolationException)
            {
                return -1;
            }
        }

        public static List<float> GetCpuTemps()
        {
            var myComputer = new Computer();
            myComputer.Open();
            myComputer.CPUEnabled = true;
            var tempTemps = new List<float>();
            var procCount = Environment.ProcessorCount;
            for (var i = 0; i < procCount; i++)
            {
                tempTemps.Add(-1);
            }
            try
            {
                var temps = (from hardwareItem in myComputer.Hardware
                             where hardwareItem.HardwareType == HardwareType.CPU
                             from sensor in hardwareItem.Sensors
                             where sensor.SensorType == SensorType.Temperature
                             let value = sensor.Value
                             where value != null
                             where value != null
                             select (float)value).ToList();
                if (temps.Count != 0) return temps;
                myComputer.Close();
                return tempTemps;
            }
            catch (Exception)
            {
                myComputer.Close();
                return tempTemps;
            }
        }

    }
}
﻿#region

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using AgentInterface.Settings;
using Newtonsoft.Json;
using UlteriusServer.Api.Network;
using UlteriusServer.Api.Network.Messages;
using UlteriusServer.Api.Services.LocalSystem;
using UlteriusServer.Api.Services.Network;
using UlteriusServer.Api.Services.Update;
using UlteriusServer.Forms.Utilities;
using UlteriusServer.Utilities.Security;
using UlteriusServer.WebSocketAPI;
using UlteriusServer.WebSocketAPI.Authentication;
using vtortola.WebSockets;
using ScreenShareService = UlteriusServer.Api.Services.LocalSystem.ScreenShareService;

#endregion

namespace UlteriusServer.Api
{
    internal class UlteriusApiServer
    {
        public static ConcurrentDictionary<Guid, AuthClient> AllClients { get; set; }
        public static bool RunningAsService { get; set; }
        public static ScreenShareService ScreenShareService { get; set; }
        public static FileSearchService FileSearchService { get; set; }
        public static CronJobService CronJobService { get; set; }

        public static UlteriusAgentClient AgentClient { get; set; }

        /// <summary>
        ///     Start the API Server
        /// </summary>
        public static void Start()
        {
            PacketLoader.LoadPackets();
            var config = Config.Load();
            var clientUpdateService = new UpdateService();
            clientUpdateService.Start();
            FileSearchService = new FileSearchService(Path.Combine(AppEnvironment.DataPath, "fileIndex.db"));
            FileSearchService.Start();
            CronJobService = new CronJobService(Path.Combine(AppEnvironment.DataPath, "jobs.json"), Path.Combine(AppEnvironment.DataPath, "scripts"));
            CronJobService.ConfigureJobs();
            var apiPort = config.TaskServer.TaskServerPort;
            AllClients = new ConcurrentDictionary<Guid, AuthClient>();
            ScreenShareService = new ScreenShareService();
            var address = NetworkService.GetAddress();
            var webCamPort = config.Webcams.WebcamPort;
            var screenSharePort = config.ScreenShareService.ScreenSharePort;
            var endPoints = new List<IPEndPoint>
            {
                new IPEndPoint(address, apiPort),
                new IPEndPoint(address, webCamPort),
                new IPEndPoint(address, screenSharePort)
            };
            var server = new WebSocketEventListener(endPoints, new WebSocketListenerOptions
            {
                PingTimeout = TimeSpan.FromSeconds(2),
                NegotiationTimeout = TimeSpan.FromSeconds(2),
                WebSocketSendTimeout = TimeSpan.FromSeconds(2),
                WebSocketReceiveTimeout = TimeSpan.FromSeconds(2),
                ParallelNegotiations = Environment.ProcessorCount*2,
                NegotiationQueueCapacity = 256,
                TcpBacklog = 1000,
                OnHttpNegotiation = (request, response) =>
                {
                    if (request.Cookies["ConnectionId"] == null)
                        response.Cookies.Add(new Cookie("ConnectionId", Guid.NewGuid().ToString()));
                }
            });
            server.OnConnect += HandleConnect;
            server.OnDisconnect += HandleDisconnect;
            server.OnPlainTextMessage += HandlePlainTextMessage;
            server.OnEncryptedMessage += HandleEncryptedMessage;
            server.OnError += HandleError;
            server.Start();
            Log("Api Server started at " + address);
            if (RunningAsService)
            {
                AgentClient = new UlteriusAgentClient();
                AgentClient.Start();
            }
        }

        


        /// <summary>
        ///     Handles encrypted binary messages
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="message"></param>
        private static void HandleEncryptedMessage(WebSocket clientSocket, byte[] message)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            if (AllClients.TryGetValue(connectionId, out authClient))
            {
                var packetManager = new PacketManager(authClient, clientSocket, message);
                var packet = packetManager.GetPacket();
                packet?.HandlePacket();
            }
        }

        private static void HandleError(WebSocket websocket, Exception error)
        {
            Console.WriteLine(error.StackTrace + " " + error.Message);
        }

        /// <summary>
        ///     Handles plaintext JSON packets.
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="message"></param>
        private static void HandlePlainTextMessage(WebSocket clientSocket, string message)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            if (AllClients.TryGetValue(connectionId, out authClient))
            {
                var packetManager = new PacketManager(authClient, clientSocket, message);
                var packet = packetManager.GetPacket();
                packet?.HandlePacket();
            }
        }


        /// <summary>
        ///     Remove a client when it disconnects
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void HandleDisconnect(WebSocket clientSocket)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient temp = null;
            if (AllClients.TryRemove(connectionId, out temp))
            {
                Console.WriteLine("Disconnection from " + clientSocket.RemoteEndpoint);
                var userCount = AllClients.Count;
                var extra = userCount < 1 ? "s" : string.Empty;
                UlteriusTray.ShowMessage($"There are now {userCount} user{extra} connected.", "A user disconnected!");
            }
        }

        /// <summary>
        ///     When a client connects, assign them a unique RSA keypair for handshake.
        /// </summary>
        /// <param name="clientSocket"></param>
        private static async void HandleConnect(WebSocket clientSocket)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            AllClients.TryGetValue(connectionId, out authClient);
            if (authClient != null)
            {
                if (RunningAsService)
                {
                    MessageQueueManager agentManager;
                    if (!authClient.MessageQueueManagers.TryGetValue(22005, out agentManager))
                    {
                        if (authClient.MessageQueueManagers.TryAdd(22005,
                            new MessageQueueManager()))
                        {
                            Console.WriteLine("Service Manager Started");
                        }
                    }
                }
                MessageQueueManager manager;
                //check if a manager for that port exist, if not, create one
                if (!authClient.MessageQueueManagers.TryGetValue(clientSocket.LocalEndpoint.Port, out manager))
                {
                    if (authClient.MessageQueueManagers.TryAdd(clientSocket.LocalEndpoint.Port,
                        new MessageQueueManager()))
                    {
                        Console.WriteLine("Manager started for " + clientSocket.LocalEndpoint.Port);
                    }
                }
                return;
            }
            Console.WriteLine("Connection from " + clientSocket.RemoteEndpoint);
            var rsa = new Rsa();
            rsa.GenerateKeyPairs();
            var client = new AuthClient
            {
                PublicKey = rsa.PublicKey,
                PrivateKey = rsa.PrivateKey,
                MessageQueueManagers = new ConcurrentDictionary<int, MessageQueueManager>()
            };
            client.MessageQueueManagers.TryAdd(clientSocket.LocalEndpoint.Port, new MessageQueueManager());
            AllClients.AddOrUpdate(connectionId, client, (key, value) => value);
            await SendWelcomeMessage(client, clientSocket);
        }

        /// <summary>
        ///     Sends a new user their unique RSA keypair
        /// </summary>
        /// <param name="client"></param>
        /// <param name="clientSocket"></param>
        private static async Task SendWelcomeMessage(AuthClient client, WebSocket clientSocket)
        {
            var welcomeMessage = JsonConvert.SerializeObject(new
            {
                endpoint = "connectedToUlterius",
                results = new
                {
                    message = "Ulterius server online!",
                    publicKey = Rsa.SecureStringToString(client.PublicKey)
                }
            });
            if (clientSocket != null)
            {
                try
                {
                    await clientSocket.WriteStringAsync(welcomeMessage, CancellationToken.None);
                    var userCount = AllClients.Count;
                    var extra = userCount > 1 ? "s" : string.Empty;
                    UlteriusTray.ShowMessage($"There are now {userCount} user{extra} connected.", "A new user connected!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to write welcome message " + ex.Message );
                }
            }
        }

        private static void Log(string message)
        {
            Console.WriteLine(message);
        }
    }
namespace AgentInterface.Api.Win32
        static extern int GetCurrentThreadId();
namespace AgentInterface.Api.ScreenShare.DesktopDuplication
﻿#region

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
using Device = SharpDX.Direct3D11.Device;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using Point = System.Drawing.Point;
using Rectangle = SharpDX.Rectangle;
using Resource = SharpDX.DXGI.Resource;
using ResultCode = SharpDX.DXGI.ResultCode;

#endregion

namespace AgentInterface.Api.ScreenShare.DesktopDuplication
{
    /// <summary>
    ///     Provides access to frame-by-frame updates of a particular desktop (i.e. one monitor), with image and cursor
    ///     information.
    /// </summary>
    public class DesktopDuplicator
    {
        private readonly OutputDuplication _mDeskDupl;
        private readonly Device _mDevice;
        private readonly Texture2DDescription _mTextureDesc;
        private readonly int _mWhichOutputDevice;
        private Texture2D _desktopImageTexture;

        private Bitmap _finalImage1, _finalImage2;
        private OutputDuplicateFrameInformation _frameInfo;
        private bool _isFinalImage1;
        private OutputDescription _mOutputDesc;

      
        /// <summary>
        ///     Duplicates the output of the specified monitor on the specified graphics adapter.
        /// </summary>
        /// <param name="whichGraphicsCardAdapter">The adapter which contains the desired outputs.</param>
        /// <param name="whichOutputDevice">
        ///     The output device to duplicate (i.e. monitor). Begins with zero, which seems to
        ///     correspond to the primary monitor.
        /// </param>
        public DesktopDuplicator()
        {


            Adapter1 adapter;
            try
            {
                adapter = GetBestAdapter(out int bestAdapaterIndex);
                if (adapter == null) throw new SharpDXException();
                Console.WriteLine($"Using the {adapter.Description.Description} for screen share.");
            }
            catch (SharpDXException)
            {
                ScreenData.CanUseGpuAcceleration = false;
                throw new DesktopDuplicationException("Could not find the specified graphics card adapter.");
            }
            DeviceCreationFlags flags = DeviceCreationFlags.BgraSupport;
            _mDevice = new Device(adapter, flags, FeatureLevel.Level_11_0);
            Output output;
            try
            {
                output = adapter.GetOutput(0);
            }
            catch (SharpDXException)
            {
                ScreenData.CanUseGpuAcceleration = false;
                throw new DesktopDuplicationException("Could not find the specified output device.");
            }
            var output1 = output.QueryInterface<Output1>();
            _mOutputDesc = output.Description;
            _mTextureDesc = new Texture2DDescription
            {
                CpuAccessFlags = CpuAccessFlags.Read,
                BindFlags = BindFlags.None,
                Format = Format.B8G8R8A8_UNorm,
                Width = ((Rectangle) _mOutputDesc.DesktopBounds).Width,
                Height = ((Rectangle) _mOutputDesc.DesktopBounds).Height,
                OptionFlags = ResourceOptionFlags.None,
                MipLevels = 1,
                ArraySize = 1,
                SampleDescription = {Count = 1, Quality = 0},
                Usage = ResourceUsage.Staging
            };

            try
            {
                _mDeskDupl = output1.DuplicateOutput(_mDevice);
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Code == ResultCode.NotCurrentlyAvailable.Result.Code)
                    throw new DesktopDuplicationException(
                        "There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again.");
            }
        }

        private Bitmap FinalImage
        {
            get { return _isFinalImage1 ? _finalImage1 : _finalImage2; }
            set
            {
                if (_isFinalImage1)
                {
                    _finalImage2 = value;
                    _finalImage1?.Dispose();
                }
                else
                {
                    _finalImage1 = value;
                    _finalImage2?.Dispose();
                }
                _isFinalImage1 = !_isFinalImage1;
            }
        }

        /// <summary>
        ///     Finds the most capable graphics card.
        /// </summary>
        /// <returns></returns>
        private static Adapter1 GetBestAdapter(out int bestAdapterIndex)
        {
            using (var dxgiFactory = new Factory1())
            {
                Adapter1 bestAdapter = null;
                bestAdapterIndex = -1;
                var adapterIndex = -1;
                long bestVideoMemory = 0;
                long bestSystemMemory = 0;

                foreach (var dxgiAdapter in dxgiFactory.Adapters1)
                {
                    adapterIndex++;

                    // not skip the render only WARP device
                    if (dxgiAdapter.Description.VendorId != 0x1414 || dxgiAdapter.Description.DeviceId != 0x8c)
                        if (dxgiAdapter.Outputs == null || dxgiAdapter.Outputs.Length == 0)
                            continue;

                    var level = Device.GetSupportedFeatureLevel(dxgiAdapter);

                    if (level < FeatureLevel.Level_11_0)
                        continue;
                    long videoMemory = (uint) dxgiAdapter.Description.DedicatedVideoMemory;
                    long systemMemory = (uint) dxgiAdapter.Description.DedicatedSystemMemory;

                    if (bestAdapter != null && videoMemory <= bestVideoMemory &&
                        (videoMemory != bestVideoMemory || systemMemory <= bestSystemMemory)) continue;
                    bestAdapter = dxgiAdapter;
                    bestAdapterIndex = adapterIndex;
                    bestVideoMemory = videoMemory;
                    bestSystemMemory = systemMemory;
                }

                return bestAdapter;
            }
        }

        /// <summary>
        ///     Retrieves the latest desktop image and associated metadata.
        /// </summary>
        public DesktopFrame GetLatestFrame()
        {
            var frame = new DesktopFrame();
            // Try to get the latest frame; this may timeout
            var retrievalTimedOut = RetrieveFrame();
            if (retrievalTimedOut)
                return null;
            try
            {
                RetrieveFrameMetadata(frame);
                //we don't need cursor info
                //RetrieveCursorMetadata(frame);
                //we dont need a full frame
                //ProcessFrame(frame);
            }
            catch
            {
                ReleaseFrame();
            }
            try
            {
                ReleaseFrame();
            }
            catch
            {
                //    throw new DesktopDuplicationException("Couldn't release frame.");  
            }
            return frame;
        }

        private bool RetrieveFrame()
        {
            if (_desktopImageTexture == null)
                _desktopImageTexture = new Texture2D(_mDevice, _mTextureDesc);
            Resource desktopResource = null;
            _frameInfo = new OutputDuplicateFrameInformation();
            try
            {
                _mDeskDupl.AcquireNextFrame(500, out _frameInfo, out desktopResource);
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Code == ResultCode.WaitTimeout.Result.Code)
                    return true;
                if (ex.ResultCode.Failure)
                {
                    //return true;
                    desktopResource?.Dispose();
                    throw new DesktopDuplicationException("Failed to acquire next frame.");
                }
            }
            using (var tempTexture = desktopResource?.QueryInterface<Texture2D>())
            {
                _mDevice.ImmediateContext.CopyResource(tempTexture, _desktopImageTexture);
            }
            desktopResource?.Dispose();
            return false;
        }

        private void RetrieveFrameMetadata(DesktopFrame frame)
        {
            if (_frameInfo.TotalMetadataBufferSize > 0)
            {
                // Get moved regions
                var movedRegionsLength = 0;
                var movedRectangles = new OutputDuplicateMoveRectangle[_frameInfo.TotalMetadataBufferSize];
                _mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out movedRegionsLength);
                frame.MovedRegions =
                    new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];
                for (var i = 0; i < frame.MovedRegions.Length; i++)
                {
                    var destRect = (Rectangle) movedRectangles[i].DestinationRect;
                    frame.MovedRegions[i] = new MovedRegion
                    {
                        Source = new Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y),
                        Destination =
                            new global::System.Drawing.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height)
                    };
                }

                // Get dirty regions
                var dirtyRegionsLength = 0;
                var dirtyRectangles = new RawRectangle[_frameInfo.TotalMetadataBufferSize];
                _mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out dirtyRegionsLength);
                frame.UpdatedRegions =
                    new global::System.Drawing.Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))];
                frame.FinishedRegions = new FinishedRegions[frame.UpdatedRegions.Length];
                for (var i = 0; i < frame.UpdatedRegions.Length; i++)
                {
                    var dirtyRect = (Rectangle) dirtyRectangles[i];
                    var rect = new global::System.Drawing.Rectangle(dirtyRect.X, dirtyRect.Y, dirtyRect.Width,
                        dirtyRect.Height);


                    frame.FinishedRegions[i] = new FinishedRegions
                    {
                        Destination = rect,
                        Frame = ExtractRect(rect.X, rect.Y, rect.Width, rect.Height)
                    };
                }
            }
            else
            {
                frame.MovedRegions = new MovedRegion[0];
                frame.UpdatedRegions = new global::System.Drawing.Rectangle[0];
            }
        }


        private Bitmap ExtractRect(int originX, int originY, int width, int height)
        {
            // Get the desktop capture screenTexture
            var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read,
                MapFlags.None);

            // Create Drawing.Bitmap

            var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); //不能是ARGB
            var boundsRect = new global::System.Drawing.Rectangle(0, 0, width, height);

            // Copy pixels from screen capture Texture to GDI bitmap
            var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
            var sourcePtr = mapSource.DataPointer;
            var destPtr = mapDest.Scan0;

            sourcePtr = IntPtr.Add(sourcePtr, originY * mapSource.RowPitch + originX * 4);
            for (var y = 0; y < height; y++)
            {
                // Copy a single line 

                Utilities.CopyMemory(destPtr, sourcePtr, width * 4);

                // Advance pointers
                if (y != height - 1)
                    sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                destPtr = IntPtr.Add(destPtr, mapDest.Stride);
            }

            // Release source and dest locks
            bitmap.UnlockBits(mapDest);
            _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
            return bitmap;
        }

        private void ProcessFrame(DesktopFrame frame)
        {
            // Get the desktop capture texture
            var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read,
                MapFlags.None);
            var bounds = (Rectangle) _mOutputDesc.DesktopBounds;
            FinalImage = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
            var boundsRect = new global::System.Drawing.Rectangle(0, 0, bounds.Width, bounds.Height);
            // Copy pixels from screen capture Texture to GDI bitmap
            var mapDest = FinalImage.LockBits(boundsRect, ImageLockMode.WriteOnly, FinalImage.PixelFormat);
            var sourcePtr = mapSource.DataPointer;
            var destPtr = mapDest.Scan0;
            for (var y = 0; y < bounds.Height; y++)
            {
                // Copy a single line 
                Utilities.CopyMemory(destPtr, sourcePtr, bounds.Width * 4);

                // Advance pointers
                sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                destPtr = IntPtr.Add(destPtr, mapDest.Stride);
            }

            // Release source and dest locks
            FinalImage.UnlockBits(mapDest);
            _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
            frame.DesktopImage = (Bitmap) FinalImage.Clone();
        }

        private void ReleaseFrame()
        {
            try
            {
                _mDeskDupl.ReleaseFrame();
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Failure)
                    throw new DesktopDuplicationException("Failed to release frame.");
            }
        }
    }
using System.Runtime.Serialization;
namespace AgentInterface.Api.ScreenShare.DesktopDuplication
    [DataContract]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
﻿using System;
using System.Drawing;
using System.Runtime.Serialization;
namespace AgentInterface.Api.ScreenShare.DesktopDuplication
    [DataContract]
        [DataMember]
        [DataMember]
namespace AgentInterface.Api.ScreenShare.DesktopDuplication
namespace AgentInterface.Api.Models
using System.Runtime.Serialization;
using AgentInterface.Api.ScreenShare.DesktopDuplication;
namespace AgentInterface.Api.Models
    [DataContract]
        [DataMember]
        [DataMember]
        [DataMember]
        [DataMember]
﻿namespace AgentInterface.Api.Models
using AgentInterface.Api.Models;
using AgentInterface.Api.ScreenShare.DesktopDuplication;
using AgentInterface.Api.Win32;
using AgentInterface.Settings;
namespace AgentInterface.Api.ScreenShare
                _desktopDuplicator = new DesktopDuplicator();
                _desktopDuplicator = new DesktopDuplicator();
namespace AgentInterface.Api.Win32
namespace AgentInterface.Api.Win32
namespace AgentInterface.Api.Win32
namespace AgentInterface.Api.Win32
﻿<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    
  </configSections>
  <system.net>
    <settings>
      <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
  </system.net>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <runtime>
    <loadFromRemoteSources enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AForge.Video" publicKeyToken="cbfb6e07d173c401" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.5.0" newVersion="2.2.5.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Magnum" publicKeyToken="b800c4cfcdeea87b" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.3.0" newVersion="2.1.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets.Rfc6455" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets.Deflate" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AForge" publicKeyToken="c1db6ff4eaa06aeb" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.5.0" newVersion="2.2.5.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks.Dataflow" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.6.1.0" newVersion="4.6.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v13.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  
﻿<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  <Costura>
    <ExcludeAssemblies>
      WindowsInput
      AgentInterface
      Newtonsoft.Json
    </ExcludeAssemblies>
  </Costura>
</Weavers>
using AgentInterface.Settings;
using AgentInterface.Settings;
using Topshelf;
using UlteriusServer.Forms.Utilities;
using UlteriusServer.Utilities.Usage;

                if (
                    Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location))
                        .Count() > 1) return;

                ProfileOptimization.SetProfileRoot(AppEnvironment.DataPath);
                ProfileOptimization.StartProfile("Startup.Profile");

                if (args.Length > 0)
                    HostFactory.Run(x => //1
                    {
                        x.Service<UlteriusAgent>(s => //2
                        {
                            s.ConstructUsing(name => new UlteriusAgent()); //3
                            s.WhenStarted(tc => tc.Start()); //4
                            s.WhenStopped(tc => tc.Stop());
                            s.WhenSessionChanged((se, e, id) => { se.HandleEvent(e, id); }); //5
                        });
                        x.RunAsLocalSystem(); //6
                        x.EnableSessionChanged();
                        x.EnableServiceRecovery(r => { r.RestartService(1); });
                        x.SetDescription("The server that powers Ulterius"); //7
                        x.SetDisplayName("Ulterius Server"); //8
                        x.SetServiceName("UlteriusServer"); //9
                    });
                else
                    var ulterius = new Ulterius();
                    ulterius.Start();
                    var hardware = new HardwareSurvey();
                    hardware.Setup();
                    if (Tools.RunningPlatform() == Tools.Platform.Windows)
                        UlteriusTray.ShowTray();
                    else
                        Console.ReadKey(true);
                Console.Read();
[assembly: AssemblyVersion("1.9.2.0")]
[assembly: AssemblyFileVersion("1.9.2.0")]
using AgentInterface.Settings;
                    Console.WriteLine(queueRequest);
                    _ws.Close();

            _wsServer = new WebSocketListener(endpoint, new WebSocketListenerOptions
                OnHttpNegotiation = HttpNegotiation
            });
            var rfc6455 = new WebSocketFactoryRfc6455(_wsServer);
            _wsServer.Standards.RegisterStandard(rfc6455);
            _wsServer.Start();
            _log.Info("Echo Server started");
        private void HttpNegotiation(WebSocketHttpRequest request, WebSocketHttpResponse response)
                    _log.Error("Error Accepting clients", aex.GetBaseException());
            _log.Info("Server Stop accepting clients");
using AgentInterface.Settings;
            if (Process.GetProcessesByName(
                Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location))
                .Length > 1)
            {
                Process.GetCurrentProcess().Kill();
            }
            if (!Directory.Exists(AppEnvironment.DataPath))
            {
                Directory.CreateDirectory(AppEnvironment.DataPath);
            }

            if (!Debugger.IsAttached)
            {

                ExceptionHandler.AddGlobalHandlers();
                Console.WriteLine("Exception Handlers Attached");
            }


           
            var settings = Config.Load();

        
           
          
          
        
            Console.Write($"Service: {UlteriusApiServer.RunningAsService}");
﻿#region

using System;
using System.Diagnostics;
using Topshelf;
using UlteriusServer.Utilities;
using UlteriusServer.Utilities.Usage;

#endregion

namespace UlteriusServer
{
    public class UlteriusAgent
    {


        private Ulterius _ulterius;

        public void Start()
        {
            _ulterius = new Ulterius();
            _ulterius.Start(true);
            HandleMonitor();
            var hardware = new HardwareSurvey();
            hardware.Setup(true);
            Console.ReadLine();
        }

       
        public void HandleMonitor()
        {
            Tools.RestartAgent();
        }


        public void Stop()
        {
            var agentList = Process.GetProcessesByName("UlteriusAgent");
            foreach (var agent in agentList)
            {
                try
                {
                    agent.Kill();
                }
                catch (Exception)
                {
                    // ignored
                }
            }
            var managerList = Process.GetProcessesByName("DaemonManager");
            foreach (var manager in managerList)
            {
                try
                {
                    manager.Kill();
                }
                catch (Exception)
                {
                    // ignored
                }
            }

            var serverInstanceList = Process.GetProcessesByName("Ulterius Server");
            foreach (var server in serverInstanceList)
            {
                try
                {
                    server.Kill();
                }
                catch (Exception)
                {
                    // ignored
                }
            }
        }

        public void HandleEvent(HostControl hostControl, SessionChangedArguments arg3)
        {
            HandleMonitor();
        }
    }
}
﻿<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\packages\Microsoft.Net.Compilers.2.0.0-rc3\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.0.0-rc3\build\Microsoft.Net.Compilers.props')" />
  <Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>UlteriusServer</RootNamespace>
    <AssemblyName>Ulterius Server</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <TargetFrameworkProfile />
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <PublishUrl>publish\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <UseApplicationTrust>false</UseApplicationTrust>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>6</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>6</LangVersion>
    <Prefer32Bit>false</Prefer32Bit>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>256.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <PropertyGroup>
    <SignAssembly>false</SignAssembly>
  </PropertyGroup>
  <PropertyGroup>
    <AssemblyOriginatorKeyFile>
    </AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup>
    <SignManifests>false</SignManifests>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Api\Network\Messages\MessageResolver.cs" />
    <Compile Include="Api\Network\Messages\PacketLoader.cs" />
    <Compile Include="Api\Network\Messages\RectangleConverter.cs" />
    <Compile Include="Api\Network\Models\FanInformation.cs" />
    <Compile Include="Api\Network\Models\LoginInformation.cs" />
    <Compile Include="Api\Network\PacketHandlers\DisplayPacketHandler.cs" />
    <Compile Include="Api\Network\UlteriusAgentClient.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\JobModel.cs" />
    <Compile Include="Api\Network\PacketHandlers\CronJobPacketHandler.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronDaemon.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronJob.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronSchedule.cs" />
    <Compile Include="Api\Services\LocalSystem\CronJobService.cs" />
    <Compile Include="Api\Services\Update\UpdateService.cs" />
    <Compile Include="Api\Network\Messages\Message.cs" />
    <Compile Include="Api\Network\Messages\MessageQueueManager.cs" />
    <Compile Include="Api\Services\LocalSystem\FileSearchService.cs" />
    <Compile Include="Forms\Utilities\AboutBox.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Forms\Utilities\AboutBox.Designer.cs">
      <DependentUpon>AboutBox.cs</DependentUpon>
    </Compile>
    <Compile Include="TerminalServer\Infrastructure\ILogger.cs" />
    <Compile Include="TerminalServer\Infrastructure\Log4NetLogger.cs" />
    <Compile Include="Ulterius.cs" />
    <Compile Include="UlteriusAgent.cs" />
    <Compile Include="Utilities\Drive\PartitionModel.cs" />
    <Compile Include="Utilities\Drive\SmartData.cs" />
    <Compile Include="Utilities\Drive\SmartEnums.cs" />
    <Compile Include="Utilities\Drive\SmartModel.cs" />
    <Compile Include="Utilities\Extensions\NetworkBrowser.cs" />
    <Compile Include="Utilities\Extensions\TaskExtensions.cs" />
    <Compile Include="Utilities\Files\Database\DatabaseController.cs" />
    <Compile Include="Utilities\Files\Database\DatabaseManager.cs" />
    <Compile Include="Utilities\Security\Streams\OfbStream.cs" />
    <Compile Include="Utilities\Security\Streams\ZeroStream.cs" />
    <Compile Include="Utilities\Security\AuthUtils.cs" />
    <Compile Include="Utilities\Usage\HardwareSurvey.cs" />
    <Compile Include="WebCams\WebCamManager.cs" />
    <Compile Include="WebSocketAPI\Authentication\AuthClient.cs" />
    <Compile Include="Forms\Utilities\UlteriusTray.cs" />
    <Compile Include="Api\Network\Messages\Packet.cs" />
    <Compile Include="Api\Network\Messages\MessageBuilder.cs" />
    <Compile Include="Api\Network\PacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ErrorPacketHandler.cs" />
    <Compile Include="Api\Network\PacketManager.cs" />
    <Compile Include="Api\Network\PacketHandlers\WebCamPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\FilePacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\GpuPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ScreenSharePacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\AccountPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\SettingsPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\NetworkPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\CpuPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\OperatingSystemPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ProcessPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ServerPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\SystemPacketHandler.cs" />
    <Compile Include="Api\Network\Models\GpuInformation.cs" />
    <Compile Include="Api\Services\LocalSystem\ScreenShareService.cs" />
    <Compile Include="TerminalServer\Cli\CommandSession.cs" />
    <Compile Include="TerminalServer\Cli\PowerShellSession.cs" />
    <Compile Include="TerminalServer\Cli\_ICliSession.cs" />
    <Compile Include="TerminalServer\Cli\_ICliSessionFactory.cs" />
    <Compile Include="TerminalServer\Infrastructure\SystemInfo.cs" />
    <Compile Include="TerminalServer\Infrastructure\_ISystemInfo.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\ConnectionConnectRequest.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\IConnectionEvent.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\IConnectionRequest.cs" />
    <Compile Include="TerminalServer\Messaging\IMessageBus.cs" />
    <Compile Include="TerminalServer\Messaging\Serialization\DefaultEventSerializator.cs" />
    <Compile Include="TerminalServer\Messaging\Serialization\IEventSerializator.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\ClosedTerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\CreatedTerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\SessionStateEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\TerminalOutputEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\_ITerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\AesHandshakeRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\CloseTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\CreateTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\InputTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\_IRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\AesHandshakeRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\CloseTerminalRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\CreateTerminalRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\TerminalInputRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\_TerminalControlRequest.cs" />
    <Compile Include="TerminalServer\Messaging\WebSocketHandler.cs" />
    <Compile Include="TerminalServer\Messaging\WebSocketQueueServer.cs" />
    <Compile Include="TerminalServer\Session\ConnectionManager.cs" />
    <Compile Include="TerminalServer\Session\UserConnection.cs" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Api\UlteriusApiServer.cs" />
    <Compile Include="TerminalServer\TerminalManagerServer.cs" />
    <Compile Include="Utilities\DynamicMap.cs" />
    <Compile Include="Utilities\Extensions\StringExtensions.cs" />
    <Compile Include="Utilities\Files\FileManager.cs" />
    <Compile Include="Utilities\IconTools.cs" />
    <Compile Include="Utilities\Security\UlteriusAes.cs" />
    <Compile Include="Utilities\Security\Rsa.cs" />
    <Compile Include="Utilities\Files\FileTree.cs" />
    <Compile Include="Utilities\Trace.cs" />
    <Compile Include="WebServer\MultipartParser.cs" />
    <Compile Include="WebSocketAPI\Authentication\CookieManager.cs" />
    <Compile Include="WebSocketAPI\WebSocketEventListener.cs" />
    <Compile Include="Api\Network\Models\DriveInformation.cs" />
    <Compile Include="Api\Network\Models\SystemInformation.cs" />
    <Compile Include="Api\Network\Models\NetworkInformation.cs" />
    <Compile Include="Api\Network\Models\CpuInformation.cs" />
    <Compile Include="Api\Network\Models\OperatingSystemInformation.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Api\Network\Models\ProcessInformation.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Utilities\ExceptionHandler.cs" />
    <Compile Include="Api\Services\Network\NetworkService.cs" />
    <Compile Include="Api\Services\LocalSystem\SystemService.cs" />
    <Compile Include="Utilities\Tools.cs" />
    <Compile Include="WebServer\HttpServer.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="app.manifest" />
    <None Include="App1.config" />
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Forms\Utilities\AboutBox.resx">
      <DependentUpon>AboutBox.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup>
    <Content Include="256.ico" />
    <EmbeddedResource Include="Packets.json" />
    <None Include="Resources\ApplicationIcon.ico" />
    <None Include="FodyWeavers.xml">
      <SubType>Designer</SubType>
    </None>
    <Content Include="twitter-profile.ico" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Service References\" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="bin\Debug\" />
    <Folder Include="Utilities\Files\Models\" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="AForge, Version=2.2.5.0, Culture=neutral, PublicKeyToken=c1db6ff4eaa06aeb, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.2.2.5\lib\AForge.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Imaging, Version=2.2.5.0, Culture=neutral, PublicKeyToken=ba8ddea9676ca48b, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Imaging.2.2.5\lib\AForge.Imaging.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Math, Version=2.2.5.0, Culture=neutral, PublicKeyToken=abba2e25397ee8c9, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Math.2.2.5\lib\AForge.Math.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Video, Version=2.2.5.0, Culture=neutral, PublicKeyToken=cbfb6e07d173c401, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Video.2.2.5\lib\AForge.Video.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Video.DirectShow, Version=2.2.5.0, Culture=neutral, PublicKeyToken=61ea4348d43881b7, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Video.DirectShow.2.2.5\lib\AForge.Video.DirectShow.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Vision, Version=2.2.5.0, Culture=neutral, PublicKeyToken=b612fa915eefaa06, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Vision.2.2.5\lib\AForge.Vision.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
      <HintPath>..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="DotNetZip, Version=1.10.1.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
      <HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="log4net, Version=2.0.7.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
      <HintPath>..\packages\log4net.2.0.7\lib\net45-full\log4net.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Magnum, Version=2.1.3.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL">
      <HintPath>..\packages\Magnum.2.1.3\lib\NET40\Magnum.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="MassTransit, Version=2.9.0.0, Culture=neutral, PublicKeyToken=b8e0e9f2f1e657fa, processorArchitecture=MSIL">
      <HintPath>..\packages\MassTransit.2.9.0\lib\net40\MassTransit.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.10.0.1-beta1\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="Open.Nat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f22a6a4582336c76, processorArchitecture=MSIL">
      <HintPath>..\packages\Open.NAT.2.1.0.0\lib\net45\Open.Nat.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PresentationCore" />
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.DirectoryServices" />
    <Reference Include="System.DirectoryServices.AccountManagement" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.IO.Compression" />
    <Reference Include="System.Management" />
    <Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll</HintPath>
    </Reference>
    <Reference Include="System.Net" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.ServiceProcess" />
    <Reference Include="System.Threading.Tasks.Dataflow, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Threading.Tasks.Dataflow.4.7.0\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Web" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xaml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Xml" />
    <Reference Include="Topshelf, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL">
      <HintPath>..\packages\Topshelf.4.0.3\lib\net452\Topshelf.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="vtortola.WebSockets, Version=2.2.2.0, Culture=neutral, PublicKeyToken=7f78616efb4a208d, processorArchitecture=MSIL">
      <HintPath>..\packages\vtortola.WebSocketListener.2.2.2.0\lib\net45\vtortola.WebSockets.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="vtortola.WebSockets.Deflate, Version=2.2.2.0, Culture=neutral, PublicKeyToken=7f78616efb4a208d, processorArchitecture=MSIL">
      <HintPath>..\packages\vtortola.WebSocketListener.2.2.2.0\lib\net45\vtortola.WebSockets.Deflate.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="vtortola.WebSockets.Rfc6455, Version=2.2.2.0, Culture=neutral, PublicKeyToken=7f78616efb4a208d, processorArchitecture=MSIL">
      <HintPath>..\packages\vtortola.WebSocketListener.2.2.2.0\lib\net45\vtortola.WebSockets.Rfc6455.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="ZetaLongPaths, Version=1.0.0.14, Culture=neutral, PublicKeyToken=b764f59068f31f38, processorArchitecture=MSIL">
      <HintPath>..\packages\ZetaLongPaths.1.0.0.14\lib\net40-full\ZetaLongPaths.dll</HintPath>
      <Private>True</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <COMReference Include="NetFwTypeLib">
      <Guid>{58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>0</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\inputsimulator2\WindowsInput\WindowsInput.csproj">
      <Project>{3549cd6f-80f8-450f-b99e-cf0a736b1f2a}</Project>
      <Name>WindowsInput</Name>
    </ProjectReference>
    <ProjectReference Include="..\AgentInterface\AgentInterface.csproj">
      <Project>{5c3b0b17-cbb7-4b4b-b527-1fab2bb96466}</Project>
      <Name>AgentInterface</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
    <Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.2.0.0-rc3\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.2.0.0-rc3\build\Microsoft.Net.Compilers.props'))" />
    <Error Condition="!Exists('..\packages\Fody.1.29.3\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.1.29.3\build\dotnet\Fody.targets'))" />
    <Error Condition="!Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets'))" />
  </Target>
  <PropertyGroup>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
  <PropertyGroup>
    <PreBuildEvent>
    </PreBuildEvent>
  </PropertyGroup>
  <Target Name="AfterClean">
    <Delete Files="$(TargetDir)\*.dll" />
  </Target>
  <Target Name="AfterClean">
    <ItemGroup>
      <FilesToDelete Include="$(TargetDir)\*.dll" />
    </ItemGroup>
    <Delete Files="@(FilesToDelete)" />
  </Target>
  <UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory">
    <ParameterGroup>
      <Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" />
      <Files Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
    </ParameterGroup>
    <Task Evaluate="true">
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml" />
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml.Linq" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" />
      <Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault();

if (config == null) return true;

var excludedAssemblies = new List<string>();
var attribute = config.Attribute("ExcludeAssemblies");
if (attribute != null)
    foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);
var element = config.Element("ExcludeAssemblies");
if (element != null)
    foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);

var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));

foreach (var item in filesToCleanup)
  File.Delete(item);
]]></Code>
    </Task>
  </UsingTask>
  <Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget">
    <CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
  </Target>
  <Import Project="..\packages\Fody.1.29.3\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.1.29.3\build\dotnet\Fody.targets')" />
  <Import Project="..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.2.0.0-beta0018\build\Costura.Fody.targets')" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  
  -->
namespace AgentInterface.Settings
namespace AgentInterface.Settings
using AgentInterface.Settings;
﻿#region

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

#endregion

namespace UlteriusServer.Utilities.Extensions
{
    /// <summary>
    ///     Enum FormatTokenFlags
    /// </summary>
    public enum FormatTokenFlags
    {
        /// <summary>
        ///     Uses the specifier token as the replacement token, matches '%' but not '%%'
        /// </summary>
        SpecifierToken,

        /// <summary>
        ///     Like String.Format
        /// </summary>
        IndexToken,

        /// <summary>
        ///     Extracts an Object's Members by name.
        /// </summary>
        MemberToken
    }

    /// <summary>
    ///     Class StringExtensions
    /// </summary>
    public static class StringExtensions
    {

        // Returns the human-readable file totalSize for an arbitrary, 64-bit file totalSize 
        // The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"

        public static string UnicodeUtf8(this string strFrom)
        {
            var bytSrc = Encoding.Unicode.GetBytes(strFrom);
            var bytDestination = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytSrc);
            var strTo = Encoding.UTF8.GetString(bytDestination);
            return strTo;
        }

        /// <summary>
        /// Implement's VB's Like operator logic.
        /// </summary>
        public static bool IsLike(this string s, string pattern)
        {
            // Characters matched so far
            int matched = 0;

            // Loop through pattern string
            for (int i = 0; i < pattern.Length;)
            {
                // Check for end of string
                if (matched > s.Length)
                    return false;

                // Get next pattern character
                char c = pattern[i++];
                if (c == '[') // Character list
                {
                    // Test for exclude character
                    bool exclude = (i < pattern.Length && pattern[i] == '!');
                    if (exclude)
                        i++;
                    // Build character list
                    int j = pattern.IndexOf(']', i);
                    if (j < 0)
                        j = s.Length;
                    HashSet<char> charList = CharListToSet(pattern.Substring(i, j - i));
                    i = j + 1;

                    if (charList.Contains(s[matched]) == exclude)
                        return false;
                    matched++;
                }
                else if (c == '?') // Any single character
                {
                    matched++;
                }
                else if (c == '#') // Any single digit
                {
                    if (!Char.IsDigit(s[matched]))
                        return false;
                    matched++;
                }
                else if (c == '*') // Zero or more characters
                {
                    if (i < pattern.Length)
                    {
                        // Matches all characters until
                        // next character in pattern
                        char next = pattern[i];
                        int j = s.IndexOf(next, matched);
                        if (j < 0)
                            return false;
                        matched = j;
                    }
                    else
                    {
                        // Matches all remaining characters
                        matched = s.Length;
                        break;
                    }
                }
                else // Exact character
                {
                    if (matched >= s.Length || c != s[matched])
                        return false;
                    matched++;
                }
            }
            // Return true if all characters matched
            return (matched == s.Length);
        }

        /// <summary>
        /// Converts a string of characters to a HashSet of characters. If the string
        /// contains character ranges, such as A-Z, all characters in the range are
        /// also added to the returned set of characters.
        /// </summary>
        /// <param name="charList">Character list string</param>
        private static HashSet<char> CharListToSet(string charList)
        {
            HashSet<char> set = new HashSet<char>();

            for (int i = 0; i < charList.Length; i++)
            {
                if ((i + 1) < charList.Length && charList[i + 1] == '-')
                {
                    // Character range
                    char startChar = charList[i++];
                    i++; // Hyphen
                    char endChar = (char)0;
                    if (i < charList.Length)
                        endChar = charList[i++];
                    for (int j = startChar; j <= endChar; j++)
                        set.Add((char)j);
                }
                else set.Add(charList[i]);
            }
            return set;
        }

        public static string GetBytesReadable(long i)
        {
            // Get absolute value
            var absoluteI = i < 0 ? -i : i;
            // Determine the suffix and readable value
            string suffix;
            double readable;
            if (absoluteI >= 0x1000000000000000) // Exabyte
            {
                suffix = "EB";
                readable = i >> 50;
            }
            else if (absoluteI >= 0x4000000000000) // Petabyte
            {
                suffix = "PB";
                readable = i >> 40;
            }
            else if (absoluteI >= 0x10000000000) // Terabyte
            {
                suffix = "TB";
                readable = i >> 30;
            }
            else if (absoluteI >= 0x40000000) // Gigabyte
            {
                suffix = "GB";
                readable = i >> 20;
            }
            else if (absoluteI >= 0x100000) // Megabyte
            {
                suffix = "MB";
                readable = i >> 10;
            }
            else if (absoluteI >= 0x400) // Kilobyte
            {
                suffix = "KB";
                readable = i;
            }
            else
            {
                return i.ToString("0 B"); // Byte
            }
            // Divide by 1024 to get fractional value
            readable = readable / 1024;
            // Return formatted number with suffix
            return readable.ToString("0.### ") + suffix;
        }

        /// <summary>
        /// Returns a Secure string from the source string
        /// </summary>
        /// <param name="Source"></param>
        /// <returns></returns>
        public static SecureString ToSecureString(this string Source)
        {
            if (string.IsNullOrWhiteSpace(Source))
                return null;
            var Result = new SecureString();
            foreach (var c in Source.ToCharArray())
                Result.AppendChar(c);
            return Result;
        }
        public static string ToUnsecureString(this SecureString secureString)
        {
            if (secureString == null) throw new ArgumentNullException("secureString");

            var unmanagedString = IntPtr.Zero;
            try
            {
                unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
                return Marshal.PtrToStringUni(unmanagedString);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
            }
        }


        /// <summary>
        ///     The Reformatting function called to format the string with a list of arguments.
        /// </summary>
        private static Func<Func<string, object>, string, IList<object>, string> _regexReformatter;

        /// <summary>
        ///     The Regex which matches the specifier token in strings.
        /// </summary>
        private static Regex _specifierTokenRegex;

        /// <summary>
        ///     The Regex which matches parameter indexes in strings, same as string.Format.
        /// </summary>
        private static Regex _argumentIndexRegex;

        /// <summary>
        ///     The Regex which matches object member names in strings.
        /// </summary>
        private static Regex _objectMemberRegex;

        /// <summary>
        ///     Splits a string into an array of strings, the string is split by commas.
        /// </summary>
        /// <param name="this">The string instance to split by commas.</param>
        /// <returns>The <paramref name="this" /> string that has been comma separated into substrings.</returns>
        public static string[] CommaSeparate(this string @this)
        {
            return @this.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        ///     Determines whether two String objects contain the same data, ignoring the case of the letters in the String; uses
        ///     Ordinal comparison.
        /// </summary>
        /// <param name="this">The current string to be compared to.</param>
        /// <param name="other">The other string to compare against the current String for equality.</param>
        /// <returns><c>true</c> if the two strings are equal, <c>false</c> otherwise</returns>
        public static bool EqualsIgnoreCase(this string @this, string other)
        {
            return string.Equals(@this, other, StringComparison.OrdinalIgnoreCase);
        }

        public static bool IsBase64String(this string s)
        {
            s = s.Trim();
            return (s.Length%4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
        }

        public static bool IsValidJson(this string strInput)
        {
            strInput = strInput.Trim();
            if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || //For object
                (strInput.StartsWith("[") && strInput.EndsWith("]"))) //For array
            {
                try
                {
                    JToken.Parse(strInput);
                    return true;
                }
                catch (JsonReaderException)
                {
                    //Exception in parsing json
                    return false;
                }
                catch (Exception) //some other exception
                {
                    return false;
                }
            }
            return false;
        }


        /// <summary>
        ///     Replaces one or more format items in a specified string with the string representation of a specified object.
        /// </summary>
        /// <returns>
        ///     A copy of <paramref name="format" /> in which any format items are replaced by the string representation of
        ///     <paramref name="values" />.
        /// </returns>
        /// <param name="format">A composite format string. </param>
        /// <param name="values">The arguments to use in formatting <paramref name="format" />.</param>
        public static string Form(this string format, params object[] values)
        {
            var specifierTokenMatches = _specifierTokenRegex.Matches(format);
            var indexTokenMatches = _argumentIndexRegex.Matches(format);
            var memberNameMatches = _objectMemberRegex.Matches(format);

            if (memberNameMatches.Count > 0 && values.Length == 1)
            {
                format = FormatString(format, FormatTokenFlags.MemberToken, values);
            }
            else
            {
                if (indexTokenMatches.Count > 0)
                {
                    format = FormatString(format, FormatTokenFlags.IndexToken, values);
                }

                if (specifierTokenMatches.Count > 0)
                {
                    format = FormatString(format, FormatTokenFlags.SpecifierToken, values);
                }
            }
            return format;
        }

        public static string CreateMD5(this string input)
        {
            // Use input string to calculate MD5 hash
            using (var md5 = MD5.Create())
            {
                var inputBytes = Encoding.ASCII.GetBytes(input);
                var hashBytes = md5.ComputeHash(inputBytes);

                // Convert the byte array to hexadecimal string
                var sb = new StringBuilder();
                foreach (var t in hashBytes)
                {
                    sb.Append(t.ToString("X2"));
                }
                return sb.ToString();
            }
        }

        /// <summary>
        ///     The Function which does all the heavy lifting.
        /// </summary>
        /// <param name="format">A composite format string</param>
        /// <param name="flags">The flags which specify how the <paramref name="format" /> string should be interpreted.</param>
        /// <param name="arguments">The arguments to format the <paramref name="format" /> parameter with.</param>
        /// <returns>System.String.</returns>
        public static string FormatString(string format, FormatTokenFlags flags, params object[] arguments)
        {
            switch (flags)
            {
                case FormatTokenFlags.IndexToken:
                    return string.Format(format, arguments);

                case FormatTokenFlags.SpecifierToken:
                    var stringBuilder = new StringBuilder();
                    for (int i = 0,
                        argIndex = 0;
                        i < format.Length;
                        i++)
                    {
                        stringBuilder.Append(format[i] == '%' && argIndex < arguments.Length
                            ? "{" + argIndex++ + "}"
                            : format.Substring(i, 1));
                    }
                    return string.Format(stringBuilder.ToString(), arguments);

                case FormatTokenFlags.MemberToken:
                    return
                        string.Format(
                            _regexReformatter(name => name == "0" ? arguments[0] : DataBinder.Eval(arguments[0], name),
                                format, arguments), arguments);

                default:
                    return format;
            }
        }

        public static void Initialize()
        {
            const RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.CultureInvariant;
            _objectMemberRegex = new Regex(@"(?<start>(\{))+(?<property>[\w\.]+)(?<end>(\}))+", regexOptions);
            _specifierTokenRegex = new Regex(@"(?<!\\)%", regexOptions);
            _argumentIndexRegex = new Regex(@"\{(\d)\}", regexOptions);
            _regexReformatter = (valueFetcher, format, parameters) =>
            {
                var argumentCollection = new List<object>();
                var rewrittenFormat = _objectMemberRegex.Replace(format, match =>
                {
                    Group startGroup = match.Groups["start"],
                        propertyGroup = match.Groups["property"],
                        endGroup = match.Groups["end"];

                    var result = valueFetcher(propertyGroup.Value);

                    argumentCollection.Add(result);
                    var index = argumentCollection.Count - 1;
                    var fmt = new string('{', startGroup.Captures.Count) + index +
                              new string('}', endGroup.Captures.Count);
                    return string.Format(fmt, argumentCollection.ToArray());
                });

                return rewrittenFormat;
            };
        }
    }
using AgentInterface.Api.Win32;

using AgentInterface.Api.ScreenShare;
using AgentInterface.Api.Win32;
using AgentInterface.Settings;
                ProcessStarter.PROCESS_INFORMATION managerInfo;
                ProcessStarter.StartProcessAndBypassUAC(managerPath, 
                out managerInfo);
                managerProcess = Process.GetProcessById((int)managerInfo.dwProcessId);

               
            ProcessStarter.PROCESS_INFORMATION agentInfo;
        
         
            var agentPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"UlteriusAgent.exe");
            
            ProcessStarter.StartProcessAndBypassUAC(agentPath, 
                out agentInfo);
            agentProcess = Process.GetProcessById((int)agentInfo.dwProcessId);
            if (!RunningAsService())
            {
              ScreenData.SetupDuplication();  
            }
                    if (RunningAsService())
                    {
                        ProcessStarter.PROCESS_INFORMATION procInfo;
                        ProcessStarter.StartProcessAndBypassUAC("CMD.exe " + command,  out procInfo);
                    }
                    else
                    {
                        Process.Start("CMD.exe", command);
                    }
                        string.Format(
                            "firewall add allowedprogram program=\"{0}\" name=\"{1}\" profile=\"ALL\"",
                            exeFileName, displayName),
            proc.WaitForExit();
            return GetCurrent().Name.ToLower().Contains(@"nt authority\system");
using AgentInterface.Settings;
﻿#region

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Net.Http;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.Win32;
using Newtonsoft.Json;
using UlteriusServer.Api.Network.Models;
using UlteriusServer.Properties;
using SystemInformation = UlteriusServer.Api.Network.Models.SystemInformation;

#endregion

namespace UlteriusServer.Utilities.Usage
{
    public class HardwareSurvey
    {
        private static readonly string results = "surveryresults.json";

        private List<GpuInformation> GetGpuInformation()
        {
            var searcher =
                new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");

            var gpus = (from ManagementBaseObject mo in searcher.Get()
                select new GpuInformation
                {
                    Name = mo["Name"]?.ToString(),
                    ScreenInfo = mo["VideoModeDescription"]?.ToString(),
                    DriverVersion = mo["DriverVersion"]?.ToString(),
                    RefreshRate = int.Parse(mo["CurrentRefreshRate"]?.ToString() ?? "0"),
                    AdapterRam = mo["AdapterRAM"]?.ToString(),
                    VideoArchitecture = int.Parse(mo["VideoArchitecture"]?.ToString() ?? "0"),
                    VideoMemoryType = int.Parse(mo["VideoMemoryType"]?.ToString() ?? "0"),
                    InstalledDisplayDrivers = mo["InstalledDisplayDrivers"]?.ToString()?.Split(','),
                    AdapterCompatibility = mo["AdapterCompatibility"]?.ToString(),
                    Status = mo["Status"]?.ToString(),
                    Availability = int.Parse(mo["Availability"]?.ToString() ?? "0")
                }).ToList();
            return gpus;
        }

        private void Prompt()
        {
            var dialogResult = MessageBox.Show(Resources.HardwareSurvey_Setup_,
                Resources.HardwareSurvey_Setup_Usage_statistics_reporting, MessageBoxButtons.YesNo);
            switch (dialogResult)
            {
                case DialogResult.Yes:
                    SendData();
                    break;
                case DialogResult.No:
                    File.WriteAllText(results, "false");
                    break;
            }
        }

        public void Setup(bool service = false)
        {
            if (File.Exists(results))
            {
                var days = (DateTime.Now - File.GetCreationTime(results)).TotalDays;
                if (days > 30)
                {
                    SendData();
                }
            }
            else
            {
                if (service)
                {
                    SendData();
                }
                else
                {
                    Prompt();
                }
            }
        }

        public string GetMachineGuid()
        {
            try
            {
                var location = @"SOFTWARE\Microsoft\Cryptography";
                var name = "MachineGuid";
                using (var localMachineX64View =
                    RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
                {
                    using (var rk = localMachineX64View.OpenSubKey(location))
                    {
                        if (rk == null)
                            throw new KeyNotFoundException(
                                $"Key Not Found: {location}");

                        var machineGuid = rk.GetValue(name);
                        if (machineGuid == null)
                            throw new IndexOutOfRangeException(
                                $"Index Not Found: {name}");
                        return machineGuid.ToString().Replace("-", "").ToUpper();
                    }
                }
            }
            catch (Exception)
            {
                return Guid.NewGuid().ToString("N").ToUpper();
            }
        }

        private async void SendData()
        {
            try
            {
                var data = new
                {
                    ServerInfo = OperatingSystemInformation.ToObject(),
                    SystemInfo = SystemInformation.ToObject(),
                    UlteriusVersion = Assembly.GetExecutingAssembly().GetName().Version,
                    GpuInfo = GetGpuInformation(),
                    NetworkInformation = NetworkInformation.ToObject(),
                    CpuInfo = CpuInformation.ToObject()
                };
                var json = JsonConvert.SerializeObject(data);
                var content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("guid", GetMachineGuid()),
                    new KeyValuePair<string, string>("results", json)
                });
                using (var client = new HttpClient())
                {
                    client.Timeout = new TimeSpan(0, 0, 0, 5);
                    var result = await client.PostAsync("https://api.ulterius.io/hardware/", content);
                    if (result.IsSuccessStatusCode)
                    {
                        Console.WriteLine("Hardware Survery Completed");
                        File.WriteAllText(results, "true");
                    }
                }
            }
            catch (Exception)
            {
                //just fail
            }
        }
    }
}
using AgentInterface.Settings;
using AgentInterface.Settings;


        private readonly List<WebSocketListener> _listeners = new List<WebSocketListener>();
        public WebSocketEventListener(List<IPEndPoint> endpoints)
        public WebSocketEventListener(List<IPEndPoint> endpoints, WebSocketListenerOptions options)
            foreach (var endpoint in endpoints)
            {
                var listener = new WebSocketListener(endpoint, options);
                var rfc6455 = new WebSocketFactoryRfc6455(listener);
                listener.Standards.RegisterStandard(rfc6455);
                _listeners.Add(listener);
            }
            foreach (var listener in _listeners)
            {
                listener.Dispose();
            }
        public void Start()
            foreach (var listener in _listeners)
            {
                listener.Start();
            }
        public void Stop()
            foreach (var listener in _listeners)
            {
                listener.Stop();
            }
            foreach (var listener in _listeners)
            {
                Task.Run(() => HandleListners(listener));
            }
﻿<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AForge" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Imaging" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Math" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Video" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Video.DirectShow" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Vision" version="2.2.5" targetFramework="net461" />
  <package id="BouncyCastle" version="1.8.1" targetFramework="net461" />
  <package id="Costura.Fody" version="2.0.0-beta0018" targetFramework="net461" developmentDependency="true" />
  <package id="DotNetZip" version="1.10.1" targetFramework="net461" />
  <package id="Fody" version="1.29.3" targetFramework="net461" developmentDependency="true" />
  <package id="JonSkeet.MiscUtil" version="0.1" targetFramework="net45" />
  <package id="log4net" version="2.0.7" targetFramework="net461" />
  <package id="Magnum" version="2.1.3" targetFramework="net461" />
  <package id="MassTransit" version="2.9.0" targetFramework="net461" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net461" />
  <package id="Microsoft.Net.Compilers" version="2.0.0-rc3" targetFramework="net461" developmentDependency="true" />
  <package id="Microsoft.Tpl.Dataflow" version="4.5.24" targetFramework="net461" />
  <package id="Mono.Cecil" version="0.9.6.4" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="10.0.1-beta1" targetFramework="net461" />
  <package id="Open.NAT" version="2.1.0.0" targetFramework="net461" />
  <package id="System.Threading.Tasks.Dataflow" version="4.7.0" targetFramework="net461" />
  <package id="Topshelf" version="4.0.3" targetFramework="net461" />
  <package id="vtortola.WebSocketListener" version="2.2.2.0" targetFramework="net461" />
  <package id="ZetaLongPaths" version="1.0.0.14" targetFramework="net461" />
﻿<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Magnum" publicKeyToken="b800c4cfcdeea87b" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.3.0" newVersion="2.1.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AsyncIO" publicKeyToken="44a94435bd6f33f8" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-0.1.25.0" newVersion="0.1.25.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
﻿<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  <Costura>
    <ExcludeAssemblies>
      WindowsInput
      AgentInterface
      Newtonsoft.Json
    </ExcludeAssemblies>
  </Costura>
</Weavers>
﻿#region

using System;
using System.Drawing;
using System.ServiceModel;
using AgentInterface;
using AgentInterface.Api.Models;
using AgentInterface.Api.ScreenShare;
using AgentInterface.Api.Win32;


#endregion

namespace UlteriusAgent.Networking
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class FrameAgent : IFrameContract
    {
        private string _lastDesktop;
        private Desktop _lastDesktopInput;


        public FrameInformation GetCleanFrame()
        {
            HandleDesktop();
            var setCurrent = Desktop.SetCurrent(_lastDesktopInput);
            return !setCurrent ? null : ScreenData.DesktopCapture();
        }

        public FrameInformation GetFullFrame()
        {
            HandleDesktop();
            var tempBounds = Display.GetWindowRectangle();
            var frameInfo = new FrameInformation
            {
                Bounds = tempBounds,
                ScreenImage = ScreenData.CaptureDesktop()
            };
            if (frameInfo.ScreenImage != null) return frameInfo;
            var bmp = new Bitmap(frameInfo.Bounds.Width, frameInfo.Bounds.Height);
            using (var gfx = Graphics.FromImage(bmp))
            using (var brush = new SolidBrush(Color.FromArgb(67, 75, 99)))
            {
                gfx.FillRectangle(brush, 0, 0, frameInfo.Bounds.Width, frameInfo.Bounds.Height);
            }
            frameInfo.ScreenImage = bmp;
            return frameInfo;
        }

        public bool KeepAlive()
        {
            return true;
        }

        private void HandleDesktop()
        {
            using (var inputDesktop = new Desktop())
            {
                inputDesktop.OpenInput();
                if (!inputDesktop.DesktopName.Equals(_lastDesktop))
                {
                    var switched = inputDesktop.Show();

                    if (switched)
                    {
                        var setCurrent = Desktop.SetCurrent(inputDesktop);
                        if (setCurrent)
                        {
                            Console.WriteLine($"Desktop switched from {_lastDesktop} to {inputDesktop.DesktopName}");
                            _lastDesktop = inputDesktop.DesktopName;
                            _lastDesktopInput = inputDesktop;
                        }
                        else
                        {
                            _lastDesktopInput.Close();
                        }
                    }
                }
                else
                {
                    inputDesktop.Close();
                }
            }
           
        }
    }
}
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using WindowsInput;
using WindowsInput.Native;
using AgentInterface;
using AgentInterface.Api.Models;
using AgentInterface.Api.System;
using AgentInterface.Api.Win32;

namespace UlteriusAgent.Networking
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class InputAgent : IInputContract
    {

        public void HandleRightMouseDown()
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                new InputSimulator().Mouse.RightButtonDown();
            }
        }

        public void HandleRightMouseUp()
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                new InputSimulator().Mouse.RightButtonUp();
            }

        }

        public void MoveMouse(int x, int y)
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                var bounds = Display.GetWindowRectangle();
                x = checked((int)Math.Round(x * (65535 / (double)bounds.Width)));
                y = checked((int)Math.Round(y * (65535 / (double)bounds.Height)));
                new InputSimulator().Mouse.MoveMouseTo(x, y);
            }
        }

        public void MouseScroll(bool positive)
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                var direction = positive ? 10 : -10;
                new InputSimulator().Mouse.VerticalScroll(direction);
            }

        }


        public void HandleLeftMouseDown()
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                new InputSimulator().Mouse.LeftButtonDown();
            }


        }

        public void HandleLeftMouseUp()
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                new InputSimulator().Mouse.LeftButtonUp();
            }


        }

        public void HandleKeyDown(List<int> keyCodes)
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                foreach (var code in keyCodes)
                {
                    var virtualKey = (VirtualKeyCode)code;
                    new InputSimulator().Keyboard.KeyDown(virtualKey);

                }
            }

        }

        public void HandleKeyUp(List<int> keyCodes)
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                foreach (var code in keyCodes)
                {
                    var virtualKey = (VirtualKeyCode)code;
                    new InputSimulator().Keyboard.KeyUp(virtualKey);
                }
            }

        }

        public void HandleRightClick()
        {
            var inputDesktop = new Desktop();
            inputDesktop.OpenInput();
            var setCurrent = Desktop.SetCurrent(inputDesktop);
            if (setCurrent)
            {
                new InputSimulator().Mouse.RightButtonClick();
            }
        }

        [HandleProcessCorruptedStateExceptions]
        public float GetGpuTemp(string gpuName)
        {
            return SystemData.GetGpuTemp(gpuName);
        }

        public List<DisplayInformation> GetDisplayInformation()
        {
            return Display.DisplayInformation();
        }


        public List<float> GetCpuTemps()
        {
            return SystemData.GetCpuTemps();
        }
    }
}
﻿#region

using System;
using System.Diagnostics;
using System.Linq;

#endregion

namespace UlteriusAgent.Networking
{
    public static class Tools
    {
        public static void KillAllButMe()
        {
            try
            {
                var current = Process.GetCurrentProcess();
                //kill any other agent that may be running
                var processes = Process.GetProcessesByName(current.ProcessName)
                    .Where(t => t.Id != current.Id)
                    .ToList();
                foreach (var process in processes)
                {
                    process.Kill();
                    process.WaitForExit();
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
    }
}
using System;
using System.Collections.ObjectModel;
using System.Net.Security;
using System.Runtime.InteropServices;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using AgentInterface;
using AgentInterface.Api.ScreenShare;
using UlteriusAgent.Networking;
  
        private const int SW_HIDE = 0;
        private const int SW_SHOW = 5;

        [DllImport("user32.dll")]
        private static extern bool SetProcessDPIAware();

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);


            if (Environment.OSVersion.Version.Major >= 6)
                SetProcessDPIAware();
            }
            var handle = GetConsoleWindow();

            // Hide
            ShowWindow(handle, SW_HIDE);

            Tools.KillAllButMe();
            try
                ScreenData.SetupDuplication();
                var inputAddress = "net.tcp://localhost/ulterius/agent/input/";
                var frameAddress = "net.pipe://localhost/ulterius/agent/frames/";
               
                var inputService = new ServiceHost(typeof(InputAgent));
                var frameService = new ServiceHost(typeof(FrameAgent));
                var inputBinding = new NetTcpBinding
                {
                    Security = new NetTcpSecurity
                    {
                        Transport = {ProtectionLevel = ProtectionLevel.None},
                        Mode = SecurityMode.None
                    },
                    MaxReceivedMessageSize = int.MaxValue
                };
                var frameBinding = new NetNamedPipeBinding
                    Security = new NetNamedPipeSecurity
                    {
                        Transport = { ProtectionLevel = ProtectionLevel.None },
                        Mode = NetNamedPipeSecurityMode.None
                    },
                    MaxReceivedMessageSize = int.MaxValue
                };
                inputService.AddServiceEndpoint(typeof(IInputContract), inputBinding, inputAddress);
                frameService.AddServiceEndpoint(typeof(IFrameContract), frameBinding, frameAddress);
                inputService.Opened += delegate(object sender, EventArgs eventArgs)
                 {
                     Console.WriteLine("Input started");
                 };
                frameService.Opened += delegate (object sender, EventArgs eventArgs)
                    Console.WriteLine("Frame started");
                };
                inputService.Open();
                frameService.Open();
                Console.WriteLine("Test");
                Console.Read();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + " \n " + ex.StackTrace);
            }
            Console.Read();
        }

        private static void host_faulted(object sender, EventArgs e)
        {
            
﻿<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{686AE4C4-791F-45EB-9414-029D6115905D}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>UlteriusAgent</RootNamespace>
    <AssemblyName>UlteriusAgent</AssemblyName>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.Windows.Forms" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Networking\InputAgent.cs" />
    <Compile Include="Networking\FrameAgent.cs" />
    <Compile Include="Networking\Tools.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config">
      <SubType>Designer</SubType>
    </None>
    <None Include="app.manifest" />
  </ItemGroup>
  <ItemGroup>
    <None Include="FodyWeavers.xml" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\inputsimulator2\WindowsInput\WindowsInput.csproj">
      <Project>{3549cd6f-80f8-450f-b99e-cf0a736b1f2a}</Project>
      <Name>WindowsInput</Name>
    </ProjectReference>
    <ProjectReference Include="..\AgentInterface\AgentInterface.csproj">
      <Project>{5c3b0b17-cbb7-4b4b-b527-1fab2bb96466}</Project>
      <Name>AgentInterface</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <UsingTask TaskName="CosturaCleanup" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" TaskFactory="CodeTaskFactory">
    <ParameterGroup>
      <Config Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem" />
      <Files Output="false" Required="true" ParameterType="Microsoft.Build.Framework.ITaskItem[]" />
    </ParameterGroup>
    <Task Evaluate="true">
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml" />
      <Reference xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Include="System.Xml.Linq" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" />
      <Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" />
      <Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault();

if (config == null) return true;

var excludedAssemblies = new List<string>();
var attribute = config.Attribute("ExcludeAssemblies");
if (attribute != null)
    foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);
var element = config.Element("ExcludeAssemblies");
if (element != null)
    foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
        excludedAssemblies.Add(item);

var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));

foreach (var item in filesToCleanup)
  File.Delete(item);
]]></Code>
    </Task>
  </UsingTask>
  <Target Name="CleanReferenceCopyLocalPaths" AfterTargets="AfterBuild;NonWinFodyTarget">
    <CosturaCleanup Config="FodyWeavers.xml" Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
  </Target>
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
﻿
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusServer", "RemoteTaskServer\UlteriusServer.csproj", "{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}"
	ProjectSection(ProjectDependencies) = postProject
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466} = {5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A} = {3549CD6F-80F8-450F-B99E-CF0A736B1F2A}
		{686AE4C4-791F-45EB-9414-029D6115905D} = {686AE4C4-791F-45EB-9414-029D6115905D}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusAgent", "UlteriusAgent\UlteriusAgent.csproj", "{686AE4C4-791F-45EB-9414-029D6115905D}"
	ProjectSection(ProjectDependencies) = postProject
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466} = {5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A} = {3549CD6F-80F8-450F-B99E-CF0A736B1F2A}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AgentInterface", "AgentInterface\AgentInterface.csproj", "{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInput", "..\inputsimulator2\WindowsInput\WindowsInput.csproj", "{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Release|Any CPU.Build.0 = Release|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Release|Any CPU.Build.0 = Release|Any CPU
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{5C3B0B17-CBB7-4B4B-B527-1FAB2BB96466}.Release|Any CPU.Build.0 = Release|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal

Fixed code:
.vs/
using vtortola.WebSockets.Http;
                var host = new Uri($"ws://{_client.HttpRequest.Headers[RequestHeader.Host]}", UriKind.Absolute);

                           

                                var targetPort = host.Port;
                    var targetPort = host.Port;
                var host = new Uri($"ws://{_client.HttpRequest.Headers[RequestHeader.Host]}", UriKind.Absolute);
                    var targetPort = host.Port;
using UlteriusServer.Api.Win32.ScreenShare.Models;
using UlteriusServer.Api.Win32;
           /* var device = _packet.Args[0].ToString();
            _builder.WriteMessage(formThread);*/
            /*var width = int.Parse(_packet.Args[0].ToString());
            _builder.WriteMessage(formThread);*/
            /*var width = int.Parse(_packet.Args[0].ToString());
            _builder.WriteMessage(formThread);*/
using UlteriusServer.Utilities;
            return SystemData.GetGpuTemp(gpuName);
using UlteriusServer.Api.Win32;
                var processStartInfo = new ProcessStartInfo(path);
                var process = new Process { StartInfo = processStartInfo };
                processStarted = process.Start();
                processId = process.Id;
using UlteriusServer.Api.Win32;
using UlteriusServer.Api.Win32.ScreenShare;
using UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication;
                var stream = new Thread(GetScreenFrame) { IsBackground = true };
                if (RunningAsService && DesktopWatcher.CurrentDesktop != null)
                {
                    Desktop.SetCurrent(DesktopWatcher.CurrentDesktop);
                }
            if (RunningAsService && DesktopWatcher.CurrentDesktop != null)
            {
                Desktop.SetCurrent(DesktopWatcher.CurrentDesktop);
            }
                    HandleFullFrame();
            new InputSimulator().Mouse.RightButtonUp();
            new InputSimulator().Mouse.RightButtonDown();
            foreach (var code in codes)
                var virtualKey = (VirtualKeyCode)code;
                new InputSimulator().Keyboard.KeyUp(virtualKey);
            foreach (var code in codes)
                var virtualKey = (VirtualKeyCode)code;
                new InputSimulator().Keyboard.KeyDown(virtualKey);
            new InputSimulator().Mouse.VerticalScroll(direction);
                var bounds = Display.GetWindowRectangle();
                x = checked((int)Math.Round(x * (65535 / (double)bounds.Width)));
                y = checked((int)Math.Round(y * (65535 / (double)bounds.Height)));
                new InputSimulator().Mouse.MoveMouseTo(x, y);
                //Console.WriteLine("Error moving mouse");
            new InputSimulator().Mouse.RightButtonClick();
            new InputSimulator().Mouse.LeftButtonUp();
            new InputSimulator().Mouse.LeftButtonDown();
using UlteriusServer.Utilities;
using UlteriusServer.Utilities;
using System.Windows.Forms;
using UlteriusServer.Api.Win32;
using UlteriusServer.Api.Win32.ScreenShare.Models;
using SystemInformation = UlteriusServer.Api.Network.Models.SystemInformation;
            var displays = new List<DisplayInformation>();
            for (var i = 0; i < Screen.AllScreens.Length; i++)
            {
                var friendly = Display.GetDeviceFriendlyName(i);
                var display = new DisplayInformation {FriendlyName = friendly};
                var currentScreen = Screen.AllScreens[i];
                display.CurrentResolution = new ResolutionInformation
                {
                    BitsPerPixel = currentScreen.BitsPerPixel,
                    Frequency = 60,
                    Height = currentScreen.Bounds.Height,
                    Width = currentScreen.Bounds.Width,
                    Orientation = "Unknown",
                    X = currentScreen.Bounds.X,
                    Y = currentScreen.Bounds.Y
                };
                displays.Add(display);
            }
            return displays;
            return SystemData.GetCpuTemps();
            return string.IsNullOrEmpty(_motherBoard) ? "Board Unknown" : _motherBoard;
                totalBytesReceived += networkInterface?.GetIPv4Statistics()?.BytesReceived ?? 0;
                totalBytesSent += networkInterface?.GetIPv4Statistics()?.BytesSent ?? 0;
                totalNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces()?.Length ?? 0,
using UlteriusServer.Utilities;
using System.Diagnostics;
using UlteriusServer.Api.Win32;
            var file = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Ulterius Updater.exe /silentall -nofreqcheck");
            Process.Start(file);
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using OpenHardwareMonitor.Hardware;

namespace UlteriusServer.Api
{
    public class SystemData
    {

        [HandleProcessCorruptedStateExceptions]
        public static float GetGpuTemp(string gpuName)
        {
            try
            {
                var myComputer = new Computer();
                myComputer.Open();
                //possible fix for gpu temps on laptops
                myComputer.GPUEnabled = true;
                float temp = -1;
                foreach (var hardwareItem in myComputer.Hardware)
                {
                    hardwareItem.Update();
                    switch (hardwareItem.HardwareType)
                    {
                        case HardwareType.GpuNvidia:
                            foreach (
                                var sensor in
                                hardwareItem.Sensors.Where(
                                    sensor =>
                                        sensor.SensorType == SensorType.Temperature &&
                                        hardwareItem.Name.Contains(gpuName)))
                            {
                                if (sensor.Value != null)
                                {
                                    temp = (float)sensor.Value;
                                }
                            }
                            break;
                        case HardwareType.GpuAti:
                            foreach (
                                var sensor in
                                hardwareItem.Sensors.Where(
                                    sensor =>
                                        sensor.SensorType == SensorType.Temperature &&
                                        hardwareItem.Name.Contains(gpuName)))
                            {
                                if (sensor.Value != null)
                                {
                                    temp = (float)sensor.Value;
                                }
                            }
                            break;
                    }
                }
                myComputer.Close();
                return temp;
            }
            catch (AccessViolationException)
            {
                return -1;
            }
        }

        public static List<float> GetCpuTemps()
        {
            var myComputer = new Computer();
            myComputer.Open();
            myComputer.CPUEnabled = true;
            var tempTemps = new List<float>();
            var procCount = Environment.ProcessorCount;
            for (var i = 0; i < procCount; i++)
            {
                tempTemps.Add(-1);
            }
            try
            {
                var temps = (from hardwareItem in myComputer.Hardware
                    where hardwareItem.HardwareType == HardwareType.CPU
                    from sensor in hardwareItem.Sensors
                    where sensor.SensorType == SensorType.Temperature
                    let value = sensor.Value
                    where value != null
                    where value != null
                    select (float)value).ToList();
                if (temps.Count != 0) return temps;
                myComputer.Close();
                return tempTemps;
            }
            catch (Exception)
            {
                myComputer.Close();
                return tempTemps;
            }
        }

    }
}
﻿#region

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UlteriusServer.Api.Network;
using UlteriusServer.Api.Network.Messages;
using UlteriusServer.Api.Services.LocalSystem;
using UlteriusServer.Api.Services.Network;
using UlteriusServer.Api.Services.Update;
using UlteriusServer.Forms.Utilities;
using UlteriusServer.Utilities;
using UlteriusServer.Utilities.Security;
using UlteriusServer.WebSocketAPI;
using UlteriusServer.WebSocketAPI.Authentication;
using vtortola.WebSockets;
using vtortola.WebSockets.Http;
using ScreenShareService = UlteriusServer.Api.Services.LocalSystem.ScreenShareService;

#endregion

namespace UlteriusServer.Api
{
    internal class UlteriusApiServer
    {
        public static ConcurrentDictionary<Guid, AuthClient> AllClients { get; set; }
        public static bool RunningAsService { get; set; }
        public static ScreenShareService ScreenShareService { get; set; }
        public static FileSearchService FileSearchService { get; set; }
        public static CronJobService CronJobService { get; set; }
        private static int _bufferSize = 1024 * 8;
        private static int _bufferPoolSize;

        /// <summary>
        ///     Start the API Server
        /// </summary>
        public static void Start()
        {
            _bufferPoolSize = 100 * _bufferSize;
            PacketLoader.LoadPackets();
            var config = Config.Load();
            var clientUpdateService = new UpdateService();
            clientUpdateService.Start();
            FileSearchService = new FileSearchService(Path.Combine(AppEnvironment.DataPath, "fileIndex.db"));
            FileSearchService.Start();
            CronJobService = new CronJobService(Path.Combine(AppEnvironment.DataPath, "jobs.json"), Path.Combine(AppEnvironment.DataPath, "scripts"));
            CronJobService.ConfigureJobs();
            var apiPort = config.TaskServer.TaskServerPort;
            AllClients = new ConcurrentDictionary<Guid, AuthClient>();
            ScreenShareService = new ScreenShareService();
            var address = NetworkService.GetAddress();
            var webCamPort = config.Webcams.WebcamPort;
            var screenSharePort = config.ScreenShareService.ScreenSharePort;
            var listenEndPoints = new Uri[] {
                new Uri($"ws://{address}:{apiPort}"),
                new Uri($"ws://{address}:{webCamPort}"),
                new Uri($"ws://{address}:{screenSharePort}")
            };
            var options = new WebSocketListenerOptions
            {
                PingMode = PingMode.LatencyControl,
                NegotiationTimeout = TimeSpan.FromSeconds(30),
                PingTimeout = TimeSpan.FromSeconds(5),
                ParallelNegotiations = 16,
                NegotiationQueueCapacity = 256,
                BufferManager = BufferManager.CreateBufferManager(_bufferPoolSize, _bufferSize),
                Logger = NullLogger.Instance,
                HttpAuthenticationHandler = async (request, response) =>
                {
                    await Task.Delay(TimeSpan.FromMilliseconds(1));
                    if (request.Cookies["ConnectionId"] == null)
                        response.Cookies.Add(new Cookie("ConnectionId", Guid.NewGuid().ToString()));
                    return true;
                }
            };
            options.Transports.ConfigureTcp(tcp =>
            {
                tcp.BacklogSize = 1000; // max pending connections waiting to be accepted
                tcp.ReceiveBufferSize = _bufferSize;
                tcp.SendBufferSize = _bufferSize;
                tcp.LingerState = new LingerOption(true, 0);
                tcp.NoDelay = true;
                tcp.IsAsync = true;
                
                tcp.ReceiveTimeout = TimeSpan.FromSeconds(1);
                tcp.SendTimeout = TimeSpan.FromSeconds(3);
            });

            var server = new WebSocketEventListener(listenEndPoints, options);
            server.OnConnect += HandleConnect;
            server.OnDisconnect += HandleDisconnect;
            server.OnPlainTextMessage += HandlePlainTextMessage;
            server.OnEncryptedMessage += HandleEncryptedMessage;
            server.OnError += HandleError;
            server.Start();
            Log("Api Server started at " + address);
        }

        


        /// <summary>
        ///     Handles encrypted binary messages
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="message"></param>
        private static void HandleEncryptedMessage(WebSocket clientSocket, byte[] message)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            if (AllClients.TryGetValue(connectionId, out authClient))
            {
                var packetManager = new PacketManager(authClient, clientSocket, message);
                var packet = packetManager.GetPacket();
                packet?.HandlePacket();
            }
        }

        private static void HandleError(WebSocket websocket, Exception error)
        {
            Console.WriteLine(error.StackTrace + " " + error.Message);
        }

        /// <summary>
        ///     Handles plaintext JSON packets.
        /// </summary>
        /// <param name="clientSocket"></param>
        /// <param name="message"></param>
        private static void HandlePlainTextMessage(WebSocket clientSocket, string message)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            if (AllClients.TryGetValue(connectionId, out authClient))
            {
                var packetManager = new PacketManager(authClient, clientSocket, message);
                var packet = packetManager.GetPacket();
                packet?.HandlePacket();
            }
        }


        /// <summary>
        ///     Remove a client when it disconnects
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void HandleDisconnect(WebSocket clientSocket)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient temp = null;
            if (AllClients.TryRemove(connectionId, out temp))
            {
                Console.WriteLine("Disconnection from " + clientSocket.RemoteEndpoint);
                var userCount = AllClients.Count;
                var extra = userCount < 1 ? "s" : string.Empty;
                UlteriusTray.ShowMessage($"There are now {userCount} user{extra} connected.", "A user disconnected!");
            }
        }

        /// <summary>
        ///     When a client connects, assign them a unique RSA keypair for handshake.
        /// </summary>
        /// <param name="clientSocket"></param>
        private static async void HandleConnect(WebSocket clientSocket)
        {
            var connectionId = CookieManager.GetConnectionId(clientSocket);
            AuthClient authClient;
            AllClients.TryGetValue(connectionId, out authClient);
            var host = new Uri($"ws://{clientSocket.HttpRequest.Headers[RequestHeader.Host]}", UriKind.Absolute);

            if (authClient != null)
            {

                if (RunningAsService)
                {
                    MessageQueueManager agentManager;
                    if (!authClient.MessageQueueManagers.TryGetValue(22005, out agentManager))
                    {
                        if (authClient.MessageQueueManagers.TryAdd(22005,
                            new MessageQueueManager()))
                        {
                            Console.WriteLine("Service Manager Started");
                        }
                    }
                }
                MessageQueueManager manager;
                //check if a manager for that port exist, if not, create one
                
                if (!authClient.MessageQueueManagers.TryGetValue(host.Port, out manager))
                {
                    if (authClient.MessageQueueManagers.TryAdd(host.Port,
                        new MessageQueueManager()))
                    {
                        Console.WriteLine($"Manager started for {host.Port}");
                    }
                }
                return;
            }
            Console.WriteLine("Connection from " + clientSocket.RemoteEndpoint);
            var rsa = new Rsa();
            rsa.GenerateKeyPairs();
            var client = new AuthClient
            {
                PublicKey = rsa.PublicKey,
                PrivateKey = rsa.PrivateKey,
                MessageQueueManagers = new ConcurrentDictionary<int, MessageQueueManager>()
            };
          
            client.MessageQueueManagers.TryAdd(host.Port, new MessageQueueManager());
            AllClients.AddOrUpdate(connectionId, client, (key, value) => value);
            await SendWelcomeMessage(client, clientSocket);
        }

        /// <summary>
        ///     Sends a new user their unique RSA keypair
        /// </summary>
        /// <param name="client"></param>
        /// <param name="clientSocket"></param>
        private static async Task SendWelcomeMessage(AuthClient client, WebSocket clientSocket)
        {
            var welcomeMessage = JsonConvert.SerializeObject(new
            {
                endpoint = "connectedToUlterius",
                results = new
                {
                    message = "Ulterius server online!",
                    publicKey = Rsa.SecureStringToString(client.PublicKey)
                }
            });
            if (clientSocket != null)
            {
                try
                {
                    await clientSocket.WriteStringAsync(welcomeMessage, CancellationToken.None);
                    var userCount = AllClients.Count;
                    var extra = userCount > 1 ? "s" : string.Empty;
                    UlteriusTray.ShowMessage($"There are now {userCount} user{extra} connected.", "A new user connected!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to write welcome message " + ex.Message );
                }
            }
        }

        private static void Log(string message)
        {
            Console.WriteLine(message);
        }
    }
namespace UlteriusServer.Api.Win32
        public static extern int GetCurrentThreadId();
﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace UlteriusServer.Api.Win32
{
    public class DesktopWatcher
    {
        private static string _lastDesktop;
        private static Desktop _lastDesktopInput;
        public static void Start()
        {
            var backgroundThread = new Thread(WatchDesktop) { IsBackground = true };
            backgroundThread.Start();
            Console.WriteLine($"Desktop Task is running on thread: {Desktop.GetCurrentThreadId()}");
        }

        private static void WatchDesktop()
        {
            while (true)
            {
                try
                {
                    using (var inputDesktop = new Desktop())
                    {
                        inputDesktop.OpenInput();
                        if (!inputDesktop.DesktopName.Equals(_lastDesktop))
                        {
                            if (inputDesktop.Show() && Desktop.SetCurrent(inputDesktop))
                            {
                               Console.WriteLine($"Desktop switched from {_lastDesktop} to {inputDesktop.DesktopName} on thread {Desktop.GetCurrentThreadId()}");
                                _lastDesktop = inputDesktop.DesktopName;
                                _lastDesktopInput = inputDesktop;
                                CurrentDesktop = inputDesktop;
                            }
                            else
                            {
                                var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                                Console.WriteLine(errorMessage);
                                _lastDesktopInput?.Close();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message, ex);
                }
                Thread.Sleep(1000);
            }
        }

        public static string CurrentDesktopName { get; set; }

        public static Desktop CurrentDesktop { get; set; }
    }
}
﻿#region

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;

#endregion

namespace UlteriusServer.Api.Win32
{
    public class Monitor
    {
        public Rectangle Rect { get; set; }
        public Rectangle WorkRect { get; set; }
        public bool Primary { get; set; }
        public string DeviceName { get; set; }
    }

    public class Display
    {

       
        private static IEnumerable<string> GetAllMonitorsFriendlyNames()
        {
            uint pathCount, modeCount;
            var error = GetDisplayConfigBufferSizes(QueryDeviceConfigFlags.QdcOnlyActivePaths, out pathCount,
                out modeCount);
            if (error != ErrorSuccess)
                throw new System.ComponentModel.Win32Exception(error);

            var displayPaths = new DisplayconfigPathInfo[pathCount];
            var displayModes = new DisplayconfigModeInfo[modeCount];
            error = QueryDisplayConfig(QueryDeviceConfigFlags.QdcOnlyActivePaths,
                ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
            if (error != ErrorSuccess)
                throw new System.ComponentModel.Win32Exception(error);

            for (var i = 0; i < modeCount; i++)
                if (displayModes[i].infoType == DisplayconfigModeInfoType.DisplayconfigModeInfoTypeTarget)
                    yield return MonitorFriendlyName(displayModes[i].adapterId, displayModes[i].id);
        }

        public static string GetDeviceFriendlyName(int screenIndex)
        {
            var allFriendlyNames = GetAllMonitorsFriendlyNames().ToList();
            if (screenIndex > allFriendlyNames.Count)
            {
                return null;
            }
            return allFriendlyNames.ElementAtOrDefault(screenIndex) ?? "Unknown";
        }

        private static string MonitorFriendlyName(Luid adapterId, uint targetId)
        {
            var deviceName = new DisplayconfigTargetDeviceName
            {
                header =
                {
                    size = (uint) Marshal.SizeOf(typeof(DisplayconfigTargetDeviceName)),
                    adapterId = adapterId,
                    id = targetId,
                    type = DisplayconfigDeviceInfoType.DisplayconfigDeviceInfoGetTargetName
                }
            };
            var error = DisplayConfigGetDeviceInfo(ref deviceName);
            if (error != ErrorSuccess)
                throw new System.ComponentModel.Win32Exception(error);
            return deviceName.monitorFriendlyDeviceName;
        }

        public const int ErrorSuccess = 0;
        [DllImport("user32.dll")]
        public static extern int GetDisplayConfigBufferSizes(
            QueryDeviceConfigFlags flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);

        [DllImport("user32.dll")]
        public static extern int QueryDisplayConfig(
            QueryDeviceConfigFlags flags,
            ref uint numPathArrayElements, [Out] DisplayconfigPathInfo[] pathInfoArray,
            ref uint numModeInfoArrayElements, [Out] DisplayconfigModeInfo[] modeInfoArray,
            IntPtr currentTopologyId
        );
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigTargetDeviceNameFlags
        {
            public uint value;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigDeviceInfoHeader
        {
            public DisplayconfigDeviceInfoType type;
            public uint size;
            public Luid adapterId;
            public uint id;
        }

        public enum DisplayconfigDeviceInfoType : uint
        {
            DisplayconfigDeviceInfoGetSourceName = 1,
            DisplayconfigDeviceInfoGetTargetName = 2,
            DisplayconfigDeviceInfoGetTargetPreferredMode = 3,
            DisplayconfigDeviceInfoGetAdapterName = 4,
            DisplayconfigDeviceInfoSetTargetPersistence = 5,
            DisplayconfigDeviceInfoGetTargetBaseType = 6,
            DisplayconfigDeviceInfoForceUint32 = 0xFFFFFFFF
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct DisplayconfigTargetDeviceName
        {
            public DisplayconfigDeviceInfoHeader header;
            public DisplayconfigTargetDeviceNameFlags flags;
            public DisplayconfigVideoOutputTechnology outputTechnology;
            public ushort edidManufactureId;
            public ushort edidProductCodeId;
            public uint connectorInstance;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string monitorFriendlyDeviceName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string monitorDevicePath;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigModeInfo
        {
            public DisplayconfigModeInfoType infoType;
            public uint id;
            public Luid adapterId;
            public DisplayconfigModeInfoUnion modeInfo;
        }
        [DllImport("user32.dll")]
        public static extern int DisplayConfigGetDeviceInfo(ref DisplayconfigTargetDeviceName deviceName);

        public enum QueryDeviceConfigFlags : uint
        {
            QdcAllPaths = 0x00000001,
            QdcOnlyActivePaths = 0x00000002,
            QdcDatabaseCurrent = 0x00000004
        }
        public enum DisplayconfigModeInfoType : uint
        {
            DisplayconfigModeInfoTypeSource = 1,
            DisplayconfigModeInfoTypeTarget = 2,
            DisplayconfigModeInfoTypeForceUint32 = 0xFFFFFFFF
        }
        [StructLayout(LayoutKind.Explicit)]
        public struct DisplayconfigModeInfoUnion
        {
            [FieldOffset(0)] public DisplayconfigTargetMode targetMode;

            [FieldOffset(0)] public DisplayconfigSourceMode sourceMode;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigTargetMode
        {
            public DisplayconfigVideoSignalInfo targetVideoSignalInfo;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathInfo
        {
            public DisplayconfigPathSourceInfo sourceInfo;
            public DisplayconfigPathTargetInfo targetInfo;
            public uint flags;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigSourceMode
        {
            public uint width;
            public uint height;
            public DisplayconfigPixelformat pixelFormat;
            public Pointl position;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathSourceInfo
        {
            public Luid adapterId;
            public uint id;
            public uint modeInfoIdx;
            public uint statusFlags;
        }

        public static Rectangle GetWindowRectangle()
        {
            var scBounds = new RECT();
            GetWindowRect(GetDesktopWindow(), ref scBounds);
            return scBounds;
        }

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);



        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();


        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left, Top, Right, Bottom;

            public RECT(int left, int top, int right, int bottom)
            {
                Left = left;
                Top = top;
                Right = right;
                Bottom = bottom;
            }

            public RECT(Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom)
            {
            }

            public int X
            {
                get => Left;
                set
                {
                    Right -= Left - value;
                    Left = value;
                }
            }

            public int Y
            {
                get => Top;
                set
                {
                    Bottom -= Top - value;
                    Top = value;
                }
            }

            public int Height
            {
                get => Bottom - Top;
                set => Bottom = value + Top;
            }

            public int Width
            {
                get => Right - Left;
                set => Right = value + Left;
            }


            public Size Size
            {
                get => new Size(Width, Height);
                set
                {
                    Width = value.Width;
                    Height = value.Height;
                }
            }

            public static implicit operator Rectangle(RECT r)
            {
                return new Rectangle(r.Left, r.Top, r.Width, r.Height);
            }

            public static implicit operator RECT(Rectangle r)
            {
                return new RECT(r);
            }

            public static bool operator ==(RECT r1, RECT r2)
            {
                return r1.Equals(r2);
            }

            public static bool operator !=(RECT r1, RECT r2)
            {
                return !r1.Equals(r2);
            }

            public bool Equals(RECT r)
            {
                return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
            }

            public override bool Equals(object obj)
            {
                if (obj is RECT)
                    return Equals((RECT)obj);
                if (obj is Rectangle)
                    return Equals(new RECT((Rectangle)obj));
                return false;
            }

            public override int GetHashCode()
            {
                return ((Rectangle)this).GetHashCode();
            }

            public override string ToString()
            {
                return string.Format(CultureInfo.CurrentCulture, "{{Left={0},Top={1},Right={2},Bottom={3}}}", Left, Top,
                    Right, Bottom);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Displayconfig2Dregion
        {
            public uint cx;
            public uint cy;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct Pointl
        {
            private readonly int x;
            private readonly int y;
        }
        public enum DisplayconfigPixelformat : uint
        {
            DisplayconfigPixelformat8Bpp = 1,
            DisplayconfigPixelformat16Bpp = 2,
            DisplayconfigPixelformat24Bpp = 3,
            DisplayconfigPixelformat32Bpp = 4,
            DisplayconfigPixelformatNongdi = 5,
            DisplayconfigPixelformatForceUint32 = 0xffffffff
        }
        public struct DisplayconfigVideoSignalInfo
        {
            public ulong pixelRate;
            public DisplayconfigRational hSyncFreq;
            public DisplayconfigRational vSyncFreq;
            public Displayconfig2Dregion activeSize;
            public Displayconfig2Dregion totalSize;
            public uint videoStandard;
            public DisplayconfigScanlineOrdering scanLineOrdering;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigPathTargetInfo
        {
            public Luid adapterId;
            public uint id;
            public uint modeInfoIdx;
            private readonly DisplayconfigVideoOutputTechnology outputTechnology;
            private readonly DisplayconfigRotation rotation;
            private readonly DisplayconfigScaling scaling;
            private readonly DisplayconfigRational refreshRate;
            private readonly DisplayconfigScanlineOrdering scanLineOrdering;
            public bool targetAvailable;
            public uint statusFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct Luid
        {
            public uint LowPart;
            public int HighPart;
        }


        public enum DisplayconfigScanlineOrdering : uint
        {
            DisplayconfigScanlineOrderingUnspecified = 0,
            DisplayconfigScanlineOrderingProgressive = 1,
            DisplayconfigScanlineOrderingInterlaced = 2,
            DisplayconfigScanlineOrderingInterlacedUpperfieldfirst = DisplayconfigScanlineOrderingInterlaced,
            DisplayconfigScanlineOrderingInterlacedLowerfieldfirst = 3,
            DisplayconfigScanlineOrderingForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigVideoOutputTechnology : uint
        {
            DisplayconfigOutputTechnologyOther = 0xFFFFFFFF,
            DisplayconfigOutputTechnologyHd15 = 0,
            DisplayconfigOutputTechnologySvideo = 1,
            DisplayconfigOutputTechnologyCompositeVideo = 2,
            DisplayconfigOutputTechnologyComponentVideo = 3,
            DisplayconfigOutputTechnologyDvi = 4,
            DisplayconfigOutputTechnologyHdmi = 5,
            DisplayconfigOutputTechnologyLvds = 6,
            DisplayconfigOutputTechnologyDJpn = 8,
            DisplayconfigOutputTechnologySdi = 9,
            DisplayconfigOutputTechnologyDisplayportExternal = 10,
            DisplayconfigOutputTechnologyDisplayportEmbedded = 11,
            DisplayconfigOutputTechnologyUdiExternal = 12,
            DisplayconfigOutputTechnologyUdiEmbedded = 13,
            DisplayconfigOutputTechnologySdtvdongle = 14,
            DisplayconfigOutputTechnologyMiracast = 15,
            DisplayconfigOutputTechnologyInternal = 0x80000000,
            DisplayconfigOutputTechnologyForceUint32 = 0xFFFFFFFF
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DisplayconfigRational
        {
            public uint Numerator;
            public uint Denominator;
        }

        public enum DisplayconfigRotation : uint
        {
            DisplayconfigRotationIdentity = 1,
            DisplayconfigRotationRotate90 = 2,
            DisplayconfigRotationRotate180 = 3,
            DisplayconfigRotationRotate270 = 4,
            DisplayconfigRotationForceUint32 = 0xFFFFFFFF
        }

        public enum DisplayconfigScaling : uint
        {
            DisplayconfigScalingIdentity = 1,
            DisplayconfigScalingCentered = 2,
            DisplayconfigScalingStretched = 3,
            DisplayconfigScalingAspectratiocenteredmax = 4,
            DisplayconfigScalingCustom = 5,
            DisplayconfigScalingPreferred = 128,
            DisplayconfigScalingForceUint32 = 0xFFFFFFFF
        }
        public const int MONITORINFOF_PRIMARY = 0x1;
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct MONITORINFOEX
        {
            public int cbSize;
            public RECT rcMonitor;
            public RECT rcWork;
            public int dwFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string szDevice;
        }
        public delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);
        [DllImport("User32.dll", CharSet = CharSet.Unicode)]
        public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi);

        [DllImport("User32.dll", CharSet = CharSet.Unicode)]
        public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);

        private static List<Monitor> GetMonitors()
        {
            List<Monitor> monitors = new List<Monitor>();

            EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero,
                (IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData) =>
                {
                    MONITORINFOEX monitorInfo = new MONITORINFOEX();
                    monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFOEX));

                    GetMonitorInfo(hMonitor, ref monitorInfo);

                    monitors.Add(new Monitor()
                    {
                        Primary = (monitorInfo.dwFlags & MONITORINFOF_PRIMARY) != 0,
                        DeviceName = monitorInfo.szDevice,
                        Rect = Rectangle.FromLTRB(monitorInfo.rcMonitor.Left,
                            monitorInfo.rcMonitor.Top,
                            monitorInfo.rcMonitor.Right,
                            monitorInfo.rcMonitor.Bottom),
                        WorkRect = Rectangle.FromLTRB(monitorInfo.rcWork.Left,
                            monitorInfo.rcWork.Top,
                            monitorInfo.rcWork.Right,
                            monitorInfo.rcWork.Bottom)
                    });

                    return true;
                },
                IntPtr.Zero
            );

            return monitors;
        }
        public static int X { get; set; }

        public static int Y { get; set; }

        public static int Height { get; set; }

        public static int Width { get; set; }
    }
}
namespace UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication
﻿#region

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
using Device = SharpDX.Direct3D11.Device;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using Point = System.Drawing.Point;
using Rectangle = SharpDX.Rectangle;
using Resource = SharpDX.DXGI.Resource;
using ResultCode = SharpDX.DXGI.ResultCode;

#endregion

namespace UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication
{
    /// <summary>
    ///     Provides access to frame-by-frame updates of a particular desktop (i.e. one monitor), with image and cursor
    ///     information.
    /// </summary>
    public class DesktopDuplicator
    {
        private readonly OutputDuplication _mDeskDupl;
        private readonly Device _mDevice;
        private readonly Texture2DDescription _mTextureDesc;
        private readonly int _mWhichOutputDevice;
        private Texture2D _desktopImageTexture;

        private Bitmap _finalImage1, _finalImage2;
        private OutputDuplicateFrameInformation _frameInfo;
        private bool _isFinalImage1;
        private OutputDescription _mOutputDesc;

        /// <summary>
        /// Duplicates the output of the specified monitor.
        /// </summary>
        /// <param name="whichMonitor">The output device to duplicate (i.e. monitor). Begins with zero, which seems to correspond to the primary monitor.</param>
        public DesktopDuplicator(int whichMonitor)
            : this(0, whichMonitor) { }

        /// <summary>
        ///     Duplicates the output of the specified monitor on the specified graphics adapter.
        /// </summary>
        /// <param name="whichGraphicsCardAdapter">The adapter which contains the desired outputs.</param>
        /// <param name="whichOutputDevice">
        ///     The output device to duplicate (i.e. monitor). Begins with zero, which seems to
        ///     correspond to the primary monitor.
        /// </param>
        public DesktopDuplicator(int whichGraphicsCardAdapter, int whichOutputDevice)
        {
            _mWhichOutputDevice = whichOutputDevice;
            Adapter1 adapter;
            try
            {
                adapter = new Factory1().GetAdapter1(whichGraphicsCardAdapter);
            }
            catch (SharpDXException)
            {
                throw new DesktopDuplicationException("Could not find the specified graphics card adapter.");
            }
           _mDevice = new Device(adapter);
            Output output = null;
            try
            {
                output = adapter.GetOutput(whichOutputDevice);
            }
            catch (SharpDXException)
            {
                throw new DesktopDuplicationException("Could not find the specified output device.");
            }
            var output1 = output.QueryInterface<Output1>();
            _mOutputDesc = output.Description;
            _mTextureDesc = new Texture2DDescription()
            {
                CpuAccessFlags = CpuAccessFlags.Read,
                BindFlags = BindFlags.None,
                Format = Format.B8G8R8A8_UNorm,
                Width = ((Rectangle)_mOutputDesc.DesktopBounds).Width,
                Height = ((Rectangle)_mOutputDesc.DesktopBounds).Height,
                OptionFlags = ResourceOptionFlags.None,
                MipLevels = 1,
                ArraySize = 1,
                SampleDescription = { Count = 1, Quality = 0 },
                Usage = ResourceUsage.Staging
            };

            try
            {
                _mDeskDupl = output1.DuplicateOutput(_mDevice);
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Code == ResultCode.NotCurrentlyAvailable.Result.Code)
                {
                    throw new DesktopDuplicationException("There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again.");
                }
            }
        }

        private Bitmap FinalImage
        {
            get => _isFinalImage1 ? _finalImage1 : _finalImage2;
            set
            {
                if (_isFinalImage1)
                {
                    _finalImage2 = value;
                    _finalImage1?.Dispose();
                }
                else
                {
                    _finalImage1 = value;
                    _finalImage2?.Dispose();
                }
                _isFinalImage1 = !_isFinalImage1;
            }
        }

        /// <summary>
        ///     Finds the most capable graphics card.
        /// </summary>
        /// <returns></returns>
        private static Adapter1 GetBestAdapter(out int bestAdapterIndex)
        {
            using (var dxgiFactory = new Factory1())
            {
                Adapter1 bestAdapter = null;
                bestAdapterIndex = -1;
                var adapterIndex = -1;
                long bestVideoMemory = 0;
                long bestSystemMemory = 0;

                foreach (var dxgiAdapter in dxgiFactory.Adapters1)
                {
                    adapterIndex++;

                    // not skip the render only WARP device
                    if (dxgiAdapter.Description.VendorId != 0x1414 || dxgiAdapter.Description.DeviceId != 0x8c)
                        if (dxgiAdapter.Outputs == null || dxgiAdapter.Outputs.Length == 0)
                            continue;

                    var level = Device.GetSupportedFeatureLevel(dxgiAdapter);

                    if (level < FeatureLevel.Level_11_0)
                        continue;
                    long videoMemory = (uint) dxgiAdapter.Description.DedicatedVideoMemory;
                    long systemMemory = (uint) dxgiAdapter.Description.DedicatedSystemMemory;

                    if (bestAdapter != null && videoMemory <= bestVideoMemory &&
                        (videoMemory != bestVideoMemory || systemMemory <= bestSystemMemory)) continue;
                    bestAdapter = dxgiAdapter;
                    bestAdapterIndex = adapterIndex;
                    bestVideoMemory = videoMemory;
                    bestSystemMemory = systemMemory;
                }

                return bestAdapter;
            }
        }

        /// <summary>
        ///     Retrieves the latest desktop image and associated metadata.
        /// </summary>
        public DesktopFrame GetLatestFrame()
        {
            var frame = new DesktopFrame();
            // Try to get the latest frame; this may timeout
            var retrievalTimedOut = RetrieveFrame();
            if (retrievalTimedOut)
                return null;
            try
            {
                RetrieveFrameMetadata(frame);
                //we don't need cursor info
                //RetrieveCursorMetadata(frame);
                //we dont need a full frame
                //ProcessFrame(frame);
            }
            catch
            {
                ReleaseFrame();
            }
            try
            {
                ReleaseFrame();
            }
            catch
            {
                //    throw new DesktopDuplicationException("Couldn't release frame.");  
            }
            return frame;
        }

        private bool RetrieveFrame()
        {
            if (_desktopImageTexture == null)
                _desktopImageTexture = new Texture2D(_mDevice, _mTextureDesc);
            Resource desktopResource = null;
            _frameInfo = new OutputDuplicateFrameInformation();
            try
            {
                _mDeskDupl.AcquireNextFrame(500, out _frameInfo, out desktopResource);
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Code == ResultCode.WaitTimeout.Result.Code)
                    return true;
                if (ex.ResultCode.Failure)
                {
                    //return true;
                    desktopResource?.Dispose();
                    throw new DesktopDuplicationException("Failed to acquire next frame.");
                }
            }
            using (var tempTexture = desktopResource?.QueryInterface<Texture2D>())
            {
                _mDevice.ImmediateContext.CopyResource(tempTexture, _desktopImageTexture);
            }
            desktopResource?.Dispose();
            return false;
        }

        private void RetrieveFrameMetadata(DesktopFrame frame)
        {
            if (_frameInfo.TotalMetadataBufferSize > 0)
            {
                // Get moved regions
                var movedRegionsLength = 0;
                var movedRectangles = new OutputDuplicateMoveRectangle[_frameInfo.TotalMetadataBufferSize];
                _mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out movedRegionsLength);
                frame.MovedRegions =
                    new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];
                for (var i = 0; i < frame.MovedRegions.Length; i++)
                {
                    var destRect = (Rectangle) movedRectangles[i].DestinationRect;
                    frame.MovedRegions[i] = new MovedRegion
                    {
                        Source = new Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y),
                        Destination =
                            new System.Drawing.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height)
                    };
                }

                // Get dirty regions
                var dirtyRegionsLength = 0;
                var dirtyRectangles = new RawRectangle[_frameInfo.TotalMetadataBufferSize];
                _mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out dirtyRegionsLength);
                frame.UpdatedRegions =
                    new System.Drawing.Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))];
                frame.FinishedRegions = new FinishedRegions[frame.UpdatedRegions.Length];
                for (var i = 0; i < frame.UpdatedRegions.Length; i++)
                {
                    var dirtyRect = (Rectangle) dirtyRectangles[i];
                    var rect = new System.Drawing.Rectangle(dirtyRect.X, dirtyRect.Y, dirtyRect.Width,
                        dirtyRect.Height);


                    frame.FinishedRegions[i] = new FinishedRegions
                    {
                        Destination = rect,
                        Frame = ExtractRect(rect.X, rect.Y, rect.Width, rect.Height)
                    };
                }
            }
            else
            {
                frame.MovedRegions = new MovedRegion[0];
                frame.UpdatedRegions = new System.Drawing.Rectangle[0];
            }
        }


        private Bitmap ExtractRect(int originX, int originY, int width, int height)
        {
            // Get the desktop capture screenTexture
            var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read,
                MapFlags.None);

            // Create Drawing.Bitmap

            var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); //不能是ARGB
            var boundsRect = new System.Drawing.Rectangle(0, 0, width, height);

            // Copy pixels from screen capture Texture to GDI bitmap
            var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
            var sourcePtr = mapSource.DataPointer;
            var destPtr = mapDest.Scan0;

            sourcePtr = IntPtr.Add(sourcePtr, originY * mapSource.RowPitch + originX * 4);
            for (var y = 0; y < height; y++)
            {
                // Copy a single line 

                SharpDX.Utilities.CopyMemory(destPtr, sourcePtr, width * 4);

                // Advance pointers
                if (y != height - 1)
                    sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                destPtr = IntPtr.Add(destPtr, mapDest.Stride);
            }

            // Release source and dest locks
            bitmap.UnlockBits(mapDest);
            _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
            return bitmap;
        }

        private void ProcessFrame(DesktopFrame frame)
        {
            // Get the desktop capture texture
            var mapSource = _mDevice.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read,
                MapFlags.None);
            var bounds = (Rectangle) _mOutputDesc.DesktopBounds;
            FinalImage = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
            var boundsRect = new System.Drawing.Rectangle(0, 0, bounds.Width, bounds.Height);
            // Copy pixels from screen capture Texture to GDI bitmap
            var mapDest = FinalImage.LockBits(boundsRect, ImageLockMode.WriteOnly, FinalImage.PixelFormat);
            var sourcePtr = mapSource.DataPointer;
            var destPtr = mapDest.Scan0;
            for (var y = 0; y < bounds.Height; y++)
            {
                // Copy a single line 
                SharpDX.Utilities.CopyMemory(destPtr, sourcePtr, bounds.Width * 4);

                // Advance pointers
                sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                destPtr = IntPtr.Add(destPtr, mapDest.Stride);
            }

            // Release source and dest locks
            FinalImage.UnlockBits(mapDest);
            _mDevice.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
            frame.DesktopImage = (Bitmap) FinalImage.Clone();
        }

        private void ReleaseFrame()
        {
            try
            {
                _mDeskDupl.ReleaseFrame();
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Failure)
                    throw new DesktopDuplicationException("Failed to release frame.");
            }
        }
    }
namespace UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication
﻿using System.Drawing;
namespace UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication
namespace UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication
namespace UlteriusServer.Api.Win32.ScreenShare.Models
using UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication;
namespace UlteriusServer.Api.Win32.ScreenShare.Models
    
      
      
    

﻿namespace UlteriusServer.Api.Win32.ScreenShare.Models
using UlteriusServer.Api.Win32.ScreenShare.DesktopDuplication;
using UlteriusServer.Api.Win32.ScreenShare.Models;
using UlteriusServer.Utilities;
namespace UlteriusServer.Api.Win32.ScreenShare
                _desktopDuplicator = new DesktopDuplicator(0);
                _desktopDuplicator = new DesktopDuplicator(0);
                Console.WriteLine("desktop duplication failed");
namespace UlteriusServer.Api.Win32
namespace UlteriusServer.Api.Win32
namespace UlteriusServer.Api.Win32
namespace UlteriusServer.Api.Win32
﻿<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    
  </configSections>
  <system.net>
    <settings>
      <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
  </system.net>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
  <runtime>
    <loadFromRemoteSources enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AForge.Video" publicKeyToken="cbfb6e07d173c401" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.5.0" newVersion="2.2.5.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Magnum" publicKeyToken="b800c4cfcdeea87b" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.3.0" newVersion="2.1.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets.Rfc6455" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="vtortola.WebSockets.Deflate" publicKeyToken="7f78616efb4a208d" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.1.0" newVersion="2.2.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AForge" publicKeyToken="c1db6ff4eaa06aeb" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.2.5.0" newVersion="2.2.5.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Threading.Tasks.Dataflow" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.6.2.0" newVersion="4.6.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v13.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  
                if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location))
                        .Count() > 1)
                    return;
                if (!Directory.Exists(AppEnvironment.DataPath))
                    Directory.CreateDirectory(AppEnvironment.DataPath);
                if (!Debugger.IsAttached)
                {
                    ExceptionHandler.AddGlobalHandlers();
                    Console.WriteLine("Exception Handlers Attached");
                }
                ProfileOptimization.SetProfileRoot(AppEnvironment.DataPath);
                ProfileOptimization.StartProfile("Startup.Profile");
                var ulterius = new Ulterius();
                ulterius.Start();
                Console.ReadKey();
[assembly: AssemblyVersion("1.9.5.0")]
[assembly: AssemblyFileVersion("1.9.5.0")]
using UlteriusServer.Utilities;
using ILogger = UlteriusServer.TerminalServer.Infrastructure.ILogger;
              
                    _ws.CloseAsync();
using ILogger = UlteriusServer.TerminalServer.Infrastructure.ILogger;
            var options = new WebSocketListenerOptions
                HttpAuthenticationHandler = this.HttpNegotiation
            };
            options.Standards.RegisterRfc6455();
            _wsServer = new WebSocketListener(endpoint, options);
            _wsServer.StartAsync().GetAwaiter().GetResult();
        private async Task<bool> HttpNegotiation(WebSocketHttpRequest request, WebSocketHttpResponse response)
            await Task.Delay(TimeSpan.FromMilliseconds(1));
                       
            return true;
                   // _log.Error("Error Accepting clients", aex.GetBaseException());
           
            //_log.Info("Server Stop accepting clients");
using UlteriusServer.Api.Win32;
            Tools.RestartDaemon();
             var settings = Config.Load();
            if (UlteriusApiServer.RunningAsService)
            {
                Console.Write($"Service: {UlteriusApiServer.RunningAsService}");
                DesktopWatcher.Start();
            }
﻿<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" />
  <Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>UlteriusServer</RootNamespace>
    <AssemblyName>Ulterius Server</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <TargetFrameworkProfile />
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <PublishUrl>publish\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <UseApplicationTrust>false</UseApplicationTrust>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>7</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7</LangVersion>
    <Prefer32Bit>false</Prefer32Bit>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>256.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <PropertyGroup>
    <SignAssembly>false</SignAssembly>
  </PropertyGroup>
  <PropertyGroup>
    <AssemblyOriginatorKeyFile>
    </AssemblyOriginatorKeyFile>
  </PropertyGroup>
  <PropertyGroup>
    <SignManifests>false</SignManifests>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Api\Network\Messages\MessageResolver.cs" />
    <Compile Include="Api\Network\Messages\PacketLoader.cs" />
    <Compile Include="Api\Network\Messages\RectangleConverter.cs" />
    <Compile Include="Api\Network\Models\FanInformation.cs" />
    <Compile Include="Api\Network\Models\LoginInformation.cs" />
    <Compile Include="Api\Network\PacketHandlers\DisplayPacketHandler.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\JobModel.cs" />
    <Compile Include="Api\Network\PacketHandlers\CronJobPacketHandler.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronDaemon.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronJob.cs" />
    <Compile Include="Api\Services\LocalSystem\Daemons\CronSchedule.cs" />
    <Compile Include="Api\Services\LocalSystem\CronJobService.cs" />
    <Compile Include="Api\Services\Update\UpdateService.cs" />
    <Compile Include="Api\Network\Messages\Message.cs" />
    <Compile Include="Api\Network\Messages\MessageQueueManager.cs" />
    <Compile Include="Api\Services\LocalSystem\FileSearchService.cs" />
    <Compile Include="Api\SystemData.cs" />
    <Compile Include="Api\Win32\Desktop.cs" />
    <Compile Include="Api\Win32\DesktopWatcher.cs" />
    <Compile Include="Api\Win32\Display.cs" />
    <Compile Include="Api\Win32\ScreenShare\DesktopDuplication\DesktopDuplicationException.cs" />
    <Compile Include="Api\Win32\ScreenShare\DesktopDuplication\DesktopDuplicator.cs" />
    <Compile Include="Api\Win32\ScreenShare\DesktopDuplication\DesktopFrame.cs" />
    <Compile Include="Api\Win32\ScreenShare\DesktopDuplication\FinishedRegions.cs" />
    <Compile Include="Api\Win32\ScreenShare\DesktopDuplication\MovedRegion.cs" />
    <Compile Include="Api\Win32\ScreenShare\Models\DisplayInformation.cs" />
    <Compile Include="Api\Win32\ScreenShare\Models\FrameInformation.cs" />
    <Compile Include="Api\Win32\ScreenShare\Models\ResolutionInformation.cs" />
    <Compile Include="Api\Win32\ScreenShare\ScreenData.cs" />
    <Compile Include="Api\Win32\SessionInfo.cs" />
    <Compile Include="Api\Win32\Win32Exception.cs" />
    <Compile Include="Api\Win32\WinApi.cs" />
    <Compile Include="Api\Win32\WindowsIdentityImpersonator.cs" />
    <Compile Include="Forms\Utilities\AboutBox.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Forms\Utilities\AboutBox.Designer.cs">
      <DependentUpon>AboutBox.cs</DependentUpon>
    </Compile>
    <Compile Include="TerminalServer\Infrastructure\ILogger.cs" />
    <Compile Include="TerminalServer\Infrastructure\Log4NetLogger.cs" />
    <Compile Include="Ulterius.cs" />
    <Compile Include="Utilities\AppEnvironment.cs" />
    <Compile Include="Utilities\Config.cs" />
    <Compile Include="Utilities\Drive\PartitionModel.cs" />
    <Compile Include="Utilities\Drive\SmartData.cs" />
    <Compile Include="Utilities\Drive\SmartEnums.cs" />
    <Compile Include="Utilities\Drive\SmartModel.cs" />
    <Compile Include="Utilities\Extensions\NetworkBrowser.cs" />
    <Compile Include="Utilities\Extensions\ProcessExtensions.cs" />
    <Compile Include="Utilities\Extensions\TaskExtensions.cs" />
    <Compile Include="Utilities\Files\Database\DatabaseController.cs" />
    <Compile Include="Utilities\Files\Database\DatabaseManager.cs" />
    <Compile Include="Utilities\Security\Streams\OfbStream.cs" />
    <Compile Include="Utilities\Security\Streams\ZeroStream.cs" />
    <Compile Include="Utilities\Security\AuthUtils.cs" />
    <Compile Include="WebCams\WebCamManager.cs" />
    <Compile Include="WebSocketAPI\Authentication\AuthClient.cs" />
    <Compile Include="Forms\Utilities\UlteriusTray.cs" />
    <Compile Include="Api\Network\Messages\Packet.cs" />
    <Compile Include="Api\Network\Messages\MessageBuilder.cs" />
    <Compile Include="Api\Network\PacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ErrorPacketHandler.cs" />
    <Compile Include="Api\Network\PacketManager.cs" />
    <Compile Include="Api\Network\PacketHandlers\WebCamPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\FilePacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\GpuPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ScreenSharePacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\AccountPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\SettingsPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\NetworkPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\CpuPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\OperatingSystemPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ProcessPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\ServerPacketHandler.cs" />
    <Compile Include="Api\Network\PacketHandlers\SystemPacketHandler.cs" />
    <Compile Include="Api\Network\Models\GpuInformation.cs" />
    <Compile Include="Api\Services\LocalSystem\ScreenShareService.cs" />
    <Compile Include="TerminalServer\Cli\CommandSession.cs" />
    <Compile Include="TerminalServer\Cli\PowerShellSession.cs" />
    <Compile Include="TerminalServer\Cli\_ICliSession.cs" />
    <Compile Include="TerminalServer\Cli\_ICliSessionFactory.cs" />
    <Compile Include="TerminalServer\Infrastructure\SystemInfo.cs" />
    <Compile Include="TerminalServer\Infrastructure\_ISystemInfo.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\ConnectionConnectRequest.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\IConnectionEvent.cs" />
    <Compile Include="TerminalServer\Messaging\Connection\IConnectionRequest.cs" />
    <Compile Include="TerminalServer\Messaging\IMessageBus.cs" />
    <Compile Include="TerminalServer\Messaging\Serialization\DefaultEventSerializator.cs" />
    <Compile Include="TerminalServer\Messaging\Serialization\IEventSerializator.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\ClosedTerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\CreatedTerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\SessionStateEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\TerminalOutputEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Events\_ITerminalEvent.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\AesHandshakeRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\CloseTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\CreateTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\InputTerminalRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Handlers\_IRequestHandler.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\AesHandshakeRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\CloseTerminalRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\CreateTerminalRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\TerminalInputRequest.cs" />
    <Compile Include="TerminalServer\Messaging\TerminalControl\Requests\_TerminalControlRequest.cs" />
    <Compile Include="TerminalServer\Messaging\WebSocketHandler.cs" />
    <Compile Include="TerminalServer\Messaging\WebSocketQueueServer.cs" />
    <Compile Include="TerminalServer\Session\ConnectionManager.cs" />
    <Compile Include="TerminalServer\Session\UserConnection.cs" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Api\UlteriusApiServer.cs" />
    <Compile Include="TerminalServer\TerminalManagerServer.cs" />
    <Compile Include="Utilities\DynamicMap.cs" />
    <Compile Include="Utilities\Extensions\StringExtensions.cs" />
    <Compile Include="Utilities\Files\FileManager.cs" />
    <Compile Include="Utilities\IconTools.cs" />
    <Compile Include="Utilities\Security\UlteriusAes.cs" />
    <Compile Include="Utilities\Security\Rsa.cs" />
    <Compile Include="Utilities\Files\FileTree.cs" />
    <Compile Include="Utilities\Trace.cs" />
    <Compile Include="WebServer\MultipartParser.cs" />
    <Compile Include="WebSocketAPI\Authentication\CookieManager.cs" />
    <Compile Include="WebSocketAPI\WebSocketEventListener.cs" />
    <Compile Include="Api\Network\Models\DriveInformation.cs" />
    <Compile Include="Api\Network\Models\SystemInformation.cs" />
    <Compile Include="Api\Network\Models\NetworkInformation.cs" />
    <Compile Include="Api\Network\Models\CpuInformation.cs" />
    <Compile Include="Api\Network\Models\OperatingSystemInformation.cs" />
    <Compile Include="Program.cs" />
    <Compile Include="Properties\Resources.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
    <Compile Include="Api\Network\Models\ProcessInformation.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="Utilities\ExceptionHandler.cs" />
    <Compile Include="Api\Services\Network\NetworkService.cs" />
    <Compile Include="Api\Services\LocalSystem\SystemService.cs" />
    <Compile Include="Utilities\Tools.cs" />
    <Compile Include="WebServer\HttpServer.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config" />
    <None Include="app.manifest" />
    <None Include="App1.config" />
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Forms\Utilities\AboutBox.resx">
      <DependentUpon>AboutBox.cs</DependentUpon>
    </EmbeddedResource>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      <SubType>Designer</SubType>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup>
    <Content Include="256.ico" />
    <EmbeddedResource Include="Packets.json" />
    <None Include="Resources\ApplicationIcon.ico" />
    <Content Include="twitter-profile.ico" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Service References\" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="bin\Debug\" />
    <Folder Include="Utilities\Files\Models\" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="AForge, Version=2.2.5.0, Culture=neutral, PublicKeyToken=c1db6ff4eaa06aeb, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.2.2.5\lib\AForge.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Imaging, Version=2.2.5.0, Culture=neutral, PublicKeyToken=ba8ddea9676ca48b, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Imaging.2.2.5\lib\AForge.Imaging.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Math, Version=2.2.5.0, Culture=neutral, PublicKeyToken=abba2e25397ee8c9, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Math.2.2.5\lib\AForge.Math.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Video, Version=2.2.5.0, Culture=neutral, PublicKeyToken=cbfb6e07d173c401, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Video.2.2.5\lib\AForge.Video.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Video.DirectShow, Version=2.2.5.0, Culture=neutral, PublicKeyToken=61ea4348d43881b7, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Video.DirectShow.2.2.5\lib\AForge.Video.DirectShow.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="AForge.Vision, Version=2.2.5.0, Culture=neutral, PublicKeyToken=b612fa915eefaa06, processorArchitecture=MSIL">
      <HintPath>..\packages\AForge.Vision.2.2.5\lib\AForge.Vision.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
      <HintPath>..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="deniszykov.WebSocketListener, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7f78616efb4a208d, processorArchitecture=MSIL">
      <HintPath>..\packages\deniszykov.WebSocketListener.4.0.0\lib\net45\deniszykov.WebSocketListener.dll</HintPath>
    </Reference>
    <Reference Include="DotNetZip, Version=1.10.1.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
      <HintPath>..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
      <HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
    </Reference>
    <Reference Include="Magnum, Version=2.1.3.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL">
      <HintPath>..\packages\Magnum.2.1.3\lib\NET40\Magnum.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="MassTransit, Version=2.9.0.0, Culture=neutral, PublicKeyToken=b8e0e9f2f1e657fa, processorArchitecture=MSIL">
      <HintPath>..\packages\MassTransit.2.9.0\lib\net40\MassTransit.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="MiscUtil, Version=0.2.0.0, Culture=neutral, PublicKeyToken=d3c42c4bfacf7596, processorArchitecture=MSIL">
      <HintPath>..\packages\JonSkeet.MiscUtil.0.2.0\lib\net35\MiscUtil.dll</HintPath>
    </Reference>
    <Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Mdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Mdb.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Pdb, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Pdb.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Mono.Cecil.Rocks, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
      <HintPath>..\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
    </Reference>
    <Reference Include="Open.Nat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f22a6a4582336c76, processorArchitecture=MSIL">
      <HintPath>..\packages\Open.NAT.2.1.0.0\lib\net45\Open.Nat.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="OpenHardwareMonitorLib">
      <HintPath>..\Deps\OpenHardwareMonitorLib.dll</HintPath>
    </Reference>
    <Reference Include="PresentationCore" />
    <Reference Include="SharpDX, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.4.0.1\lib\net45\SharpDX.dll</HintPath>
    </Reference>
    <Reference Include="SharpDX.Direct3D11, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.Direct3D11.4.0.1\lib\net45\SharpDX.Direct3D11.dll</HintPath>
    </Reference>
    <Reference Include="SharpDX.DXGI, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.DXGI.4.0.1\lib\net45\SharpDX.DXGI.dll</HintPath>
    </Reference>
    <Reference Include="SharpDX.Mathematics, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
      <HintPath>..\packages\SharpDX.Mathematics.4.0.1\lib\net45\SharpDX.Mathematics.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.DirectoryServices" />
    <Reference Include="System.DirectoryServices.AccountManagement" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.IO.Compression" />
    <Reference Include="System.Management" />
    <Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll</HintPath>
    </Reference>
    <Reference Include="System.Net" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.ServiceModel" />
    <Reference Include="System.ServiceProcess" />
    <Reference Include="System.Threading.Tasks.Dataflow, Version=4.6.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>..\packages\System.Threading.Tasks.Dataflow.4.8.0\lib\netstandard2.0\System.Threading.Tasks.Dataflow.dll</HintPath>
    </Reference>
    <Reference Include="System.Web" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xaml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Xml" />
    <Reference Include="Topshelf, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL">
      <HintPath>..\packages\Topshelf.4.0.3\lib\net452\Topshelf.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="TurboJpegWrapper, Version=1.4.2.19498, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\TurboJpegWrapper.1.4.2.6\lib\net35\TurboJpegWrapper.dll</HintPath>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="ZetaLongPaths, Version=1.0.0.19, Culture=neutral, PublicKeyToken=b764f59068f31f38, processorArchitecture=MSIL">
      <HintPath>..\packages\ZetaLongPaths.1.0.0.19\lib\net40-full\ZetaLongPaths.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <COMReference Include="NetFwTypeLib">
      <Guid>{58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>0</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\..\..\inputsimulator2\WindowsInput\WindowsInput.csproj">
      <Project>{3549cd6f-80f8-450f-b99e-cf0a736b1f2a}</Project>
      <Name>WindowsInput</Name>
    </ProjectReference>
    <ProjectReference Include="..\UlteriusAgent\UlteriusAgent.csproj">
      <Project>{686ae4c4-791f-45eb-9414-029d6115905d}</Project>
      <Name>UlteriusAgent</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.3\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
    <Error Condition="!Exists('..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\TurboJpegWrapper.1.4.2.6\build\TurboJpegWrapper.targets'))" />
    <Error Condition="!Exists('..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props'))" />
  </Target>
  <PropertyGroup>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
  <PropertyGroup>
    <PreBuildEvent>
    </PreBuildEvent>
  </PropertyGroup>
  <Target Name="AfterClean">
    <Delete Files="$(TargetDir)\*.dll" />
  </Target>
  <Target Name="AfterClean">
    <ItemGroup>
      <FilesToDelete Include="$(TargetDir)\*.dll" />
    </ItemGroup>
    <Delete Files="@(FilesToDelete)" />
  </Target>
﻿<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
	<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp70</s:String></wpf:ResourceDictionary>
namespace UlteriusServer.Utilities
namespace UlteriusServer.Utilities
﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

namespace UlteriusServer.Utilities.Extensions
{
    public static class ProcessExtensions
    {
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr parentWindow, IntPtr previousChildWindow, string windowClass,
            string windowTitle);

        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowThreadProcessId(IntPtr window, out int process);

        public static IntPtr[] GetProcessWindows(this Process process)
        {
            var apRet = new IntPtr[256];
            var iCount = 0;
            var pLast = IntPtr.Zero;
            do
            {
                pLast = FindWindowEx(IntPtr.Zero, pLast, null, null);
                int iProcess_;
                GetWindowThreadProcessId(pLast, out iProcess_);
                if (iProcess_ == process.Id)
                {
                    apRet[iCount++] = pLast;
                }
            } while (pLast != IntPtr.Zero);
            Array.Resize(ref apRet, iCount);
            return apRet;
        }

        private static string FindIndexedProcessName(int pid)
        {
            try
            {
                var processName = Process.GetProcessById(pid).ProcessName;
                var processesByName = Process.GetProcessesByName(processName);
                string processIndexdName = null;
                for (var index = 0; index < processesByName.Length; index++)
                {
                    processIndexdName = index == 0 ? processName : processName + "#" + index;
                    var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
                    if ((int)processId.NextValue() == pid)
                    {
                        return processIndexdName;
                    }
                }
                return processIndexdName;
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static List<Process> GetChildrenById(int id)
        {
            try
            {
                var mos = new ManagementObjectSearcher(
                    $"Select * From Win32_Process Where ParentProcessID={id}");
                return (from ManagementObject mo in mos.Get()
                    select Process.GetProcessById(Convert.ToInt32(mo["ProcessID"]))).ToList();
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static List<Process> GetChildProcesses(this Process process)
        {
            try
            {
                var mos = new ManagementObjectSearcher(
                    $"Select * From Win32_Process Where ParentProcessID={process.Id}");
                return (from ManagementObject mo in mos.Get()
                    select Process.GetProcessById(Convert.ToInt32(mo["ProcessID"]))).ToList();
            }
            catch (Exception)
            {
                return null;
            }
        }

        public static bool IsService(this Process process)
        {
            if (process == null)
            {
                return false;
            }
            using (var searcher =
                new ManagementObjectSearcher("SELECT * FROM Win32_Service WHERE ProcessId =" + "\"" + process.Id +
                                             "\""))
            {
                if (searcher.Get().Cast<ManagementObject>().Any())
                {
                    return true;
                }
            }
            return false;
        }

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);

        [DllImport("psapi.dll")]
        private static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName,
            [In] [MarshalAs(UnmanagedType.U4)] int nSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr hObject);


        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static string GetProcessName(this Process proc)
        {
            var processHandle = OpenProcess(0x0400 | 0x0010, false, proc.Id);

            if (processHandle == IntPtr.Zero)
            {
                return null;
            }

            const int lengthSb = 4000;

            var sb = new StringBuilder(lengthSb);

            string result = null;

            if (GetModuleFileNameEx(processHandle, IntPtr.Zero, sb, lengthSb) > 0)
            {
                result = Path.GetFileName(sb.ToString());
            }

            CloseHandle(processHandle);

            return result;
        }

        public static Process GetProcess(string path)
        {
            try
            {
                return Process.GetProcessesByName(Path.GetFileNameWithoutExtension(path)).FirstOrDefault();
            }
            catch
            {

                return null;
            }
        }

        private static Process FindPidFromIndexedProcessName(string indexedProcessName)
        {
            try
            {
                var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
                return Process.GetProcessById((int)parentId.NextValue());
            }
            catch (Exception)
            {
                return null;
            }
        }


        public static void KillProcessAndChildren(this Process process)
        {
            try
            {
                var searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + process.Id);
                var moc = searcher.Get();
                foreach (var o in moc)
                {
                    var mo = (ManagementObject)o;
                    var child = Process.GetProcessById(Convert.ToInt32(mo["ProcessID"]));
                    KillProcessAndChildren(child);
                    child.Kill();
                }
                process.Kill();
            }
            catch
            {
                // Process already exited.
            }
        }

        public static bool ProgramIsRunning(string fullPath)
        {
            return Process.GetProcessesByName(Path.GetFileNameWithoutExtension(fullPath)).Count() > 1;
        }

        public static Process Parent(this Process process)
        {
            return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
        }
    }
}
﻿#region

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;
using MassTransit.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

#endregion

namespace UlteriusServer.Utilities.Extensions
{
    /// <summary>
    ///     Enum FormatTokenFlags
    /// </summary>
    public enum FormatTokenFlags
    {
        /// <summary>
        ///     Uses the specifier token as the replacement token, matches '%' but not '%%'
        /// </summary>
        SpecifierToken,

        /// <summary>
        ///     Like String.Format
        /// </summary>
        IndexToken,

        /// <summary>
        ///     Extracts an Object's Members by name.
        /// </summary>
        MemberToken
    }

    /// <summary>
    ///     Class StringExtensions
    /// </summary>
    public static class StringExtensions
    {

        // Returns the human-readable file totalSize for an arbitrary, 64-bit file totalSize 
        // The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"

        public static string UnicodeUtf8(this string strFrom)
        {
            var bytSrc = Encoding.Unicode.GetBytes(strFrom);
            var bytDestination = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, bytSrc);
            var strTo = Encoding.UTF8.GetString(bytDestination);
            return strTo;
        }

        /// <summary>
        /// Implement's VB's Like operator logic.
        /// </summary>
        public static bool IsLike(this string s, string pattern)
        {
            // Characters matched so far
            var matched = 0;

            // Loop through pattern string
            for (var i = 0; i < pattern.Length;)
            {
                // Check for end of string
                if (matched > s.Length)
                    return false;

                // Get next pattern character
                var c = pattern[i++];
                if (c == '[') // Character list
                {
                    // Test for exclude character
                    var exclude = (i < pattern.Length && pattern[i] == '!');
                    if (exclude)
                        i++;
                    // Build character list
                    var j = pattern.IndexOf(']', i);
                    if (j < 0)
                        j = s.Length;
                    var charList = CharListToSet(pattern.Substring(i, j - i));
                    i = j + 1;

                    if (charList.Contains(s[matched]) == exclude)
                        return false;
                    matched++;
                }
                else if (c == '?') // Any single character
                {
                    matched++;
                }
                else if (c == '#') // Any single digit
                {
                    if (!Char.IsDigit(s[matched]))
                        return false;
                    matched++;
                }
                else if (c == '*') // Zero or more characters
                {
                    if (i < pattern.Length)
                    {
                        // Matches all characters until
                        // next character in pattern
                        var next = pattern[i];
                        var j = s.IndexOf(next, matched);
                        if (j < 0)
                            return false;
                        matched = j;
                    }
                    else
                    {
                        // Matches all remaining characters
                        matched = s.Length;
                        break;
                    }
                }
                else // Exact character
                {
                    if (matched >= s.Length || c != s[matched])
                        return false;
                    matched++;
                }
            }
            // Return true if all characters matched
            return (matched == s.Length);
        }
        /// <summary>
        /// Checks if a string is a valid email
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static bool IsValidEmail(this string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address == email;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Returns true if <paramref name="path"/> starts with the path <paramref name="baseDirPath"/>.
        /// The comparison is case-insensitive, handles / and \ slashes as folder separators and
        /// only matches if the base dir folder name is matched exactly ("c:\foobar\file.txt" is not a sub path of "c:\foo").
        /// </summary>
        public static bool IsSubPathOf(this string path, string baseDirPath)
        {
            var normalizedPath = Path.GetFullPath(path.Replace('/', '\\')
                .WithEnding("\\"));

            var normalizedBaseDirPath = Path.GetFullPath(baseDirPath.Replace('/', '\\')
                .WithEnding("\\"));

            return normalizedPath.StartsWith(normalizedBaseDirPath, StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// Returns <paramref name="str"/> with the minimal concatenation of <paramref name="ending"/> (starting from end) that
        /// results in satisfying .EndsWith(ending).
        /// </summary>
        /// <example>"hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo".</example>
        public static string WithEnding([CanBeNull] this string str, string ending)
        {
            if (str == null)
                return ending;

            var result = str;

            // Right() is 1-indexed, so include these cases
            // * Append no characters
            // * Append up to N characters, where N is ending length
            for (var i = 0; i <= ending.Length; i++)
            {
                var tmp = result + ending.Right(i);
                if (tmp.EndsWith(ending))
                    return tmp;
            }

            return result;
        }

        /// <summary>Gets the rightmost <paramref name="length" /> characters from a string.</summary>
        /// <param name="value">The string to retrieve the substring from.</param>
        /// <param name="length">The number of characters to retrieve.</param>
        /// <returns>The substring.</returns>
        public static string Right([NotNull] this string value, int length)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException("length", length, "Length is less than zero");
            }

            return (length < value.Length) ? value.Substring(value.Length - length) : value;
        }

        /// <summary>
        /// Converts a string of characters to a HashSet of characters. If the string
        /// contains character ranges, such as A-Z, all characters in the range are
        /// also added to the returned set of characters.
        /// </summary>
        /// <param name="charList">Character list string</param>
        private static HashSet<char> CharListToSet(string charList)
        {
            var set = new HashSet<char>();

            for (var i = 0; i < charList.Length; i++)
            {
                if ((i + 1) < charList.Length && charList[i + 1] == '-')
                {
                    // Character range
                    var startChar = charList[i++];
                    i++; // Hyphen
                    var endChar = (char)0;
                    if (i < charList.Length)
                        endChar = charList[i++];
                    for (int j = startChar; j <= endChar; j++)
                        set.Add((char)j);
                }
                else set.Add(charList[i]);
            }
            return set;
        }

        public static string GetBytesReadable(long i)
        {
            // Get absolute value
            var absoluteI = i < 0 ? -i : i;
            // Determine the suffix and readable value
            string suffix;
            double readable;
            if (absoluteI >= 0x1000000000000000) // Exabyte
            {
                suffix = "EB";
                readable = i >> 50;
            }
            else if (absoluteI >= 0x4000000000000) // Petabyte
            {
                suffix = "PB";
                readable = i >> 40;
            }
            else if (absoluteI >= 0x10000000000) // Terabyte
            {
                suffix = "TB";
                readable = i >> 30;
            }
            else if (absoluteI >= 0x40000000) // Gigabyte
            {
                suffix = "GB";
                readable = i >> 20;
            }
            else if (absoluteI >= 0x100000) // Megabyte
            {
                suffix = "MB";
                readable = i >> 10;
            }
            else if (absoluteI >= 0x400) // Kilobyte
            {
                suffix = "KB";
                readable = i;
            }
            else
            {
                return i.ToString("0 B"); // Byte
            }
            // Divide by 1024 to get fractional value
            readable = readable / 1024;
            // Return formatted number with suffix
            return readable.ToString("0.### ") + suffix;
        }

        /// <summary>
        /// Returns a Secure string from the source string
        /// </summary>
        /// <param name="Source"></param>
        /// <returns></returns>
        public static SecureString ToSecureString(this string Source)
        {
            if (string.IsNullOrWhiteSpace(Source))
                return null;
            var Result = new SecureString();
            foreach (var c in Source.ToCharArray())
                Result.AppendChar(c);
            return Result;
        }
        public static string ToUnsecureString(this SecureString secureString)
        {
            if (secureString == null) throw new ArgumentNullException("secureString");

            var unmanagedString = IntPtr.Zero;
            try
            {
                unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
                return Marshal.PtrToStringUni(unmanagedString);
            }
            finally
            {
                Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
            }
        }


        /// <summary>
        ///     The Reformatting function called to format the string with a list of arguments.
        /// </summary>
        private static Func<Func<string, object>, string, IList<object>, string> _regexReformatter;

        /// <summary>
        ///     The Regex which matches the specifier token in strings.
        /// </summary>
        private static Regex _specifierTokenRegex;

        /// <summary>
        ///     The Regex which matches parameter indexes in strings, same as string.Format.
        /// </summary>
        private static Regex _argumentIndexRegex;

        /// <summary>
        ///     The Regex which matches object member names in strings.
        /// </summary>
        private static Regex _objectMemberRegex;

        /// <summary>
        ///     Splits a string into an array of strings, the string is split by commas.
        /// </summary>
        /// <param name="this">The string instance to split by commas.</param>
        /// <returns>The <paramref name="this" /> string that has been comma separated into substrings.</returns>
        public static string[] CommaSeparate(this string @this)
        {
            return @this.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        ///     Determines whether two String objects contain the same data, ignoring the case of the letters in the String; uses
        ///     Ordinal comparison.
        /// </summary>
        /// <param name="this">The current string to be compared to.</param>
        /// <param name="other">The other string to compare against the current String for equality.</param>
        /// <returns><c>true</c> if the two strings are equal, <c>false</c> otherwise</returns>
        public static bool EqualsIgnoreCase(this string @this, string other)
        {
            return string.Equals(@this, other, StringComparison.OrdinalIgnoreCase);
        }

        public static bool IsBase64String(this string s)
        {
            s = s.Trim();
            return (s.Length%4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
        }

        public static bool IsValidJson(this string strInput)
        {
            strInput = strInput.Trim();
            if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || //For object
                (strInput.StartsWith("[") && strInput.EndsWith("]"))) //For array
            {
                try
                {
                    JToken.Parse(strInput);
                    return true;
                }
                catch (JsonReaderException)
                {
                    //Exception in parsing json
                    return false;
                }
                catch (Exception) //some other exception
                {
                    return false;
                }
            }
            return false;
        }


        /// <summary>
        ///     Replaces one or more format items in a specified string with the string representation of a specified object.
        /// </summary>
        /// <returns>
        ///     A copy of <paramref name="format" /> in which any format items are replaced by the string representation of
        ///     <paramref name="values" />.
        /// </returns>
        /// <param name="format">A composite format string. </param>
        /// <param name="values">The arguments to use in formatting <paramref name="format" />.</param>
        public static string Form(this string format, params object[] values)
        {
            var specifierTokenMatches = _specifierTokenRegex.Matches(format);
            var indexTokenMatches = _argumentIndexRegex.Matches(format);
            var memberNameMatches = _objectMemberRegex.Matches(format);

            if (memberNameMatches.Count > 0 && values.Length == 1)
            {
                format = FormatString(format, FormatTokenFlags.MemberToken, values);
            }
            else
            {
                if (indexTokenMatches.Count > 0)
                {
                    format = FormatString(format, FormatTokenFlags.IndexToken, values);
                }

                if (specifierTokenMatches.Count > 0)
                {
                    format = FormatString(format, FormatTokenFlags.SpecifierToken, values);
                }
            }
            return format;
        }

        public static string CreateMD5(this string input)
        {
            // Use input string to calculate MD5 hash
            using (var md5 = MD5.Create())
            {
                var inputBytes = Encoding.ASCII.GetBytes(input);
                var hashBytes = md5.ComputeHash(inputBytes);

                // Convert the byte array to hexadecimal string
                var sb = new StringBuilder();
                foreach (var t in hashBytes)
                {
                    sb.Append(t.ToString("X2"));
                }
                return sb.ToString();
            }
        }

        /// <summary>
        ///     The Function which does all the heavy lifting.
        /// </summary>
        /// <param name="format">A composite format string</param>
        /// <param name="flags">The flags which specify how the <paramref name="format" /> string should be interpreted.</param>
        /// <param name="arguments">The arguments to format the <paramref name="format" /> parameter with.</param>
        /// <returns>System.String.</returns>
        public static string FormatString(string format, FormatTokenFlags flags, params object[] arguments)
        {
            switch (flags)
            {
                case FormatTokenFlags.IndexToken:
                    return string.Format(format, arguments);

                case FormatTokenFlags.SpecifierToken:
                    var stringBuilder = new StringBuilder();
                    for (int i = 0,
                        argIndex = 0;
                        i < format.Length;
                        i++)
                    {
                        stringBuilder.Append(format[i] == '%' && argIndex < arguments.Length
                            ? "{" + argIndex++ + "}"
                            : format.Substring(i, 1));
                    }
                    return string.Format(stringBuilder.ToString(), arguments);

                case FormatTokenFlags.MemberToken:
                    return
                        string.Format(
                            _regexReformatter(name => name == "0" ? arguments[0] : DataBinder.Eval(arguments[0], name),
                                format, arguments), arguments);

                default:
                    return format;
            }
        }

        public static void Initialize()
        {
            const RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.CultureInvariant;
            _objectMemberRegex = new Regex(@"(?<start>(\{))+(?<property>[\w\.]+)(?<end>(\}))+", regexOptions);
            _specifierTokenRegex = new Regex(@"(?<!\\)%", regexOptions);
            _argumentIndexRegex = new Regex(@"\{(\d)\}", regexOptions);
            _regexReformatter = (valueFetcher, format, parameters) =>
            {
                var argumentCollection = new List<object>();
                var rewrittenFormat = _objectMemberRegex.Replace(format, match =>
                {
                    Group startGroup = match.Groups["start"],
                        propertyGroup = match.Groups["property"],
                        endGroup = match.Groups["end"];

                    var result = valueFetcher(propertyGroup.Value);

                    argumentCollection.Add(result);
                    var index = argumentCollection.Count - 1;
                    var fmt = new string('{', startGroup.Captures.Count) + index +
                              new string('}', endGroup.Captures.Count);
                    return string.Format(fmt, argumentCollection.ToArray());
                });

                return rewrittenFormat;
            };
        }
    }
using UlteriusServer.Api.Win32;
using UlteriusServer.Utilities.Extensions;
      
                if (username.IsValidEmail())
                {
                    domainName = "MicrosoftAccount";
                }
using UlteriusServer.Api.Win32;
using UlteriusServer.Api.Win32.ScreenShare;
using UlteriusServer.Utilities.Extensions;
               
                managerProcess = Process.Start(managerPath);
               //
            var agentPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"UlteriusAgent.exe");
            agentProcess = Process.Start(agentPath);
            ScreenData.SetupDuplication();
                    Process.Start("CMD.exe", command);
                        $"firewall add allowedprogram program=\"{exeFileName}\" name=\"{displayName}\" profile=\"ALL\"",
            proc?.WaitForExit();
            var me = Process.GetCurrentProcess();
            var parent = me.Parent();
            return parent != null && parent.IsService();
using UlteriusServer.Utilities;
using UlteriusServer.Utilities;
using UlteriusServer.Utilities.Extensions;
               
                    var targetPath = Path.GetDirectoryName(new DirectoryInfo(filename).FullName);
                    //prevent directory traversal, we should only allow access to the root directory of the HTTP Server.
                    if (!targetPath.IsSubPathOf(_rootDirectory))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return;
                    }
        private WebSocketListener _listener;
        public WebSocketEventListener(Uri[] endpoints)
        public WebSocketEventListener(Uri[] endpoints, WebSocketListenerOptions options)
            options.Standards.RegisterRfc6455();
            _listener = new WebSocketListener(endpoints, options);
            _listener?.StopAsync().GetAwaiter().GetResult();
        public async void Start()
            await _listener.StartAsync();
        public async void Stop()
            await _listener.StopAsync();
            Task.Run(() => HandleListners(_listener));
﻿<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="AForge" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Imaging" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Math" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Video" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Video.DirectShow" version="2.2.5" targetFramework="net461" />
  <package id="AForge.Vision" version="2.2.5" targetFramework="net461" />
  <package id="BouncyCastle" version="1.8.1" targetFramework="net461" />
  <package id="deniszykov.WebSocketListener" version="4.0.0" targetFramework="net461" />
  <package id="DotNetZip" version="1.10.1" targetFramework="net461" />
  <package id="JonSkeet.MiscUtil" version="0.2.0" targetFramework="net461" />
  <package id="log4net" version="2.0.8" targetFramework="net461" />
  <package id="Magnum" version="2.1.3" targetFramework="net461" />
  <package id="MassTransit" version="2.9.0" targetFramework="net461" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net461" />
  <package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net461" developmentDependency="true" />
  <package id="Microsoft.Tpl.Dataflow" version="4.5.24" targetFramework="net461" />
  <package id="Mono.Cecil" version="0.9.6.4" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
  <package id="Open.NAT" version="2.1.0.0" targetFramework="net461" />
  <package id="SharpDX" version="4.0.1" targetFramework="net461" />
  <package id="SharpDX.Direct3D11" version="4.0.1" targetFramework="net461" />
  <package id="SharpDX.DXGI" version="4.0.1" targetFramework="net461" />
  <package id="SharpDX.Mathematics" version="4.0.1" targetFramework="net461" />
  <package id="System.Threading.Tasks.Dataflow" version="4.8.0" targetFramework="net461" />
  <package id="Topshelf" version="4.0.3" targetFramework="net461" />
  <package id="TurboJpegWrapper" version="1.4.2.6" targetFramework="net461" />
  <package id="ZetaLongPaths" version="1.0.0.19" targetFramework="net461" />
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Magnum" publicKeyToken="b800c4cfcdeea87b" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-2.1.3.0" newVersion="2.1.3.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AsyncIO" publicKeyToken="44a94435bd6f33f8" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-0.1.25.0" newVersion="0.1.25.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
using Topshelf;
using Warden.Core;
            WardenManager.Initialize(new WardenOptions
                DeepKill = true,
                CleanOnExit = true,
                ReadFileHeaders = false
            });
            HostFactory.Run(x => //1
                x.Service<UlteriusAgent>(s => //2
                    s.ConstructUsing(name => new UlteriusAgent()); //3
                    s.WhenStarted(tc => tc.Start()); //4
                    s.WhenStopped(tc => tc.Stop());
                    s.WhenSessionChanged((se, e, id) => { se.HandleEvent(e, id); }); //5
                });
                x.OnException(ex =>
                    //TODO Logging
                });
                x.RunAsLocalSystem(); //6
                x.EnableSessionChanged();
                x.EnableServiceRecovery(r => { r.RestartService(1); });
                x.SetDescription("The server that powers Ulterius"); //7
                x.SetDisplayName("Ulterius Server"); //8
                x.SetServiceName("UlteriusServer"); //9
                x.StartAutomaticallyDelayed();
            });
﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;
using Warden.Core;
using Warden.Core.Utils;

namespace UlteriusAgent
{
    public class UlteriusAgent
    {
        private readonly string _ulteriusPath;
        private WardenProcess _ulteriusInstance;


        public UlteriusAgent()
        {
            const string ulteriusFileName = "Ulterius Server.exe";
            _ulteriusPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ulteriusFileName);
        }

        public void Start()
        {
            if (!File.Exists(_ulteriusPath))
            {
                throw new InvalidOperationException($"Unable to locate Ulterius at {_ulteriusPath}");
            }
            if (Respawn())
            {
                Console.WriteLine("Rainway started as a service!");
                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("Failed to start Rainway!");
                Environment.Exit(1);
            }
        }

        private bool Respawn()
        {
            _ulteriusInstance = null;
            _ulteriusInstance = WardenProcess.Start(_ulteriusPath, string.Empty, null, true).GetAwaiter().GetResult();
            if (_ulteriusInstance == null || !_ulteriusInstance.IsTreeActive())
            {
                return false;
            }
            _ulteriusInstance.OnStateChange += UlteriusInstanceOnOnStateChange;
            return true;
        }

        public void Stop()
        {
            const string ulteriusFileName = "Ulterius Server.exe";
            if (_ulteriusInstance != null)
            {
                _ulteriusInstance?.Kill();
                WardenManager.Flush(_ulteriusInstance.Id);
            }
            _ulteriusInstance = null;
            EndProcessTree(ulteriusFileName);
        }

        private void EndProcessTree(string imageName)
        {
            try
            {
                var taskKill = new TaskKill
                {
                    Arguments = new List<TaskSwitch>()
                    {
                        TaskSwitch.Force,
                        TaskSwitch.TerminateChildren,
                        TaskSwitch.ImageName.SetValue(imageName)
                    }
                };
                taskKill.Execute(out var output, out var errror);
            }
            catch
            {
                //
            }
        }

        private void UlteriusInstanceOnOnStateChange(object sender, StateEventArgs stateEventArgs)
        {
            if (stateEventArgs.Id == _ulteriusInstance.Id && stateEventArgs.State == ProcessState.Dead)
            {
                //Kill the entire tree.
                _ulteriusInstance.Kill();
                WardenManager.Flush(_ulteriusInstance.Id);
                if (Respawn())
                {
                   Console.WriteLine("Rainway restarted!");
                }
            }
        }

        public void HandleEvent(HostControl hostControl, SessionChangedArguments arg3)
        {
            
        }
    }
}
﻿<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{686AE4C4-791F-45EB-9414-029D6115905D}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>UlteriusAgent</RootNamespace>
    <AssemblyName>UlteriusAgent</AssemblyName>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <LangVersion>7</LangVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <LangVersion>7</LangVersion>
  </PropertyGroup>
  <PropertyGroup>
    <StartupObject />
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="Topshelf, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b800c4cfcdeea87b, processorArchitecture=MSIL">
      <HintPath>..\packages\Topshelf.4.0.3\lib\net452\Topshelf.dll</HintPath>
    </Reference>
    <Reference Include="Warden, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\Warden.NET.1.2.3\lib\net45\Warden.dll</HintPath>
      <Private>True</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="UlteriusAgent.cs" />
  </ItemGroup>
  <ItemGroup>
    <None Include="App.config">
      <SubType>Designer</SubType>
    </None>
    <None Include="app.manifest" />
    <None Include="packages.config" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
﻿<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Topshelf" version="4.0.3" targetFramework="net452" />
  <package id="Warden.NET" version="1.2.3" targetFramework="net452" />
</packages>
﻿
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2005
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusServer", "RemoteTaskServer\UlteriusServer.csproj", "{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}"
	ProjectSection(ProjectDependencies) = postProject
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A} = {3549CD6F-80F8-450F-B99E-CF0A736B1F2A}
		{686AE4C4-791F-45EB-9414-029D6115905D} = {686AE4C4-791F-45EB-9414-029D6115905D}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UlteriusAgent", "UlteriusAgent\UlteriusAgent.csproj", "{686AE4C4-791F-45EB-9414-029D6115905D}"
	ProjectSection(ProjectDependencies) = postProject
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A} = {3549CD6F-80F8-450F-B99E-CF0A736B1F2A}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInput", "..\..\..\inputsimulator2\WindowsInput\WindowsInput.csproj", "{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{E9A365D5-AEBE-4AF3-86C5-D17BC65ADE46}.Release|Any CPU.Build.0 = Release|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{686AE4C4-791F-45EB-9414-029D6115905D}.Release|Any CPU.Build.0 = Release|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{3549CD6F-80F8-450F-B99E-CF0A736B1F2A}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {9CC02739-8FB9-4530-9C74-0436AF2D60A7}
	EndGlobalSection
EndGlobal