1
0
mirror of https://github.com/Ylianst/MeshCentralRouter synced 2025-12-06 00:13:33 +00:00

Started work on remote desktop client.

This commit is contained in:
Ylian Saint-Hilaire
2020-08-10 23:51:17 -07:00
parent e574e5007f
commit 7ad838265c
23 changed files with 4227 additions and 271 deletions

56
KVMControl.Designer.cs generated Normal file
View File

@@ -0,0 +1,56 @@
namespace MeshCentralRouter
{
partial class KVMControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// KVMControl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.SystemColors.Control;
this.Margin = new System.Windows.Forms.Padding(4);
this.Name = "KVMControl";
this.Size = new System.Drawing.Size(585, 364);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.KVMControl_Paint);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KVMControl_KeyDown);
this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.KVMControl_KeyPress);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.KVMControl_KeyUp);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.KVMControl_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.KVMControl_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.KVMControl_MouseUp);
this.ResumeLayout(false);
}
#endregion
//private System.Windows.Forms.Integration.ElementHost mainElementHost;
}
}

636
KVMControl.cs Normal file
View File

@@ -0,0 +1,636 @@
/*
Copyright 2009-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
namespace MeshCentralRouter
{
public partial class KVMControl : UserControl
{
private bool remotepause = true;
private Bitmap desktop = null;
private Graphics desktopGraphics = null;
private uint screenWidth = 0;
private uint screenHeight = 0;
private Pen RedPen = new Pen(System.Drawing.Color.Red);
private Font DebugFont = new Font(FontFamily.GenericSansSerif, 14);
private int compressionlevel = 60; // 60% compression
private int scalinglevel = 1024; // 100% scale
private int frameRate = 100; // Medium frame rate
private double scalefactor = 1;
public List<string> displays = new List<string>();
public ushort currentDisp = 0;
public bool MouseButtonLeft = false;
public bool MouseButtonMiddle = false;
public bool MouseButtonRight = false;
public double DpiX = 96;
public double DpiY = 96;
public KVMViewer parent = null;
private enum KvmCommands
{
Nop = 0,
Key = 1,
Mouse = 2,
Picture = 3,
Copy = 4,
Compression = 5,
Refresh = 6,
Screen = 7,
Pause = 8,
TerminalText = 9,
CtrlAltDel = 10,
GetDisplays = 11,
SetDisplay = 12,
FrameRateTimer = 13,
InitTouch = 14,
Touch = 15,
Message = 16,
Disconnect = 59,
Alert = 65,
MouseCursor = 88
}
private enum KvmMouseButtonCommands
{
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_MIDDLEUP = 0x0040
}
[Category("Action")]
[Description("Fires when the remote desktop size changes.")]
public event EventHandler DesktopSizeChanged;
[Category("Action")]
[Description("Fires when it receives the display list.")]
public event EventHandler DisplaysReceived;
public enum ConnectState
{
Disconnected,
Connecting,
Connected
}
public int CompressionLevel { get { return compressionlevel; } set { compressionlevel = value; SendCompressionLevel(); } }
public int ScalingLevel { get { return scalinglevel; } set { scalinglevel = value; SendCompressionLevel(); } }
public int FrameRate { get { return frameRate; } set { frameRate = value; SendCompressionLevel(); } }
public double ScaleFactor { get { return scalefactor; } set { scalefactor = value; } }
public void SetCompressionParams(int level, int scaling, int framerate) { compressionlevel = level; scalinglevel = scaling; frameRate = framerate; SendCompressionLevel(); }
public int DesktopWidth { get { return (int)screenWidth; } }
public int DesktopHeight { get { return (int)screenHeight; } }
// Debug
public int bytesent = 0;
public int byterecv = 0;
public int tilecount = 0;
public int tilecopy = 0;
public bool debugmode = false;
public KVMControl()
{
InitializeComponent();
this.SetStyle(ControlStyles.Selectable, false);
this.SetStyle(ControlStyles.UserMouse, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(KVMControl_MouseWheel);
}
public int ProcessData(byte[] buffer, int off, int len)
{
if (len == 0) return 0;
if (len >= 4)
{
KvmCommands btype = (KvmCommands)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off));
ushort blen = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 2));
if (len < blen) return 0;
switch (btype)
{
case KvmCommands.Screen:
{
if (blen != 8) return blen;
uint w = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 4));
uint h = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 6));
if (screenWidth == w && screenHeight == h) break;
screenWidth = w;
screenHeight = h;
desktop = new Bitmap((int)screenWidth, (int)screenHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
desktopGraphics = Graphics.FromImage(desktop);
SendCompressionLevel();
Invoke(new SetSizeHandler(SetSize));
SendPause(false);
SendMouse(2, KvmMouseButtonCommands.MOUSEEVENTF_LEFTUP);
SendMouse(2, KvmMouseButtonCommands.MOUSEEVENTF_MIDDLEUP);
SendMouse(2, KvmMouseButtonCommands.MOUSEEVENTF_RIGHTUP);
return blen;
}
case KvmCommands.Picture:
{
Image newtile;
ushort tile_x = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 4));
ushort tile_y = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 6));
try { newtile = Image.FromStream(new System.IO.MemoryStream(buffer, off + 8, blen - 8)); } catch (Exception) { return blen; }
Rectangle r = new Rectangle((int)tile_x, (int)tile_y, newtile.Width, newtile.Height);
Rectangle r3 = new Rectangle((int)((double)tile_x / (double)scalefactor) - 2, (int)((double)tile_y / (double)scalefactor) - 2, (int)((double)newtile.Width / (double)scalefactor) + 4, (int)((double)newtile.Height / (double)scalefactor) + 4);
tilecount++;
// Winform mode
if (desktop != null)
{
lock (desktop)
{
desktopGraphics.DrawImage(newtile, new Rectangle((int)tile_x, (int)tile_y, newtile.Width, newtile.Height), new Rectangle(0, 0, newtile.Width, newtile.Height), GraphicsUnit.Pixel);
if (debugmode)
{
desktopGraphics.DrawRectangle(RedPen, new Rectangle((int)tile_x, (int)tile_y, newtile.Width - 1, newtile.Height - 1));
desktopGraphics.DrawString(string.Format("{0} / {1}kb", tilecount, blen / 2014), DebugFont, RedPen.Brush, new Point((int)tile_x, (int)tile_y));
}
}
if (scalefactor == 1) Invalidate(r, false); else Invalidate(r3, false);
}
return blen;
}
case KvmCommands.Copy:
{
ushort sourcex = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 4));
ushort sourcey = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 6));
ushort targetx = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 8));
ushort targety = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 10));
ushort tilew = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 12));
ushort tileh = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 14));
Rectangle r1 = new Rectangle((int)sourcex, (int)sourcey, (int)tilew, (int)tileh);
Rectangle r2 = new Rectangle((int)targetx, (int)targety, (int)tilew, (int)tileh);
Rectangle r3 = new Rectangle((int)((double)targetx / (double)scalefactor) - 2, (int)((double)targety / (double)scalefactor) - 2, (int)((double)tilew / (double)scalefactor) + 4, (int)((double)tileh / (double)scalefactor) + 4);
// WinForm mode
if (desktop != null)
{
lock (desktop)
{
Bitmap bmp = new Bitmap(tilew, tileh);
Graphics g = Graphics.FromImage(bmp);
g.DrawImage(desktop, 0, 0, r1, GraphicsUnit.Pixel);
g.Dispose();
desktopGraphics.Flush();
desktopGraphics.DrawImage(bmp, r2, 0, 0, tilew, tileh, GraphicsUnit.Pixel);
if (debugmode) { desktopGraphics.DrawString("COPY", DebugFont, RedPen.Brush, new Point((int)targetx, (int)targety + 20)); }
}
tilecopy++;
}
return blen;
}
case KvmCommands.GetDisplays:
{
int i = 0;
ushort length = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 4));
displays.Clear();
if (length > 0)
{
for (i = 0; i < length; i++)
{
ushort num = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 6 + i * 2));
if (num == 0xFFFF)
{
displays.Add("All Displays");
}
else
{
displays.Add("Display " + num);
}
}
}
currentDisp = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 6 + i * 2));
if (DisplaysReceived != null) DisplaysReceived(this, null);
break;
}
case KvmCommands.SetDisplay:
{
currentDisp = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buffer, off + 4));
break;
}
case KvmCommands.MouseCursor:
{
if (blen != 5) return blen;
ChangeMouseCursor(buffer[off + 4]);
break;
}
default:
{
// MessageBox.Show("Should never happen!");
//Disconnect();
return 0;
}
}
return blen;
}
return 0;
}
private delegate void ChangeMouseCursorHandler(int cursorId);
private void ChangeMouseCursor(int cursorId)
{
if (this.InvokeRequired) { this.Invoke(new ChangeMouseCursorHandler(ChangeMouseCursor), cursorId); return; }
if (cursorId == 0) { this.Cursor = System.Windows.Forms.Cursors.Default; return; } // default
if (cursorId == 1) { this.Cursor = System.Windows.Forms.Cursors.AppStarting; return; } // progress
if (cursorId == 2) { this.Cursor = System.Windows.Forms.Cursors.Cross; return; } // crosshair
if (cursorId == 3) { this.Cursor = System.Windows.Forms.Cursors.Default; return; } // pointer
if (cursorId == 4) { this.Cursor = System.Windows.Forms.Cursors.Help; return; } // help
if (cursorId == 5) { this.Cursor = System.Windows.Forms.Cursors.IBeam; return; } // text
if (cursorId == 6) { this.Cursor = System.Windows.Forms.Cursors.No; return; } // no-drop
if (cursorId == 7) { this.Cursor = System.Windows.Forms.Cursors.Arrow; return; } // move
if (cursorId == 8) { this.Cursor = System.Windows.Forms.Cursors.SizeNESW; return; } // nesw-resize
if (cursorId == 9) { this.Cursor = System.Windows.Forms.Cursors.SizeNS; return; } // ns-resize
if (cursorId == 10) { this.Cursor = System.Windows.Forms.Cursors.SizeNWSE; return; } // nwse-resize
if (cursorId == 11) { this.Cursor = System.Windows.Forms.Cursors.SizeWE; return; } // w-resize
if (cursorId == 12) { this.Cursor = System.Windows.Forms.Cursors.Arrow; return; } // alias
if (cursorId == 13) { this.Cursor = System.Windows.Forms.Cursors.WaitCursor; return; } // wait
if (cursorId == 14) { this.Cursor = System.Windows.Forms.Cursors.Default; return; } // none
if (cursorId == 15) { this.Cursor = System.Windows.Forms.Cursors.No; return; } // not-allowed
if (cursorId == 16) { this.Cursor = System.Windows.Forms.Cursors.VSplit; return; } // col-resize
if (cursorId == 17) { this.Cursor = System.Windows.Forms.Cursors.HSplit; return; } // row-resize
if (cursorId == 18) { this.Cursor = System.Windows.Forms.Cursors.Default; return; } // copy
if (cursorId == 19) { this.Cursor = System.Windows.Forms.Cursors.SizeAll; return; } // zoom-in
if (cursorId == 20) { this.Cursor = System.Windows.Forms.Cursors.SizeAll; return; } // zoom-out
}
public void Repaint(Region region)
{
Invalidate(region);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do not paint background.
}
private delegate void SetSizeHandler();
private void SetSize()
{
if (DesktopSizeChanged != null) { DesktopSizeChanged(this, null); }
}
private void KVMControl_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (desktop == null)
{
g.FillRectangle(new SolidBrush(Color.Black), e.ClipRectangle);
}
else
{
lock (desktop)
{
if (scalefactor == 1)
{
g.DrawImage(desktop, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel);
}
else
{
//g.DrawImage((Image)desktop, new Rectangle(0, 0, Width, Height), 0, 0, screenWidth, screenHeight, GraphicsUnit.Pixel);
g.DrawImage((Image)desktop, e.ClipRectangle, (int)((double)e.ClipRectangle.Left * (double)scalefactor), (int)((double)e.ClipRectangle.Top * (double)scalefactor), (int)((double)e.ClipRectangle.Width * (double)scalefactor), (int)((double)e.ClipRectangle.Height * (double)scalefactor), GraphicsUnit.Pixel);
}
}
}
}
public void SendKey(byte key, byte action)
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Key));
bw.Write(IPAddress.HostToNetworkOrder((short)6));
bw.Write((byte)action);
bw.Write((byte)key);
Send(bw);
}
private void SendKey(KeyEventArgs e, byte action)
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Key));
bw.Write(IPAddress.HostToNetworkOrder((short)6));
bw.Write((byte)action);
bw.Write((byte)e.KeyCode);
Send(bw);
}
private short LastX = 0;
private short LastY = 0;
private void SendMouse(MouseEventArgs e, byte action)
{
//if (state != ConnectState.Connected) return;
byte buttons = 0;
if (action == 1)
{
switch (e.Button)
{
case MouseButtons.Left:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_LEFTDOWN;
break;
case MouseButtons.Right:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_RIGHTDOWN;
break;
case MouseButtons.Middle:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_MIDDLEDOWN;
break;
}
}
else if (action == 2)
{
switch (e.Button)
{
case MouseButtons.Left:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_LEFTUP;
break;
case MouseButtons.Right:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_RIGHTUP;
break;
case MouseButtons.Middle:
buttons |= (byte)KvmMouseButtonCommands.MOUSEEVENTF_MIDDLEUP;
break;
}
}
LastX = (short)((double)e.X * (double)scalefactor);
LastY = (short)((double)e.Y * (double)scalefactor);
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Mouse));
bw.Write(IPAddress.HostToNetworkOrder((short)(e.Delta == 0 ? 10 : 12)));
bw.Write((byte)action);
bw.Write((byte)buttons);
bw.Write(IPAddress.HostToNetworkOrder(LastX));
bw.Write(IPAddress.HostToNetworkOrder(LastY));
if (e.Delta != 0) { bw.Write(IPAddress.HostToNetworkOrder((short)e.Delta)); }
Send(bw);
}
public void SendMouseWheel(MouseEventArgs e, byte action)
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Mouse));
bw.Write(IPAddress.HostToNetworkOrder((short)(e.Delta == 0 ? 10 : 12)));
bw.Write((short)0);
bw.Write(IPAddress.HostToNetworkOrder(LastX));
bw.Write(IPAddress.HostToNetworkOrder(LastY));
if (e.Delta != 0) { bw.Write(IPAddress.HostToNetworkOrder((short)e.Delta)); }
Send(bw);
}
private void SendMouse(byte action, KvmMouseButtonCommands buttons)
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Mouse));
bw.Write(IPAddress.HostToNetworkOrder((short)10));
bw.Write((byte)action);
bw.Write((byte)buttons);
bw.Write((short)0);
bw.Write((short)0);
Send(bw);
}
public void SendCompressionLevel()
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Compression));
bw.Write(IPAddress.HostToNetworkOrder((short)10));
bw.Write((byte)1); // Image Type (Reserved, 1 = JPEG)
bw.Write((byte)compressionlevel); // Compression Level
bw.Write(IPAddress.HostToNetworkOrder((short)scalinglevel)); // Scaling
bw.Write(IPAddress.HostToNetworkOrder((short)frameRate)); // Frame Rate
Send(bw);
}
public void SendRefresh()
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Refresh));
bw.Write(IPAddress.HostToNetworkOrder((short)4));
Send(bw);
}
public void SendPause(bool paused)
{
//if (remotepauseactive == false || paused == remotepause) return;
//if (paused == remotepause) return;
remotepause = paused;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.Pause));
bw.Write(IPAddress.HostToNetworkOrder((short)5));
bw.Write(paused ? (byte)1 : (byte)0);
Send(bw);
}
public void Send(byte[] buffer)
{
//if (state == ConnectState.Disconnected) return;
try
{
parent.wc.WriteBinaryWebSocket(buffer, 0, buffer.Length);
bytesent += buffer.Length;
}
catch (Exception) { }
}
public void Send(string str)
{
//if (state == ConnectState.Disconnected) return;
try
{
parent.wc.WriteStringWebSocket(str);
bytesent += str.Length;
}
catch (Exception) { }
}
public void Send(BinaryWriter bw)
{
//if (state == ConnectState.Disconnected) { RecycleBinaryWriter(bw); return; }
try
{
parent.wc.WriteBinaryWebSocket(((MemoryStream)bw.BaseStream).GetBuffer(), 0, (int)((MemoryStream)bw.BaseStream).Length);
bytesent += (int)((MemoryStream)bw.BaseStream).Length;
}
catch (Exception) { }
RecycleBinaryWriter(bw);
}
private void KVMControl_MouseDown(object sender, MouseEventArgs e)
{
SendMouse(e, 1);
}
private void KVMControl_MouseUp(object sender, MouseEventArgs e)
{
SendMouse(e, 2);
}
long lastMouseMove = 0;
private void KVMControl_MouseMove(object sender, MouseEventArgs e)
{
long ct = DateTime.Now.Ticks;
if ((lastMouseMove + 30) < ct) {
lastMouseMove = ct;
SendMouse(e, 0);
}
}
public void KVMControl_MouseWheel(object sender, MouseEventArgs e)
{
SendMouse(e, 0);
}
private void KVMControl_KeyDown(object sender, KeyEventArgs e)
{
SendKey(e, 0);
e.Handled = true;
}
private void KVMControl_KeyUp(object sender, KeyEventArgs e)
{
SendKey(e, 1);
e.Handled = true;
}
private void KVMControl_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
private void KVMControl_MouseEnter(object sender, EventArgs e)
{
this.Focus();
}
public void SendCtrlAltDel()
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.CtrlAltDel));
bw.Write(IPAddress.HostToNetworkOrder((short)4));
Send(bw);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
// Tab keys
if (msg.Msg == WM_KEYDOWN && msg.WParam.ToInt32() == 9)
{
SendKey((byte)msg.WParam.ToInt32(), 0);
return true;
}
// Handle arrow keys
if (((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN)) && msg.WParam.ToInt32() >= 37 && msg.WParam.ToInt32() <= 40)
{
SendKey((byte)msg.WParam.ToInt32(), 0);
return true;
}
return false;
}
public void GetDisplayNumbers()
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.GetDisplays));
bw.Write(IPAddress.HostToNetworkOrder((short)4));
Send(bw);
}
public void SendDisplay(int dispNo)
{
//if (state != ConnectState.Connected) return;
BinaryWriter bw = GetBinaryWriter();
bw.Write(IPAddress.HostToNetworkOrder((short)KvmCommands.SetDisplay));
bw.Write(IPAddress.HostToNetworkOrder((short)6));
bw.Write(IPAddress.HostToNetworkOrder((short)dispNo));
Send(bw);
}
public void SendWindowsKey()
{
SendKey(0x5B, 4); // Windows key down
SendKey(0x5B, 3); // Windows key up
}
public void SendCharmsKey()
{
SendKey(0x5B, 4); // Windows key down
SendKey(67, 1); // C down
SendKey(67, 2); // C up
SendKey(0x5B, 3); // Windows key up
}
// BinaryWriter Object Recycling System
private static Stack<BinaryWriter> BinaryWriteRecycleList = new Stack<BinaryWriter>();
public static BinaryWriter GetBinaryWriter() { lock (BinaryWriteRecycleList) { return (BinaryWriteRecycleList.Count == 0) ? new BinaryWriter(new MemoryStream(32000), Encoding.UTF8) : BinaryWriteRecycleList.Pop(); } }
public static void RecycleBinaryWriter(BinaryWriter obj) { lock (BinaryWriteRecycleList) { ((MemoryStream)obj.BaseStream).SetLength(0); BinaryWriteRecycleList.Push(obj); } }
// MemoryStream Object Recycling System
private static Stack<MemoryStream> MemoryStreamRecycleList = new Stack<MemoryStream>();
public static MemoryStream GetMemoryStream() { lock (MemoryStreamRecycleList) { return (MemoryStreamRecycleList.Count == 0) ? new MemoryStream(32000) : MemoryStreamRecycleList.Pop(); } }
public static void RecycleMemoryStream(MemoryStream obj) { lock (MemoryStreamRecycleList) { obj.SetLength(0); MemoryStreamRecycleList.Push(obj); } }
// StringBuilder Object Recycling System
private static Stack<StringBuilder> StringBuilderRecycleList = new Stack<StringBuilder>();
public static StringBuilder GetStringBuilder() { lock (StringBuilderRecycleList) { return (StringBuilderRecycleList.Count == 0) ? new StringBuilder(16000) : StringBuilderRecycleList.Pop(); } }
public static void RecycleStringBuilder(StringBuilder obj) { lock (StringBuilderRecycleList) { obj.Length = 0; StringBuilderRecycleList.Push(obj); } }
// byte[] Object Recycling System
private static Stack<byte[]> ByteArrayRecycleList = new Stack<byte[]>();
private static int ByteArrayRecycleListCount = 0;
public static byte[] GetByteArray() { lock (ByteArrayRecycleList) { if (ByteArrayRecycleList.Count == 0) ByteArrayRecycleListCount++; return (ByteArrayRecycleList.Count == 0) ? new byte[65535] : ByteArrayRecycleList.Pop(); } }
public static void RecycleByteArray(byte[] obj) { lock (ByteArrayRecycleList) { if (obj != null) ByteArrayRecycleList.Push(obj); } }
}
}

120
KVMControl.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

128
KVMResizeControl.Designer.cs generated Normal file
View File

@@ -0,0 +1,128 @@
namespace MeshCentralRouter
{
partial class KVMResizeControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.rightScrollPanel = new System.Windows.Forms.Panel();
this.vScrollBar = new System.Windows.Forms.VScrollBar();
this.cornerBlockPanel = new System.Windows.Forms.Panel();
this.hScrollBar = new System.Windows.Forms.HScrollBar();
this.clientPanel = new System.Windows.Forms.Panel();
this.kvmControl = new MeshCentralRouter.KVMControl();
this.rightScrollPanel.SuspendLayout();
this.clientPanel.SuspendLayout();
this.SuspendLayout();
//
// rightScrollPanel
//
this.rightScrollPanel.Controls.Add(this.vScrollBar);
this.rightScrollPanel.Controls.Add(this.cornerBlockPanel);
this.rightScrollPanel.Dock = System.Windows.Forms.DockStyle.Right;
this.rightScrollPanel.Location = new System.Drawing.Point(1159, 0);
this.rightScrollPanel.Name = "rightScrollPanel";
this.rightScrollPanel.Size = new System.Drawing.Size(17, 789);
this.rightScrollPanel.TabIndex = 12;
//
// vScrollBar
//
this.vScrollBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.vScrollBar.LargeChange = 100;
this.vScrollBar.Location = new System.Drawing.Point(0, 0);
this.vScrollBar.Name = "vScrollBar";
this.vScrollBar.Size = new System.Drawing.Size(17, 772);
this.vScrollBar.TabIndex = 10;
this.vScrollBar.ValueChanged += new System.EventHandler(this.vScrollBar_ValueChanged);
//
// cornerBlockPanel
//
this.cornerBlockPanel.BackColor = System.Drawing.SystemColors.Control;
this.cornerBlockPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
this.cornerBlockPanel.Location = new System.Drawing.Point(0, 772);
this.cornerBlockPanel.Name = "cornerBlockPanel";
this.cornerBlockPanel.Size = new System.Drawing.Size(17, 17);
this.cornerBlockPanel.TabIndex = 11;
this.cornerBlockPanel.Visible = false;
//
// hScrollBar
//
this.hScrollBar.Dock = System.Windows.Forms.DockStyle.Bottom;
this.hScrollBar.LargeChange = 100;
this.hScrollBar.Location = new System.Drawing.Point(0, 772);
this.hScrollBar.Name = "hScrollBar";
this.hScrollBar.Size = new System.Drawing.Size(1159, 17);
this.hScrollBar.TabIndex = 13;
this.hScrollBar.ValueChanged += new System.EventHandler(this.hScrollBar_ValueChanged);
//
// clientPanel
//
this.clientPanel.Controls.Add(this.kvmControl);
this.clientPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.clientPanel.Location = new System.Drawing.Point(0, 0);
this.clientPanel.Name = "clientPanel";
this.clientPanel.Size = new System.Drawing.Size(1159, 772);
this.clientPanel.TabIndex = 15;
//
// kvmControl
//
this.kvmControl.BackColor = System.Drawing.Color.LightCoral;
this.kvmControl.CompressionLevel = 60;
this.kvmControl.Location = new System.Drawing.Point(33, 31);
this.kvmControl.Margin = new System.Windows.Forms.Padding(4);
this.kvmControl.Name = "kvmControl";
this.kvmControl.ScaleFactor = 1D;
this.kvmControl.ScalingLevel = 1024;
this.kvmControl.Size = new System.Drawing.Size(450, 314);
this.kvmControl.TabIndex = 14;
this.kvmControl.DesktopSizeChanged += new System.EventHandler(this.kvmControl_DesktopSizeChanged);
this.kvmControl.Resize += new System.EventHandler(this.kvmControl_Resize);
//
// KVMResizeControl
//
this.BackColor = System.Drawing.Color.Gray;
this.Controls.Add(this.clientPanel);
this.Controls.Add(this.hScrollBar);
this.Controls.Add(this.rightScrollPanel);
this.Name = "KVMResizeControl";
this.Size = new System.Drawing.Size(1176, 789);
this.Resize += new System.EventHandler(this.ResizeKVMControl_Resize);
this.rightScrollPanel.ResumeLayout(false);
this.clientPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel rightScrollPanel;
private System.Windows.Forms.VScrollBar vScrollBar;
private System.Windows.Forms.Panel cornerBlockPanel;
private System.Windows.Forms.HScrollBar hScrollBar;
private KVMControl kvmControl;
private System.Windows.Forms.Panel clientPanel;
}
}

138
KVMResizeControl.cs Normal file
View File

@@ -0,0 +1,138 @@
/*
Copyright 2009-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Windows.Forms;
using System.ComponentModel;
namespace MeshCentralRouter
{
public partial class KVMResizeControl : UserControl
{
private bool zoomtofit = false;
public KVMControl KVM { get { return kvmControl; } }
public bool ZoomToFit { get { return zoomtofit; } set { zoomtofit = value; CenterKvmControl(false); } }
[Category("Action")]
[Description("Fires when the connection state changes.")]
public event EventHandler StateChanged;
[Category("Action")]
[Description("Fires when the display list is received.")]
public event EventHandler DisplaysReceived;
public KVMResizeControl()
{
InitializeComponent();
vScrollBar.LargeChange = 100;
vScrollBar.SmallChange = 10;
hScrollBar.LargeChange = 100;
hScrollBar.SmallChange = 10;
//KVM.StateChanged += new EventHandler(KVM_StateChanged);
KVM.DisplaysReceived += new EventHandler(KVM_DisplaysReceived);
CenterKvmControl(false);
}
void KVM_StateChanged(object sender, EventArgs e)
{
if (InvokeRequired) { Invoke(new EventHandler(KVM_StateChanged), sender, e); return; }
CenterKvmControl(false);
kvmControl.Visible = false;
//kvmControl.Visible = (kvmControl.State == KVMControl.ConnectState.Connected);
if (StateChanged != null) StateChanged(this, e);
}
void KVM_DisplaysReceived(object sender, EventArgs e)
{
if (InvokeRequired) { Invoke(new EventHandler(KVM_DisplaysReceived), sender, e); return; }
if (DisplaysReceived != null) DisplaysReceived(this, e);
}
public void CenterKvmControl(bool forceRefresh)
{
int w = clientPanel.Width;
int h = clientPanel.Height;
int l = 0;
int t = 0;
bool invalidate = true;
if (zoomtofit == false)
{
if (kvmControl.Width != kvmControl.DesktopWidth || kvmControl.Height != kvmControl.DesktopHeight || kvmControl.ScaleFactor != 1)
{
kvmControl.Size = new System.Drawing.Size(kvmControl.DesktopWidth, kvmControl.DesktopHeight);
kvmControl.ScaleFactor = 1;
invalidate = true;
}
hScrollBar.Visible = (w < kvmControl.DesktopWidth);
rightScrollPanel.Visible = vScrollBar.Visible = (h < kvmControl.DesktopHeight);
cornerBlockPanel.Visible = (hScrollBar.Visible & vScrollBar.Visible);
}
else
{
hScrollBar.Visible = false;
rightScrollPanel.Visible = false;
double sfx = (double)kvmControl.DesktopWidth / (double)Width;
double sfy = (double)kvmControl.DesktopHeight / (double)Height;
double sf = Math.Max(sfx, sfy);
sf = Math.Max(1, sf);
if ((kvmControl.ScaleFactor != sf) || (forceRefresh))
{
kvmControl.Size = new System.Drawing.Size((int)((double)kvmControl.DesktopWidth / sf), (int)((double)kvmControl.DesktopHeight / sf));
kvmControl.ScaleFactor = sf;
invalidate = true;
}
}
if (w < kvmControl.Width) { hScrollBar.Maximum = (kvmControl.Width - w) + 100; } else { l = (w - kvmControl.Width) / 2; }
if (h < kvmControl.Height) { vScrollBar.Maximum = (kvmControl.Height - h) + 100; } else { t = (h - kvmControl.Height) / 2; }
if (vScrollBar.Visible) { kvmControl.Top = 0 - vScrollBar.Value; } else { kvmControl.Top = t; }
if (hScrollBar.Visible) { kvmControl.Left = 0 - hScrollBar.Value; } else { kvmControl.Left = l; }
if (invalidate) kvmControl.Invalidate();
}
private void kvmControl_Resize(object sender, EventArgs e)
{
CenterKvmControl(false);
}
private void ResizeKVMControl_Resize(object sender, EventArgs e)
{
CenterKvmControl(false);
}
private void vScrollBar_ValueChanged(object sender, EventArgs e)
{
kvmControl.Top = -vScrollBar.Value;
}
private void hScrollBar_ValueChanged(object sender, EventArgs e)
{
kvmControl.Left = -hScrollBar.Value;
}
private void kvmControl_DesktopSizeChanged(object sender, EventArgs e)
{
CenterKvmControl(true);
}
public void MouseWheelEx(object sender, MouseEventArgs e)
{
//if (KVMControl.WPF) kvmControl.SendMouseWheel(e, 0);
}
}
}

120
KVMResizeControl.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

210
KVMSettingsForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,210 @@
namespace MeshCentralRouter
{
partial class KVMSettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(KVMSettingsForm));
this.cancelButton = new System.Windows.Forms.Button();
this.okButton = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.qualityComboBox = new System.Windows.Forms.ComboBox();
this.scalingComboBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.frameRateComboBox = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// cancelButton
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(312, 182);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(75, 23);
this.cancelButton.TabIndex = 0;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseVisualStyleBackColor = true;
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.Location = new System.Drawing.Point(231, 182);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 1;
this.okButton.Text = "OK";
this.okButton.UseVisualStyleBackColor = true;
this.okButton.Click += new System.EventHandler(this.okButton_Click);
//
// groupBox1
//
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.frameRateComboBox);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.scalingComboBox);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.qualityComboBox);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Location = new System.Drawing.Point(12, 68);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(375, 108);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Compression Settings";
//
// pictureBox1
//
this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.pictureBox1.Image = global::MeshCentralRouter.Properties.Resources._50_Computer;
this.pictureBox1.Location = new System.Drawing.Point(337, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(50, 50);
this.pictureBox1.TabIndex = 3;
this.pictureBox1.TabStop = false;
//
// label4
//
this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label4.Location = new System.Drawing.Point(12, 12);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(319, 50);
this.label4.TabIndex = 4;
this.label4.Text = "Remote desktop quality, scaling and frame rate settings. These can be adjusted de" +
"pending on the quality of the network connection.";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(9, 24);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(39, 13);
this.label3.TabIndex = 4;
this.label3.Text = "Quality";
//
// qualityComboBox
//
this.qualityComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.qualityComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.qualityComboBox.FormattingEnabled = true;
this.qualityComboBox.Location = new System.Drawing.Point(128, 21);
this.qualityComboBox.Name = "qualityComboBox";
this.qualityComboBox.Size = new System.Drawing.Size(238, 21);
this.qualityComboBox.TabIndex = 5;
//
// scalingComboBox
//
this.scalingComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.scalingComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.scalingComboBox.FormattingEnabled = true;
this.scalingComboBox.Location = new System.Drawing.Point(128, 48);
this.scalingComboBox.Name = "scalingComboBox";
this.scalingComboBox.Size = new System.Drawing.Size(238, 21);
this.scalingComboBox.TabIndex = 7;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(9, 51);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(42, 13);
this.label1.TabIndex = 6;
this.label1.Text = "Scaling";
//
// frameRateComboBox
//
this.frameRateComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.frameRateComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.frameRateComboBox.FormattingEnabled = true;
this.frameRateComboBox.Location = new System.Drawing.Point(128, 75);
this.frameRateComboBox.Name = "frameRateComboBox";
this.frameRateComboBox.Size = new System.Drawing.Size(238, 21);
this.frameRateComboBox.TabIndex = 9;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(9, 78);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(57, 13);
this.label2.TabIndex = 8;
this.label2.Text = "Frame rate";
//
// KVMSettingsForm
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(399, 217);
this.Controls.Add(this.label4);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.okButton);
this.Controls.Add(this.cancelButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "KVMSettingsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Remote Desktop Settings";
this.Load += new System.EventHandler(this.SettingsForm_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.ComboBox frameRateComboBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ComboBox scalingComboBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox qualityComboBox;
private System.Windows.Forms.Label label3;
}
}

131
KVMSettingsForm.cs Normal file
View File

@@ -0,0 +1,131 @@
/*
Copyright 2009-2011 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Data;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
namespace MeshCentralRouter
{
public partial class KVMSettingsForm : Form
{
public KVMSettingsForm()
{
InitializeComponent();
qualityComboBox.Items.Add(new DropListItem(90, "90%"));
qualityComboBox.Items.Add(new DropListItem(80, "80%"));
qualityComboBox.Items.Add(new DropListItem(70, "70%"));
qualityComboBox.Items.Add(new DropListItem(60, "60%"));
qualityComboBox.Items.Add(new DropListItem(50, "50%"));
qualityComboBox.Items.Add(new DropListItem(40, "40%"));
qualityComboBox.Items.Add(new DropListItem(30, "30%"));
qualityComboBox.Items.Add(new DropListItem(20, "20%"));
qualityComboBox.Items.Add(new DropListItem(10, "10%"));
qualityComboBox.Items.Add(new DropListItem(5, "5%"));
qualityComboBox.Items.Add(new DropListItem(1, "1%"));
scalingComboBox.Items.Add(new DropListItem(1024, "100%"));
scalingComboBox.Items.Add(new DropListItem(896, "87.5%"));
scalingComboBox.Items.Add(new DropListItem(768, "75%"));
scalingComboBox.Items.Add(new DropListItem(640, "62.5%"));
scalingComboBox.Items.Add(new DropListItem(512, "50%"));
scalingComboBox.Items.Add(new DropListItem(384, "37.5%"));
scalingComboBox.Items.Add(new DropListItem(256, "25%"));
scalingComboBox.Items.Add(new DropListItem(128, "12.5%"));
frameRateComboBox.Items.Add(new DropListItem(50, "Fast"));
frameRateComboBox.Items.Add(new DropListItem(100, "Medium"));
frameRateComboBox.Items.Add(new DropListItem(400, "Slow"));
frameRateComboBox.Items.Add(new DropListItem(1000, "Very slow"));
qualityComboBox.SelectedIndex = 4;
scalingComboBox.SelectedIndex = 0;
frameRateComboBox.SelectedIndex = 1;
}
private class DropListItem
{
public int value;
public string str;
public DropListItem(int value, string str) { this.value = value; this.str = str; }
public override string ToString() { return str; }
}
private void SettingsForm_Load(object sender, EventArgs e)
{
}
public int Compression
{
get { return ((DropListItem)qualityComboBox.SelectedItem).value; }
set
{
if (value >= 90) { qualityComboBox.SelectedIndex = 0; return; }
if (value >= 80) { qualityComboBox.SelectedIndex = 1; return; }
if (value >= 70) { qualityComboBox.SelectedIndex = 2; return; }
if (value >= 60) { qualityComboBox.SelectedIndex = 3; return; }
if (value >= 50) { qualityComboBox.SelectedIndex = 4; return; }
if (value >= 40) { qualityComboBox.SelectedIndex = 5; return; }
if (value >= 30) { qualityComboBox.SelectedIndex = 6; return; }
if (value >= 20) { qualityComboBox.SelectedIndex = 7; return; }
if (value >= 10) { qualityComboBox.SelectedIndex = 8; return; }
if (value >= 5) { qualityComboBox.SelectedIndex = 9; return; }
qualityComboBox.SelectedIndex = 10;
}
}
public int Scaling
{
get { return ((DropListItem)scalingComboBox.SelectedItem).value; }
set
{
if (value >= 1024) { scalingComboBox.SelectedIndex = 0; return; }
if (value >= 896) { scalingComboBox.SelectedIndex = 1; return; }
if (value >= 768) { scalingComboBox.SelectedIndex = 2; return; }
if (value >= 640) { scalingComboBox.SelectedIndex = 3; return; }
if (value >= 512) { scalingComboBox.SelectedIndex = 4; return; }
if (value >= 384) { scalingComboBox.SelectedIndex = 5; return; }
if (value >= 256) { scalingComboBox.SelectedIndex = 6; return; }
scalingComboBox.SelectedIndex = 7;
}
}
public int FrameRate
{
get { return ((DropListItem)frameRateComboBox.SelectedItem).value; }
set
{
if (value <= 50) { frameRateComboBox.SelectedIndex = 0; return; }
if (value <= 100) { frameRateComboBox.SelectedIndex = 1; return; }
if (value <= 400) { frameRateComboBox.SelectedIndex = 2; return; }
frameRateComboBox.SelectedIndex = 3;
}
}
private void okButton_Click(object sender, EventArgs e)
{
DialogResult = System.Windows.Forms.DialogResult.OK;
}
private void cancelButton_Click(object sender, EventArgs e)
{
DialogResult = System.Windows.Forms.DialogResult.Cancel;
}
}
}

546
KVMSettingsForm.resx Normal file
View File

@@ -0,0 +1,546 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAkAEBAQAAEABAAoAQAAlgAAABAQAAABAAgAaAUAAL4BAAAgIBAAAQAEAOgCAAAmBwAAICAAAAEA
CACoCAAADgoAADAwEAABAAQAaAYAALYSAAAwMAAAAQAIAKgOAAAeGQAAEBAAAAEAIABoBAAAxicAACAg
AAABACAAqBAAAC4sAAAwMAAAAQAgAKglAADWPAAAKAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8A
AAD/AP8A//8AAP///wAACIiHh4eAAAAPiIh4eAAAAAAIh3eAAACIiIiIiIh4eI+IiIiIiIiIiEREREZE
Z4iIRGRMfIyMiIhlxMTIeMeIiFZEbHjIjoiIbExMiIiHiIhWxsyIiIiIiExMx4iIiIiITGzIj4+IiIhM
TM6I6OiIiHiIiIeIiIgI+IiIiIiIiOAHAADgDwAA+B8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAAB
AAAAAQAAAAAAAIAAAACGCwkAlAAAAJQNAgCfEQAAnBsQAJgdEQCiDgAAqQ0AAKgSAACqFQAApxkNAKUc
DwCyEgAAsRUAALQXAAC/FgIAuBgAAL0YAACaJhwArCcVAKMnHQC7Mh8AmDAoAJ42LACqMCMApTctAKU+
MwDAGwAAwRwAAMUdAADKGgAAyh4FANIbAADdGQAA4RoAAOcaAADRIQAA1SMAAPEnCQDkMxMAvkwqALpI
OADMSjYA81A1AKVIQACtSkEAr1ZMAM5dTADUXUgA1GZKANhgSwDdYUwA3WpXAON5ZgDgfWsA6HxoAPp9
aADmgWgA7IBrAPiKawDqi3oA8JtyAPahdwD6qH8AiYuLAIyOjgCXmpoAmp2dAJ6fnwCeoaEAoKGhAKOj
pACipKQApKamAKaoqQCoqqoAqaytAKyurwCvsbEAsbS1ALO3uAC1uLkAtru8ALm+vgDvk4IA7ZuNAPOX
hQDzn4oA9ZyLAPuuiQD3qpsA+q6eAPu0kQD0saYA+7KjAPi1oAD+sqQA+7+iAP7DswD6xrQA/8a2AP7G
ugD/yboA+s2+ALzBwQC+xMQAvsvNAL/MzQDFyMkAwczNAMnMzADDztAAxM7QAMbQ0QDJ0dIAytLUAMzT
1QDN1NUA1NbXANjY2ADc3NwA/9LGAP/UxgD/1cgA/9rLAP/i2QD/5twA/+nfAN7h4QDo6OgA/+rgAP/r
5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AAAAAFVVUk1GRkZGRkYAAAAAAACDeXduU0tGTUYAAAAAAAAAAAB5T0RDQ24AAAAAAIJr
a1VVU1JPT09NTEtLRm53d3J0cnNuc3JucW1tbW1Ld08BAQIBAQMVFRUVFSttS3dNBxQHBAUKFzEyNDUq
bUt3TRgYBwoKDyw4Nzk8NG1Ld0wuHAcPDxE2V1ZYWjtuTXdLMBsIDxIhPl9cXWJZc013Sy8WDxIiKWJn
ZGRoX21Pd0saCR0nJC17fXt+fmVtT3dGDRAdJyU6hX9/hIRoc093SwwRISMoPWNeW0FAP3NSd0ZGRktL
S01PT09SUlNzUgB3d3d3d3d3d3d3c3dzcnjgBwAA4A8AAPgfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAKAAAACAAAABAAAAAAQAEAAAAAAAAAgAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8A
AAD/AP8A//8AAP///wAAAAAAAAAAj4AAAAAAAAAAAAAAAAAIj4iIiAAAAAAAAAAAAAAIj4+Pj4iIAAAA
AAAAAAAAiIj4+I+IiIcAAAAAAAAACIiIj4iIiIh4cAAAAAAAAAiIiPiPiIiHeAAAAAAAAAAIiIiIiIiH
d4cAAAAAAAAAAAiIiId3d3eIiIAAAAAAAAAAh3d3d3eIiIiAAAAAAAAAAACHd3iIiIiIgAAAAAAAAIeH
iIiIh8fEeHAAAAAId4iIiId3xExETH+AAAAAeIiId3RExExsbGx4gAAAD3d3RERERExnx8fHz3AAAACE
RERETExEx8fIx8+IAAAAhERkTERGxnyMjI54iAAAAIR8VkRGxEyMjnjIyIgAAACHRkxExEzGh3fIjIiI
AAAAh0d8RkxsTIeIh4joiAAAAIfHx0xExMiHd46HiIgAAACIR3xExsbHiI6IiHiHAAAAiEjERMTMyI6I
iIiIiAAAAAhHxMbGzGiIiIiIiIiAAAAIbEZMzGzPiIiIiIiIgAAACFZMTGzMj4+Pj4+IiIAAAAhsTGxM
bIj4+Pj/+PiAAAAIVETEzMz/+P+Pj4iIgAAACHTGzGzOiIiIiIiIj3AAAAiETEzGx4iIiIiI+PgAAAAI
hHd3iIiIj4//AAAAAAAACIiIj4+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/8f///4A///4AD//8A
AP/+AAB//gAA//4AAP//gAAf/8AAH//wAB//AAAf4AAAH8AAAB+AAAAfwAAAD8AAAA/AAAAPwAAAD8AA
AA/AAAAPwAAAD8AAAA/gAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAP4AAD/+AH////////KAAAACAA
AABAAAAAAQAIAAAAAAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAB+AQAAZmdmAGlpagB2dnYAfX1+AIIA
AACMAgAAhQsCAIwMAQCSAAAAmAcAAJMLAQCbDgAAkwwIAIsUCgCUEgUAnRAAAJIYDACLHBQAkB4WAJoe
EgCmAAAAqgYAAKELAAC5CAAApBIAAKsUAACqGAYArBwJALIVAAC5EwAAsxgBALsZAACNJBwAkyQcAKYg
DwC2IA0AoCATAKwjEQCgJxoAsy0bALcxHgCSJiAAliskAJYvKACfMCUAmjIqAI85NACZNjAAmz01AJc+
OAC0MiEAvDUhAL0/LQDFEwAAwhsAAMsdAADQHAAA2BwAAO8UAADkGwAA6x0AANMgAADbIgAA2iQMAMAs
FQDlIQAA5S4LAPIqAwDhLhgA9j8dAMs8JQDOPygAmUQ8AKhANgCgQTkAr0U6AMNCLwDDRTIAyUYyAMxI
MwDBTD8AzVI/ANZROQDaVj8A8UQiAP5UMgCZU00Al1RRAKRKRACuVUwAsVJHALBUSgCiWlUArFhRALFc
VQCzZF0AmmtqALFvZgC5a2QAr3FtALdwawC+dWsAoHVyALZ4cQDHU0IAzF1MANFWQQDVWUQA2FpFANVe
SAD1X0IAxGlaANVlUgDcZlIA3WhUANhuXQDiY0kA4mZQAOJqVADpcFoAxnRoAN10YgDjd2QA5nllAOp8
ZgDyfGYA6IBtAPqFbgDjhHQA6YZ0AOyIdgDuingA8Y16APqNeQCDhIQAi4yOAIuOkgCOlZoAlZWVAJSV
mACWm5wAnZ2dAKGFhQCzhIEAp5KSAKCfnwCqnZ4AspOTAL2VkwC5nJsAuaGcAJeepACVoaYAnKCmAJit
qgCfrrEAoqKiAKukpwCmpqgApqmrAKurqwCyp6kAsKqsAKyssAClsLMArbKzAKS6tgCttbkAs7O0ALW5
vAC6ursA0ZWSAO2WhgDrmIoA8piHAPWbigD7nowAy6KcAOKqnADtrJ0A8qOVAPikkwDwqZ0A/KubAPG1
ngD/sJ0A9bieAMCtrADbtKoAwre0AMq1sQDFuLYAwbu9ANG1sADbuLMA4K6jAOu8pwDgtKgA57+tAPWw
ogD7tKUA+b+mAPS3qwD+vK0A/r+xANXCvgD1wKoA+8euAOjGuAD+xLIA/sm1AP7EuQD9y7sAvb/DAMG/
wQC3wcQAvMLDALnGyAC+y8wAw8PDAMTFyADDyswAy8vLANXKxgDSzcsA2M/LAMLP0ADMz9AAx9XWAMzT
1ADK1tgA09PTANLW2ADU2twA29zcAOzPwgD/zsEA/9LDAP/VyQD/2coA5NvXAOvc1gDs3tgA/93SAP/h
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
AADwAAAAAB8AAPAAAAAAHwAA8AAAAAAfAADwAAAAAB8AAPAAAAAAHwAA8AAAAAAfAADwAAAAAB8AAPgA
AAAAHwAA+AAAAAAPAAD4AAAAAB8AAPgAAAAAPwAA+AAAAD//AAD4AAA///8AAPgAP////wAA/D//////
AAD///////8AACgAAAAwAAAAYAAAAAEACAAAAAAAAAkAAAAAAAAAAAAAAAEAAAABAAAAAAAAX19fAGVl
ZQBrbGsAdHR1AHp6egCDAQAAhAoBAIsMAACUBgAAmQYAAJMNAACaDQAAhxEIAIoUCwCOGAwAlBIEAJwQ
AQCTFgkAnhsNAIwaEgCnDAAAtAYAAKMSAACqFAAAphgGAKMbCwCqHgwAshUAALYYAAC7GQAAsR4LAIsj
GgCVJRsAtSILALkgCwCnJBUAqyQSAK4oFwCxJRIAsCoXALsrFwCzLBoAuS4aALIwHwC6MBwAii8oAJUq
IwCJMCkAmTAnAJkzKwCcOS8Aijs0AJw8NACvNicApTYrALUzIAC8NSIAtzopALo7KQClPDIAwxsAAMsd
AADTHQAA5RoAAMYjCADYIQAAzzAVAOckAADwKAIA9TEKAO85FgD0OBIAwTciAMI5JADBPisAyT4oANY8
IgClQzsAvUQ0ALdKNwDFQS0AykQvANBDLADCRjQAykUwAMRINgDKSjYAwko6AM5NOADXTjYA0VA8APRK
KACNSUEAk0pFAJtTTgCXWFQApktEAKpRSgCzUEUAuVBCALFWTAC4VEoArVdQAKtYUgCmXVgAtF1TALBf
WgCbY14At2BUAJVlYQCcfHkAomZhALhrYwC7c2wAoHRzAL54cAC2f3sAylVDANVaRgDiWkIA12JOANlo
VQDpZUwA+GFDAORrVQDncl0AxHVqAM56bgDRcGIA3XRiAN57awDBfHUA5XpnAPt+ZQCugXsA3oFvAMWF
fADYinwA5oBuAPOBawDqiHYA9Yp1APaRfQCCgoMAioqMAJ2EgwCIkI4AgJ2MAIyNkQCOkZUAjJOYAJKS
lACWlpkAmpqbAKSKigC0iIUAs42LALGSjgCmmJgAh6SYAJ2eogCaoaYAnaWpAJ+trACjo6MApKaqAKim
qACjqawAq6urALWpqQCurrAArLK1AK+4uwC0tLQAurO0ALW2uAC8t7gAtby/ALu7uwDOkIUAyZaPAMSf
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
1v+kpab/r1ZM/6U3Lf+iDgD/sBYA/70YAP/KHgX/6ot6//Sxpv/3qpv/+q6e//6ypP/zn4r/ws3O/6iq
qv/O1NX/oqSk/61KQf+jJx3/sBQA/8EcAP/SGwD/5DMT//uyo//+xrr//sOz///Gtv//ybr/+LWg/8LO
z/+qrKz/zdTW/6Gjo/+qMCP/qQ0A/8AbAP/RIQD/4RoA//NQNf//0sb//9TI///Uxv//18j//9rL//rG
tP/Dzs//rK6v/87U1v+goaH/pRwP/7MWAP/FHQD/1SMA/+caAP/6fWj//+vm///i2f//5tz//+nf///q
4P/6zb7/xM7Q/6+ysv/O1Nb/oKGh/6cZDf+4GAD/yhoA/90ZAP/xJwn/+Ipr//u/ov/7tJH/+66J//qo
f//2oXf/8Jty/8XO0P+xtLX/ztTW/6Chof+goaH/oKGh/6Gio/+jpaX/paen/6epqf+prKz/rK+v/6+x
sf+xtLX/tLi4/7a7vP/Fz9H/s7e4/87U1njO1Nb/ztTW/87U1v/N1Nb/zdPV/83T1f/M09X/y9LU/8rS
1P/K0tP/ydHT/8jR0v/H0NH/xs/R/7a6u5XgBwAA4AcAAPAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAACAEAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjo6MDurq6I7S0
tFatra18t7e3hbm5uYeoqKiGjo6Of4KCgmB7e3stg4ODCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkJCQHbCw
sHzHx8fIzs7O8NXV1fvZ2dn+1tbW/s7Ozv7MzMz8wsLC9Kurq9WUlJRrjo6OMAAAAAAAAAAAAAAAAAAA
AAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJWV
lWu+vr7r0tLS/9fX1//b29v/3t7e/9zc3P/U1NT/zc3N/93d3f/b29v/wcHB/8XFxf+4uLj+eXl5UBMT
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiCyqqqrOzc3N/83Nzf/Ly8v/z8/P/9PT
0//X19f/2tra/9vb2//a2tr/19fX/9LS0v/MzMz/0dHR/9/f3//Z2dn/wMDA/7e3t/++vr7/ycnJ/7i4
uP+wsLD9WVlZiAAAABYAAAAjAAAAKwAAACsAAAAlAAAAGQAAAA0AAAAGAAAAAwAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi4uLJbS0tOfIyMj/w8PD/8bG
xv/Ly8v/zs7O/9LS0v/X19f/29vb/9zc3P/c3Nz/2NjY/9HR0f/Kysr/09PT/+Hh4f/Q0ND/ubm5/8DA
wP/Pz8//urq6/62trf+urq7/ubm5/2FhYawAAABDAAAARgAAAEAAAAA2AAAAKQAAABwAAAARAAAACQAA
AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJiYkDq6urvcDA
wP++vr7/wsLC/8TExP/IyMj/zMzM/9HR0f/X19f/29vb/93d3f/c3Nz/2NjY/9HR0f/Jycn/0tLS/9vb
2//FxcX/wcHB/8nJyf+6urr/sLCw/66urv+oqKj/oqKi/6qqqv8fHx93AAAATgAAAEkAAAA+AAAAMwAA
ACYAAAAbAAAAEQAAAAoAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAChoaEXtra29Lm5uf+8vLz/v7+//8LCwv/FxcX/ycnJ/87Ozv/U1NT/2dnZ/9zc3P/b29v/1tbW/87O
zv/Hx8f/zMzM/8zMzP/AwMD/w8PD/7e3t/+ysrL/rq6u/6SkpP+ampr/l5eX/6qqqv9GRkaXAAAARwAA
AEgAAABAAAAANQAAACgAAAAfAAAAFgAAAA4AAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAC6uroWtLS08be3t/+5ubn/vLy8/7+/v//BwcH/xcXF/8nJyf/Pz8//1NTU/9bW
1v/V1dX/0dHR/8rKyv/ExMT/xcXF/8DAwP++vr7/t7e3/7Gxsf+pqan/n5+f/5WVlf+SkpL/mJiY/6ur
q/9RUVGcAAAAPAAAAEEAAAA6AAAAMQAAACcAAAAeAAAAFgAAAA4AAAAHAAAAAwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0tLQCtbW1y7W1tf+3t7f/ubm5/729vf+/v7//wcHB/8TE
xP/Hx8f/y8vL/83Nzf/MzMz/ycnJ/8XFxf/BwcH/v7+//7q6uv+ysrL/qamp/6Ghof+Xl5f/kpKS/5OT
k/+YmJj/nZ2d/6urq/8pKSltAAAALgAAADQAAAAzAAAALAAAACMAAAAaAAAAEwAAAAwAAAAHAAAAAgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqampQrOzs/e7u7v/t7e3/7q6
uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/FxcX/wsLC/7y8vP+1tbX/ra2t/6ampv+bm5v/jIyM/3t7
e/95eXn/ioqK/5SUlP+bm5v/pqam/4GBgcoWFhZFODk5YTk5Olpubm5aEhISKQAAABwAAAAWAAAADgAA
AAgAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGdn
Z0WZmZnNu7u7/7a2tv+zs7P/tLS0/7S0tP+zs7P/srKy/7CwsP+tra3/pqam/5ubm/+SkpL/iIiI/3x8
fP9qamn/X19f/2VlZf97e3z/jY6O/56en/+sra3/tre3/pubnM6urq/iycrK/7a2t+6IiIi+Z2dnKwAA
ABEAAAALAAAABwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAICAgGTk5ObJ2dneiurq7/qamp/6Ojo/+enp7/m5ub/5ycnP+Pj4//goGB/3p6
ev9zc3P/bm5u/2tsbP91dnf/hIWG/5iYmv+goaL/sLCx/7e3uP+3t7f/u7u7/8HBwf/AwMD/v7+//L6+
vv+Xl5ftgICAMQAAAAMAAAADAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAGAAAAABAQECNGRkZ0eXl5v4+PjuKgoKD4o6Oj/ouL
iv97e3v/gICB/4SEhf+IiYv/kJCT/5manP+oqKv/rq6w/66ur/+vr7D/r6+w/7a3t/+1t7f/u8LD/8LM
zf/Jzs//wcDA/by8vPyfn5/6b29vUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAGAAAACQAAAAwAAAAOAAAADQAAAAUAAAAAFhYXC0BA
QjBvb3GBjo+R7oqKjf+OjpL/kJCU/4+QlP+Skpb/lpaZ/56eof+lpaf/p6mr/6yxtP+1vsD/wMnL/87T
1P/W09P/2cnG/9+4tP/Wvrn/wMXF/cHBwfyioqL8jIyMbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAQEARQUFQgtLS8XSkpMNWpq
bGaCgoaYj4+TxJSUmOWQkJT4jY2R/42Nkf+MjJH/i42R/4uOk/+Nkpf/nKSo/6+4u//Dycv/z87P/9TH
xv/Usq7/2p+U/9FwYv/HQS7/wBwE/7QGAP+zX1X/w87P/sTExPyhoaH+n5+fiwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhoHJCQlHT8/QTBbW15MfX2AgY6O
kbCYmJ3anJyh+Zubn/+Xl5v/jo6S/4yMkf+KjpL/jJOY/5ihpf+hqKv/rauv/7mwsv/HvLz/yK2q/8mW
j//Oem7/wko6/7kgC/+0FAD/rBAA/6URAP+lFgP/phoI/6YTAf+yVkv/xczN/8fHx/2kpKT/nJycqwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+PkxNwcHM3dHV4ZouIjqKOjZHTkZGW7piY
nPufn6P/oKCk/5+fov+fn6P/nZ+j/5mfpP+fp6v/oquu/6usr/+8tbb/xra1/8SfnP++eHD/uFRK/682
J/+nHg7/phgH/6UTAv+lFQP/phoJ/6gfDv+qIRD/rCMR/68kEf+wJRL/sSYT/7EeC/+5UEL/x8vM/8nJ
yf6pqan/nJycxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkZGVao+Pk+aTk5f/kpCW/4Cd
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
T//kiXr/5ol5/+iKef/qjHv/7I17/+2OfP/vj33/8JB+//KRf//zkoD/9JOB//WVgv/3kX7/7H1n/9TI
xv/W2dn/ra2t/5mZmdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOfn5zO5vsH+noSE/4wc
Ff+mS0T/pEhB/6JGP/+kRj7/pkA2/5UWCP+VDQD/mw8A/6ISAP+nFAD/qhUA/64VAP+0FwD/uRkA/74a
AP/DGgD/yScM/+B0Yv/plYb/65SF/+yVhf/ulob/8JeH//GZiP/zmYj/9JqJ//abiv/2nIv/952M//ie
jf/5noz/84Jr/9W8uP/Y3N3/t7e3/5mZmeoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO7u
7xe9wMLwqJyd/4ojHP+pUEn/qFFK/6dOR/+sUUj/pDYs/5MOAP+ZDwD/nxEA/6YTAP+pFAD/rBUA/7IW
AP+4GAD/vhoA/8McAP/GGwD/zzAV/+aFdP/tn5H/7p2P//Cej//xn5D/86GR//Whkf/2o5L/96ST//il
lP/5ppX/+qaW//unl//8p5f/+4t0/9q0rP/Y3uD/vr6+/5mZmfSenp4HAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPLy8ge/wMLbs7Gz/4ovKP+qUUv/q1hS/61YT/+wV07/nCQX/5UMAP+cEAD/ohIA/6gU
AP+rFQD/sBYA/7YYAP+7GQD/whsA/8YcAP/KGwD/1jwi/+uVhv/wp5v/8aaY//Onmf/1qJr/9qma//iq
m//5q5z/+ayc//utnv/8rp7//a+f//6woP//sKD//5aA/+SzqP/Y4OH/w8PD/5mZmfucnJwiAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGxsi/vMDC/48+Of+qUEr/sF9a/7NhWf+xVUv/lhQG/5kN
AP+gEQD/pRMA/6kVAP+uFQD/tBcA/7kYAP+/GgD/xBwA/8gdAP/NHQD/3Ewz/++jlv/yr6P/86+i//Wv
ov/3sKP/+LGk//mypP/7s6X//LSm//62pv//tqf//7ao//+4qf//uar//6KN/+Wvo//a4eL/yMjI/5mZ
mf6bm5tJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADNzs+bw8jL/5hNSP+oTkj/tmpi/7lr
Y/+rRDr/lgwA/50QAP+jEgD/pxQA/6sVAP+xFgD/txgA/78aAP/GHQD/zB4A/9MfAP/aIwL/6WVM//e0
p//5ua3/+7mr//y6rP/9u63//b2u//6+rv/+v6///8Gw///CsP//w7H//8Sy///Esv//xrT//7Sc/+iv
nP/b4OL/zc3N/5qamv+bm5tzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADW1th3w8nM/5tT
Tv+oTET/u3Ns/7tsZP+eKBv/mAsA/6ERAP+oFAD/rhUA/7cYAP+/GwD/xx0A/88fAP/XIQD/3iIA/+Qj
AP/sLgn/9oFq//3Btf//wrX//8K1///Etv//xbb//8e3///IuP//ybj//8m5///Luv//zLv//827///O
vP//0L3//8Oq/+yulf/c3t//0dHR/5ubm/+ampqcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADc3N5TxMvN/5dYVP+mR0D/wXx1/7ZbUv+aEgT/oxEA/6oUAP+xFgD/uRkA/8EbAP/HHQD/zR4A/9Qg
AP/aIgD/4CMA/+cjAP/vORb/+ZmF//7Jvv//yL3//8m9///Kvf//zL7//82////Ov///z8D//9DA///R
wf//0sH//9PC///Uw///1cT//8y2//Guk//b2tn/2NnZ/56env+ampq6AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADh4eI4xs3P/5dlYv+lQjn/xoF5/6s9Mf+eDAD/qBQA/6wVAP+0FwD/uxkA/8Ib
AP/JHQD/0B8A/9YhAP/cIwD/5CQA/+sjAP/ySyn//K6f///Pxv//zsP//8/E///QxP//0sX//9PF///U
xv//1cb//9bH///Xx///2Mj//9jJ///Zyv//28z//9XD//Wxlv/b09D/3+Dh/6Ghof+ZmZnTAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADU1NYbyc/R85x8ef+iPTP/wnZt/6AeD/+hDwD/qRQA/68V
AP+3GAD/vhoA/8QcAP/LHgD/0yAA/9ghAP/fIwD/6CQA/+0lAP/2YUP//8K2///VzP//1Mr//9XK///W
yv//18v//9jL///ZzP//2sz//9vN///czv//3c///93Q///f0f//4NP//93O//q5nv/dz8n/4+bn/6mp
qf+ZmZnkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt7e4Jys3Q3qmZmP+cOS//s1BF/5sO
AP+kEgD/qxUA/7EWAP+5GQD/vxsA/8cdAP/OHgD/1SAA/9siAP/jJAD/6yUA//ArBP/6fmX//9LI///a
0f//2dD//9rQ///b0f//3NH//93S///e0v//39L//+DT///h1f//4tb//+PX///k2P//5dn//+LW//3C
qf/lz8b/6Ozu/7Ozs/+YmJjynp6eBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM7QuLq0
tf+SKB7/nhsN/50PAP+mEwD/rBUA/7QXAP+8GQD/wRsA/8kdAP/RHwD/1yEA/90jAP/mJQD/7SQA//Q4
Ev/+oI3//97X///e1///39b//9/X///g1///4df//+LY///j2P//5Nn//+Xa///m2///593//+fe///o
3v//6d///+je///Mtv/mzMH/7fHz/8HBwf+Xl5f6nJycJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAwMHDlcPExf+NIxn/lwkA/6ARAP+nFAD/rhUA/7YXAP+9GgD/wxwA/8sdAP/TIAD/2SIA/98j
AP/oJQD/7iUA//dKJ///uq3//+Pd///i2///49v//+Pb///j2///5dz//+bc///n3P//597//+je///p
4P//6uH//+vi///r4///7OT//+zk///Uwv/lyLz/7/P1/8zMzP+YmJj+nJycSQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAy8vNdsLJyv+KMSj/mQgA/6ERAP+oFAD/rxYA/7gYAP++GgD/xBwA/80e
AP/VIAD/2yIA/+EkAP/pJQD/8CUA//piQ///z8X//+fh///l3///5t///+bf///n4P//6OD//+nh///q
4f//6+L//+vj///s5P//7OT//+3l///s5P//7OT//+rg///Uv//owK7/8fX3/9bW1v+YmJj/m5ubawAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArq6xVcjR0/+NSUH/mQYA/6MSAP+pFAD/sBYA/7kY
AP+/GwD/xhwA/84eAP/WIQD/3CIA/+MkAP/rJQD/8ioC//x+Zf//39j//+rl///p5P//6uT//+rk///q
4///6uH//+nf///m3P//5Nj//+HU///czP//18T//9G8//3JtP/5w6v/9ryk//Gtjv/WppL/7/P1/+Xl
5f+YmJj/np6ejAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0tLUNsXNz/6UZWD/lwUA/6QS
AP+pFAD/sRYA/7oZAP/AGwD/xh0A/9AfAP/WIQD/3SIA/+QkAP/sJAD/9TEK//+TfP//39f//9/W///X
y///0MH//8m4//3DsP/3vqn/9Lqk//S5of/0tp3/9LOY/+mulv/frpr/2LOj/9i+tP/cy8T/4tbR/+bh
3//m5ub/8fHx/+jo6P+mpqb6s7OzTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm7F8HG
yO+dhIL/lAcA/6USAP+qFAD/sxYA/7wZAP/DGgD/yhsA/9UaAP/bGgD/4BoA/+YaAP/rGwD/7CsE/+1s
Uv/qmYf/4pyM/+GgkP/hpZX/2qqd/9Gxp//Rvrn/1MrH/9nSz//c19b/2dfX/9jZ2v/X29z/297f/9zf
4Pvb3d3u2tvc39XW1tnb29vG3Nzcst7e3o3MzMxLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAw8PGBby/wdeomZn/lQcA/6YJAP+oCwD/rw0A/7URAP+1GAD/tSIL/7c1IP+3Sjf/vGBQ/8Z1
aP/Fin//wKCa/8W3tP/LxsX/zs/Q/9HW1//T2Nr/0tfZ/9PX2f/T1db50dPT7NDR0d3Nzs7Xz8/Pwc/P
z63U1NSP0NDQdNLS0k/Ozs8rysrKFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAALCytb2zra7/hTgw/5FKQ/+cZV//roF7/7GSjv+xoaD/tLGy/7vB
w/+/ys3/xdDT/8rU1v/N1db/ztPU983P0OvNzs7dy8vL1MvLy8HKysqmzs7Oj8vLzHnOzs5Oy8vLM8rK
yhrKysoDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2tr7PCw8P/t7/C/73Fx//Dy83/xMrM/cXJ
y/XHycrqxsfI3MbGx83Hx8jAx8fHp8rKyovIyMhzy8vLUsrKyjnKysoaysrKCwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCgo3a5ubvAvLy9wr+/
wK28vL6NwMDBb8LCw1fHx8g8ysrKIMrKyhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADKysoOysrKAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AD//8AAP/8
AAD4fwAA//AAACAPAAD/4AAAAAcAAP/AAAAAAQAA/4AAAAABAAD/gAAAAAEAAP+AAAAAAQAA/4AAAAAB
AAD/wAAAAAEAAP/gAAAAAAAA//AAAAAHAAD/hAAAAH8AAP4BAAAAfwAA/4AAAAB/AAD8AAAAAH8AAMAA
AAAAfwAAgAAAAAB/AACAAAAAAH8AAIAAAAAAPwAAgAAAAAA/AACAAAAAAD8AAIAAAAAAPwAAwAAAAAA/
AADAAAAAAD8AAMAAAAAAPwAAwAAAAAA/AADAAAAAAD8AAMAAAAAAHwAAwAAAAAAfAADgAAAAAB8AAOAA
AAAAHwAA4AAAAAAfAADgAAAAAB8AAOAAAAAAHwAA4AAAAAAfAADgAAAAAA8AAPAAAAAADwAA8AAAAAAP
AADwAAAAAA8AAPAAAAAADwAA8AAAAAAPAADwAAAAAB8AAPAAAAAD/wAA+AAAAf//AAD4AAH///8AAPgB
/////wAA/P//////AAA=
</value>
</data>
</root>

404
KVMViewer.Designer.cs generated Normal file
View File

@@ -0,0 +1,404 @@
using System.Windows.Forms;
namespace MeshCentralRouter
{
public class BlankPanel : System.Windows.Forms.Panel
{
public BlankPanel()
{
}
protected override void OnPaintBackground(PaintEventArgs e)
{
// Do not paint background.
}
}
partial class KVMViewer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(KVMViewer));
this.mainMenu = new System.Windows.Forms.MenuStrip();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.MenuItemConnect = new System.Windows.Forms.ToolStripMenuItem();
this.MenuItemDisconnect = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.MenuItemExit = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.zoomtofitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
this.refreshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pauseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.actionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.sendCtrlAltDelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mainStatusStrip = new System.Windows.Forms.StatusStrip();
this.mainToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.updateTimer = new System.Windows.Forms.Timer(this.components);
this.topPanel = new System.Windows.Forms.Panel();
this.displaySelectComboBox = new System.Windows.Forms.ComboBox();
this.settingsButton = new System.Windows.Forms.Button();
this.zoomButton = new System.Windows.Forms.Button();
this.cadButton = new System.Windows.Forms.Button();
this.connectButton = new System.Windows.Forms.Button();
this.resizeKvmControl = new MeshCentralRouter.KVMResizeControl();
this.mainMenu.SuspendLayout();
this.mainStatusStrip.SuspendLayout();
this.topPanel.SuspendLayout();
this.SuspendLayout();
//
// mainMenu
//
this.mainMenu.BackColor = System.Drawing.SystemColors.Menu;
this.mainMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem2,
this.viewToolStripMenuItem,
this.actionsToolStripMenuItem});
this.mainMenu.Location = new System.Drawing.Point(0, 0);
this.mainMenu.Name = "mainMenu";
this.mainMenu.Size = new System.Drawing.Size(1227, 24);
this.mainMenu.TabIndex = 1;
this.mainMenu.Text = "menuStrip1";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.MenuItemConnect,
this.MenuItemDisconnect,
this.toolStripMenuItem5,
this.settingsToolStripMenuItem,
this.toolStripMenuItem1,
this.MenuItemExit});
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(59, 20);
this.toolStripMenuItem2.Text = "&Control";
this.toolStripMenuItem2.DropDownOpening += new System.EventHandler(this.toolStripMenuItem2_DropDownOpening);
//
// MenuItemConnect
//
this.MenuItemConnect.Name = "MenuItemConnect";
this.MenuItemConnect.Size = new System.Drawing.Size(167, 22);
this.MenuItemConnect.Text = "&Connect...";
this.MenuItemConnect.Click += new System.EventHandler(this.MenuItemConnect_Click);
//
// MenuItemDisconnect
//
this.MenuItemDisconnect.Name = "MenuItemDisconnect";
this.MenuItemDisconnect.Size = new System.Drawing.Size(167, 22);
this.MenuItemDisconnect.Text = "&Disconnect";
this.MenuItemDisconnect.Click += new System.EventHandler(this.MenuItemDisconnect_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(164, 6);
//
// settingsToolStripMenuItem
//
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(167, 22);
this.settingsToolStripMenuItem.Text = "Session Settings...";
this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(164, 6);
//
// MenuItemExit
//
this.MenuItemExit.Name = "MenuItemExit";
this.MenuItemExit.Size = new System.Drawing.Size(167, 22);
this.MenuItemExit.Text = "E&xit";
this.MenuItemExit.Click += new System.EventHandler(this.MenuItemExit_Click);
//
// viewToolStripMenuItem
//
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.zoomtofitToolStripMenuItem,
this.statusToolStripMenuItem,
this.debugToolStripMenuItem,
this.toolStripMenuItem6,
this.refreshToolStripMenuItem,
this.pauseToolStripMenuItem});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.viewToolStripMenuItem.Text = "&View";
this.viewToolStripMenuItem.DropDownOpening += new System.EventHandler(this.viewToolStripMenuItem_DropDownOpening);
//
// zoomtofitToolStripMenuItem
//
this.zoomtofitToolStripMenuItem.CheckOnClick = true;
this.zoomtofitToolStripMenuItem.Name = "zoomtofitToolStripMenuItem";
this.zoomtofitToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.zoomtofitToolStripMenuItem.Text = "&Zoom-to-fit";
this.zoomtofitToolStripMenuItem.CheckStateChanged += new System.EventHandler(this.zoomtofitToolStripMenuItem_CheckStateChanged);
//
// statusToolStripMenuItem
//
this.statusToolStripMenuItem.Checked = true;
this.statusToolStripMenuItem.CheckOnClick = true;
this.statusToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.statusToolStripMenuItem.Name = "statusToolStripMenuItem";
this.statusToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.statusToolStripMenuItem.Text = "&Status";
this.statusToolStripMenuItem.CheckedChanged += new System.EventHandler(this.statusToolStripMenuItem_CheckedChanged);
//
// debugToolStripMenuItem
//
this.debugToolStripMenuItem.CheckOnClick = true;
this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
this.debugToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.debugToolStripMenuItem.Text = "&Debug";
this.debugToolStripMenuItem.Click += new System.EventHandler(this.debugToolStripMenuItem_Click);
//
// toolStripMenuItem6
//
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
this.toolStripMenuItem6.Size = new System.Drawing.Size(135, 6);
//
// refreshToolStripMenuItem
//
this.refreshToolStripMenuItem.Name = "refreshToolStripMenuItem";
this.refreshToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;
this.refreshToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.refreshToolStripMenuItem.Text = "&Refresh";
//
// pauseToolStripMenuItem
//
this.pauseToolStripMenuItem.Name = "pauseToolStripMenuItem";
this.pauseToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F7;
this.pauseToolStripMenuItem.Size = new System.Drawing.Size(138, 22);
this.pauseToolStripMenuItem.Text = "&Pause";
//
// actionsToolStripMenuItem
//
this.actionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.sendCtrlAltDelToolStripMenuItem});
this.actionsToolStripMenuItem.Name = "actionsToolStripMenuItem";
this.actionsToolStripMenuItem.Size = new System.Drawing.Size(59, 20);
this.actionsToolStripMenuItem.Text = "Actions";
//
// sendCtrlAltDelToolStripMenuItem
//
this.sendCtrlAltDelToolStripMenuItem.Name = "sendCtrlAltDelToolStripMenuItem";
this.sendCtrlAltDelToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
this.sendCtrlAltDelToolStripMenuItem.Text = "Send &Ctrl-Alt-Del";
this.sendCtrlAltDelToolStripMenuItem.Click += new System.EventHandler(this.sendCtrlAltDelToolStripMenuItem_Click);
//
// mainStatusStrip
//
this.mainStatusStrip.BackColor = System.Drawing.SystemColors.Menu;
this.mainStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mainToolStripStatusLabel,
this.toolStripStatusLabel1});
this.mainStatusStrip.Location = new System.Drawing.Point(0, 787);
this.mainStatusStrip.Name = "mainStatusStrip";
this.mainStatusStrip.Size = new System.Drawing.Size(1227, 22);
this.mainStatusStrip.TabIndex = 9;
this.mainStatusStrip.Text = "statusStrip1";
//
// mainToolStripStatusLabel
//
this.mainToolStripStatusLabel.Name = "mainToolStripStatusLabel";
this.mainToolStripStatusLabel.Size = new System.Drawing.Size(1212, 17);
this.mainToolStripStatusLabel.Spring = true;
this.mainToolStripStatusLabel.Text = "---";
this.mainToolStripStatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(13, 17);
this.toolStripStatusLabel1.Text = "v";
this.toolStripStatusLabel1.Visible = false;
//
// updateTimer
//
this.updateTimer.Enabled = true;
this.updateTimer.Interval = 1000;
this.updateTimer.Tick += new System.EventHandler(this.updateTimer_Tick);
//
// topPanel
//
this.topPanel.BackColor = System.Drawing.SystemColors.Control;
this.topPanel.Controls.Add(this.displaySelectComboBox);
this.topPanel.Controls.Add(this.settingsButton);
this.topPanel.Controls.Add(this.zoomButton);
this.topPanel.Controls.Add(this.cadButton);
this.topPanel.Controls.Add(this.connectButton);
this.topPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.topPanel.Location = new System.Drawing.Point(0, 24);
this.topPanel.Name = "topPanel";
this.topPanel.Size = new System.Drawing.Size(1227, 32);
this.topPanel.TabIndex = 11;
this.topPanel.Visible = false;
//
// displaySelectComboBox
//
this.displaySelectComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.displaySelectComboBox.Location = new System.Drawing.Point(383, 5);
this.displaySelectComboBox.Name = "displaySelectComboBox";
this.displaySelectComboBox.Size = new System.Drawing.Size(128, 21);
this.displaySelectComboBox.TabIndex = 6;
this.displaySelectComboBox.TabStop = false;
this.displaySelectComboBox.Visible = false;
this.displaySelectComboBox.SelectionChangeCommitted += new System.EventHandler(this.displaySelectComboBox_SelectionChangeCommitted);
//
// settingsButton
//
this.settingsButton.Location = new System.Drawing.Point(288, 3);
this.settingsButton.Name = "settingsButton";
this.settingsButton.Size = new System.Drawing.Size(89, 26);
this.settingsButton.TabIndex = 5;
this.settingsButton.TabStop = false;
this.settingsButton.Text = "Settings";
this.settingsButton.UseVisualStyleBackColor = true;
this.settingsButton.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click);
//
// zoomButton
//
this.zoomButton.Location = new System.Drawing.Point(193, 3);
this.zoomButton.Name = "zoomButton";
this.zoomButton.Size = new System.Drawing.Size(89, 26);
this.zoomButton.TabIndex = 4;
this.zoomButton.TabStop = false;
this.zoomButton.Text = "Zoom-to-Fit";
this.zoomButton.UseVisualStyleBackColor = true;
this.zoomButton.Click += new System.EventHandler(this.zoomButton_Click);
//
// cadButton
//
this.cadButton.Location = new System.Drawing.Point(98, 3);
this.cadButton.Name = "cadButton";
this.cadButton.Size = new System.Drawing.Size(89, 26);
this.cadButton.TabIndex = 1;
this.cadButton.TabStop = false;
this.cadButton.Text = "Ctrl-Alt-Del";
this.cadButton.UseVisualStyleBackColor = true;
this.cadButton.Click += new System.EventHandler(this.sendCtrlAltDelToolStripMenuItem_Click);
//
// connectButton
//
this.connectButton.Location = new System.Drawing.Point(3, 3);
this.connectButton.Name = "connectButton";
this.connectButton.Size = new System.Drawing.Size(89, 26);
this.connectButton.TabIndex = 0;
this.connectButton.TabStop = false;
this.connectButton.Text = "Connect";
this.connectButton.UseVisualStyleBackColor = true;
this.connectButton.Click += new System.EventHandler(this.MenuItemDisconnect_Click);
//
// resizeKvmControl
//
this.resizeKvmControl.BackColor = System.Drawing.Color.Gray;
this.resizeKvmControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.resizeKvmControl.Location = new System.Drawing.Point(0, 56);
this.resizeKvmControl.Name = "resizeKvmControl";
this.resizeKvmControl.Size = new System.Drawing.Size(1227, 731);
this.resizeKvmControl.TabIndex = 10;
this.resizeKvmControl.ZoomToFit = false;
this.resizeKvmControl.StateChanged += new System.EventHandler(this.kvmControl_StateChanged);
this.resizeKvmControl.DisplaysReceived += new System.EventHandler(this.resizeKvmControl_DisplaysReceived);
//
// KVMViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Gray;
this.ClientSize = new System.Drawing.Size(1227, 809);
this.Controls.Add(this.resizeKvmControl);
this.Controls.Add(this.topPanel);
this.Controls.Add(this.mainStatusStrip);
this.Controls.Add(this.mainMenu);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Margin = new System.Windows.Forms.Padding(2);
this.Name = "KVMViewer";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Remote Desktop";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Main_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.Resize += new System.EventHandler(this.MainForm_Resize);
this.mainMenu.ResumeLayout(false);
this.mainMenu.PerformLayout();
this.mainStatusStrip.ResumeLayout(false);
this.mainStatusStrip.PerformLayout();
this.topPanel.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private MenuStrip mainMenu;
private ToolStripMenuItem toolStripMenuItem2;
private ToolStripMenuItem MenuItemConnect;
private ToolStripMenuItem MenuItemExit;
private ToolStripMenuItem MenuItemDisconnect;
private StatusStrip mainStatusStrip;
private ToolStripStatusLabel mainToolStripStatusLabel;
private Timer updateTimer;
private ToolStripSeparator toolStripMenuItem1;
private ToolStripMenuItem viewToolStripMenuItem;
private ToolStripMenuItem statusToolStripMenuItem;
private ToolStripMenuItem debugToolStripMenuItem;
private ToolStripMenuItem settingsToolStripMenuItem;
private ToolStripMenuItem refreshToolStripMenuItem;
private ToolStripMenuItem pauseToolStripMenuItem;
private ToolStripSeparator toolStripMenuItem5;
private KVMResizeControl resizeKvmControl;
private ToolStripStatusLabel toolStripStatusLabel1;
private ToolStripMenuItem zoomtofitToolStripMenuItem;
private ToolStripMenuItem actionsToolStripMenuItem;
private ToolStripMenuItem sendCtrlAltDelToolStripMenuItem;
private Panel topPanel;
private Button connectButton;
private Button cadButton;
private Button zoomButton;
private Button settingsButton;
private ComboBox displaySelectComboBox;
private ToolStripSeparator toolStripMenuItem6;
}
}

813
KVMViewer.cs Normal file
View File

@@ -0,0 +1,813 @@
/*
Copyright 2009-2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Net.Sockets;
using System.Net.Security;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Win32;
namespace MeshCentralRouter
{
public partial class KVMViewer : Form
{
private KVMControl kvmControl = null;
private MeshCentralServer server = null;
private NodeClass node = null;
private int state = 0;
public webSocketClient wc = null;
public KVMViewer(MeshCentralServer server, NodeClass node)
{
InitializeComponent();
this.Text += " - " + node.name;
this.node = node;
this.server = server;
kvmControl = resizeKvmControl.KVM;
kvmControl.parent = this;
resizeKvmControl.ZoomToFit = true;
UpdateStatus();
this.MouseWheel += MainForm_MouseWheel;
}
private void Server_onStateChanged(int state)
{
UpdateStatus();
}
void MainForm_MouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta == 0) return;
Control c = this.GetChildAtPoint(e.Location);
if (c != null && c == resizeKvmControl) resizeKvmControl.MouseWheelEx(sender, e);
}
private void MainForm_Load(object sender, EventArgs e)
{
this.Controls.Remove(mainMenu);
this.Size = new Size(820, 480);
resizeKvmControl.CenterKvmControl(false);
topPanel.Visible = true;
}
public void OnScreenChanged()
{
resizeKvmControl.CenterKvmControl(true);
}
private void MenuItemExit_Click(object sender, EventArgs e)
{
node.desktopViewer = null;
Close();
}
public void MenuItemConnect_Click(object sender, EventArgs e)
{
if (wc != null) return;
state = 1;
string randomId = "abc"; // TODO
Uri u = new Uri(server.wsurl.ToString().Replace("/control.ashx", "/") + "meshrelay.ashx?browser=1&p=2&nodeid=" + node.nodeid + "&id=" + randomId + "&auth=" + server.authCookie);
wc = new webSocketClient();
wc.Start(this, u, server.wshash);
}
public void onWebSocketConnected()
{
string randomId = "abc"; // TODO
string u = "*/meshrelay.ashx?p=2&nodeid=" + node.nodeid + "&id=" + randomId + "&rauth=" + server.rauthCookie;
server.sendCommand("{ \"action\": \"msg\", \"type\": \"tunnel\", \"nodeid\": \"" + node.nodeid + "\", \"value\": \"" + u.ToString() + "\", \"usage\": 2 }");
}
public void processServerData(string data) {
if ((state == 1) && ((data == "c") || (data == "cr"))) {
state = 3;
kvmControl.Send("2");
kvmControl.SendCompressionLevel();
kvmControl.SendPause(false);
kvmControl.SendRefresh();
UpdateStatus();
return;
}
if (state != 3) return;
}
public void processServerBinaryData(byte[] data, int offset, int len)
{
if (state != 3) return;
kvmControl.ProcessData(data, offset, len);
}
private void MenuItemDisconnect_Click(object sender, EventArgs e)
{
if (wc != null)
{
// Disconnect
state = 0;
wc.Dispose();
wc = null;
UpdateStatus();
} else {
// Connect
MenuItemConnect_Click(null, null);
}
}
public delegate void UpdateStatusHandler();
private void UpdateStatus()
{
if (this.InvokeRequired) { this.Invoke(new UpdateStatusHandler(UpdateStatus)); return; }
//if (kvmControl == null) return;
switch (state)
{
case 0: // Disconnected
mainToolStripStatusLabel.Text = "Disconnected";
displaySelectComboBox.Visible = false;
kvmControl.Visible = false;
connectButton.Text = "Connect";
break;
case 1: // Connecting
mainToolStripStatusLabel.Text = "Connecting...";
displaySelectComboBox.Visible = false;
kvmControl.Visible = false;
connectButton.Text = "Disconnect";
break;
case 2: // Setup
mainToolStripStatusLabel.Text = "Setup...";
displaySelectComboBox.Visible = false;
kvmControl.Visible = false;
connectButton.Text = "Disconnect";
break;
case 3: // Connected
//string extras = ".";
//if (kvmControl.touchEnabled) extras = ", touch enabled.";
//mainToolStripStatusLabel.Text = string.Format("Connected. {0} tiles received, {1} tiles copied, {2} received, {3} sent{4}", kvmControl.tilecount, kvmControl.tilecopy, MeshUtils.GetKiloShortString((ulong)kvmControl.byterecv), MeshUtils.GetKiloShortString((ulong)kvmControl.bytesent), extras);
mainToolStripStatusLabel.Text = "Connected.";
kvmControl.Visible = true;
connectButton.Text = "Disconnect";
kvmControl.SendCompressionLevel();
break;
}
}
private void updateTimer_Tick(object sender, EventArgs e)
{
UpdateStatus();
}
private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
node.desktopViewer = null;
//if (kvmControl != null) kvmControl.Disconnect();
//controller.OnNodeStateUpdated -= new MeshControl.NodeUpdateHandler(controller_NodeStateUpdated);
//controller.OnPolicyUpdated -= new MeshControl.PolicyUpdateHandler(controller_OnPolicyUpdated);
}
private void statusToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
mainStatusStrip.Visible = statusToolStripMenuItem.Checked;
}
private void toolStripMenuItem2_DropDownOpening(object sender, EventArgs e)
{
//MenuItemConnect.Enabled = (kvmControl.State == KVMControl.ConnectState.Disconnected);
//MenuItemDisconnect.Enabled = (kvmControl.State != KVMControl.ConnectState.Disconnected);
//serverConnectToolStripMenuItem.Enabled = (server == null && kvmControl.State == KVMControl.ConnectState.Disconnected);
//serviceDisconnectToolStripMenuItem.Enabled = (server != null && server.CurrentState != MeshSwarmServer.State.Disconnected);
}
private void viewToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
debugToolStripMenuItem.Checked = kvmControl.debugmode;
//pauseToolStripMenuItem.Checked = kvmControl.Pause;
}
private void debugToolStripMenuItem_Click(object sender, EventArgs e)
{
if (kvmControl != null) kvmControl.debugmode = debugToolStripMenuItem.Checked;
}
private void kvmControl_StateChanged(object sender, EventArgs e)
{
UpdateStatus();
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (kvmControl == null) return;
using (KVMSettingsForm form = new KVMSettingsForm())
{
form.Compression = kvmControl.CompressionLevel;
form.Scaling = kvmControl.ScalingLevel;
form.FrameRate = kvmControl.FrameRate;
if (form.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) {
kvmControl.SetCompressionParams(form.Compression, form.Scaling, form.FrameRate);
}
}
}
private void MainForm_Resize(object sender, EventArgs e)
{
if (kvmControl != null) kvmControl.SendPause(WindowState == FormWindowState.Minimized);
}
private void zoomtofitToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
{
resizeKvmControl.ZoomToFit = zoomtofitToolStripMenuItem.Checked;
}
private void sendCtrlAltDelToolStripMenuItem_Click(object sender, EventArgs e)
{
if (kvmControl != null) kvmControl.SendCtrlAltDel();
}
private void debugButton_Click(object sender, EventArgs e)
{
if (kvmControl != null) kvmControl.debugmode = !kvmControl.debugmode;
}
private void zoomButton_Click(object sender, EventArgs e)
{
resizeKvmControl.ZoomToFit = !resizeKvmControl.ZoomToFit;
}
private void resizeKvmControl_DisplaysReceived(object sender, EventArgs e)
{
if (kvmControl == null || kvmControl.displays.Count == 0) return;
if (kvmControl.displays.Count > 0)
{
displaySelectComboBox.Visible = true;
displaySelectComboBox.Items.Clear();
displaySelectComboBox.Items.AddRange(kvmControl.displays.ToArray());
if (kvmControl.currentDisp == 0xFFFF)
{
displaySelectComboBox.SelectedItem = "All Displays";
}
else
{
displaySelectComboBox.SelectedItem = "Display " + kvmControl.currentDisp;
}
}
else
{
displaySelectComboBox.Visible = false;
displaySelectComboBox.Items.Clear();
}
}
private void displaySelectComboBox_SelectionChangeCommitted(object sender, EventArgs e)
{
string displayText = displaySelectComboBox.SelectedItem.ToString();
int displaynum = 0;
if (displayText == "All Displays") displaynum = 0xFFFF;
if (displaynum != 0 || int.TryParse(displayText.Substring(8), out displaynum))
{
//if (kvmControl != null) kvmControl.SendDisplay(displaynum);
}
}
private void resizeKvmControl_TouchEnabledChanged(object sender, EventArgs e)
{
UpdateStatus();
}
private void commandsToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
{
//if (server == null) return;
//if (commandsToolStripMenuItem.Checked) server.ShowCommandViewer(); else server.HideCommandViewer();
}
private void emulateTouchToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
{
//kvmControl.emulateTouch = emulateTouchToolStripMenuItem.Checked;
}
private void packetsToolStripMenuItem_CheckStateChanged(object sender, EventArgs e)
{
//kvmControl.ShowPackets(packetsToolStripMenuItem.Checked);
}
private void kVMCommandsToolStripMenuItem_Click(object sender, EventArgs e)
{
//kvmControl.ShowCommands(kVMCommandsToolStripMenuItem.Checked);
}
private void winButton_Click(object sender, EventArgs e)
{
kvmControl.SendWindowsKey();
}
private void charmButton_Click(object sender, EventArgs e)
{
//kvmControl.SendCharmsKey();
}
public static void saveToRegistry(string name, string value)
{
try { Registry.SetValue(@"HKEY_CURRENT_USER\SOFTWARE\OpenSource\MeshRouter", name, value); } catch (Exception) { }
}
public static string loadFromRegistry(string name)
{
try { return Registry.GetValue(@"HKEY_CURRENT_USER\SOFTWARE\OpenSource\MeshRouter", name, "").ToString(); } catch (Exception) { return ""; }
}
public static string GetProxyForUrlUsingPac(string DestinationUrl, string PacUri)
{
IntPtr WinHttpSession = Win32Api.WinHttpOpen("User", Win32Api.WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, IntPtr.Zero, IntPtr.Zero, 0);
Win32Api.WINHTTP_AUTOPROXY_OPTIONS ProxyOptions = new Win32Api.WINHTTP_AUTOPROXY_OPTIONS();
Win32Api.WINHTTP_PROXY_INFO ProxyInfo = new Win32Api.WINHTTP_PROXY_INFO();
ProxyOptions.dwFlags = Win32Api.WINHTTP_AUTOPROXY_CONFIG_URL;
ProxyOptions.dwAutoDetectFlags = (Win32Api.WINHTTP_AUTO_DETECT_TYPE_DHCP | Win32Api.WINHTTP_AUTO_DETECT_TYPE_DNS_A);
ProxyOptions.lpszAutoConfigUrl = PacUri;
// Get Proxy
bool IsSuccess = Win32Api.WinHttpGetProxyForUrl(WinHttpSession, DestinationUrl, ref ProxyOptions, ref ProxyInfo);
Win32Api.WinHttpCloseHandle(WinHttpSession);
if (IsSuccess)
{
return ProxyInfo.lpszProxy;
}
else
{
Console.WriteLine("Error: {0}", Win32Api.GetLastError());
return null;
}
}
public class webSocketClient : IDisposable
{
private KVMViewer parent = null;
private TcpClient wsclient = null;
private SslStream wsstream = null;
private NetworkStream wsrawstream = null;
private int state = 0;
private Uri url = null;
private byte[] readBuffer = new Byte[500];
private int readBufferLen = 0;
private int accopcodes = 0;
private bool accmask = false;
private int acclen = 0;
private bool proxyInUse = false;
private string user = null;
private string pass = null;
private string token = null;
public bool xdebug = false;
public bool xignoreCert = false;
public void Dispose()
{
try { wsstream.Close(); } catch (Exception) { }
try { wsstream.Dispose(); } catch (Exception) { }
wsstream = null;
wsclient = null;
state = -1;
}
public void Debug(string msg) { if (xdebug) { try { File.AppendAllText("debug.log", "Debug-" + msg + "\r\n"); } catch (Exception) { } } }
public bool Start(KVMViewer parent, Uri url, string fingerprint)
{
if (state != 0) return false;
state = 1;
this.url = url;
this.parent = parent;
Uri proxyUri = null;
// Check if we need to use a HTTP proxy (Auto-proxy way)
try
{
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true);
Object x = registryKey.GetValue("AutoConfigURL", null);
if ((x != null) && (x.GetType() == typeof(string)))
{
string proxyStr = GetProxyForUrlUsingPac("http" + ((url.Port == 80) ? "" : "s") + "://" + url.Host + ":" + url.Port, x.ToString());
if (proxyStr != null) { proxyUri = new Uri("http://" + proxyStr); }
}
}
catch (Exception) { proxyUri = null; }
// Check if we need to use a HTTP proxy (Normal way)
if (proxyUri == null)
{
var proxy = System.Net.HttpWebRequest.GetSystemWebProxy();
proxyUri = proxy.GetProxy(url);
if ((url.Host.ToLower() == proxyUri.Host.ToLower()) && (url.Port == proxyUri.Port)) { proxyUri = null; }
}
if (proxyUri != null)
{
// Proxy in use
proxyInUse = true;
wsclient = new TcpClient();
wsclient.BeginConnect(proxyUri.Host, proxyUri.Port, new AsyncCallback(OnConnectSink), this);
}
else
{
// No proxy in use
proxyInUse = false;
wsclient = new TcpClient();
wsclient.BeginConnect(url.Host, url.Port, new AsyncCallback(OnConnectSink), this);
}
return true;
}
private void OnConnectSink(IAsyncResult ar)
{
if (wsclient == null) return;
// Accept the connection
try
{
wsclient.EndConnect(ar);
}
catch (Exception ex)
{
Debug("Websocket TCP failed to connect: " + ex.ToString());
Dispose();
return;
}
if (proxyInUse == true)
{
// Send proxy connection request
wsrawstream = wsclient.GetStream();
byte[] proxyRequestBuf = UTF8Encoding.UTF8.GetBytes("CONNECT " + url.Host + ":" + url.Port + " HTTP/1.1\r\nHost: " + url.Host + ":" + url.Port + "\r\n\r\n");
wsrawstream.Write(proxyRequestBuf, 0, proxyRequestBuf.Length);
wsrawstream.BeginRead(readBuffer, readBufferLen, readBuffer.Length - readBufferLen, new AsyncCallback(OnProxyResponseSink), this);
}
else
{
// Start TLS connection
Debug("Websocket TCP connected, doing TLS...");
wsstream = new SslStream(wsclient.GetStream(), false, VerifyServerCertificate, null);
wsstream.BeginAuthenticateAsClient(url.Host, null, System.Security.Authentication.SslProtocols.Tls12, false, new AsyncCallback(OnTlsSetupSink), this);
}
}
private void OnProxyResponseSink(IAsyncResult ar)
{
if (wsrawstream == null) return;
int len = 0;
try { len = wsrawstream.EndRead(ar); } catch (Exception) { }
if (len == 0)
{
// Disconnect
Debug("Websocket proxy disconnected, length = 0.");
Dispose();
return;
}
readBufferLen += len;
string proxyResponse = UTF8Encoding.UTF8.GetString(readBuffer, 0, readBufferLen);
if (proxyResponse.IndexOf("\r\n\r\n") >= 0)
{
// We get a full proxy response, we should get something like "HTTP/1.1 200 Connection established\r\n\r\n"
if (proxyResponse.StartsWith("HTTP/1.1 200 "))
{
// All good, start TLS setup.
readBufferLen = 0;
Debug("Websocket TCP connected, doing TLS...");
wsstream = new SslStream(wsrawstream, false, VerifyServerCertificate, null);
wsstream.BeginAuthenticateAsClient(url.Host, null, System.Security.Authentication.SslProtocols.Tls12, false, new AsyncCallback(OnTlsSetupSink), this);
}
else
{
// Invalid response
Debug("Proxy connection failed: " + proxyResponse);
Dispose();
}
}
else
{
if (readBufferLen == readBuffer.Length)
{
// Buffer overflow
Debug("Proxy connection failed");
Dispose();
}
else
{
// Read more proxy data
wsrawstream.BeginRead(readBuffer, readBufferLen, readBuffer.Length - readBufferLen, new AsyncCallback(OnProxyResponseSink), this);
}
}
}
public string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
private void OnTlsSetupSink(IAsyncResult ar)
{
if (wsstream == null) return;
// Accept the connection
try
{
wsstream.EndAuthenticateAsClient(ar);
}
catch (Exception ex)
{
// Disconnect
MessageBox.Show(ex.Message, "MeshRouter");
Debug("Websocket TLS failed: " + ex.ToString());
Dispose();
return;
}
// Fetch remote certificate
//parent.wshash = wsstream.RemoteCertificate.GetCertHashString();
// Setup extra headers if needed
string extraHeaders = "";
if (user != null && pass != null && token != null) { extraHeaders = "x-meshauth: " + Base64Encode(user) + "," + Base64Encode(pass) + "," + Base64Encode(token) + "\r\n"; }
else if (user != null && pass != null) { extraHeaders = "x-meshauth: " + Base64Encode(user) + "," + Base64Encode(pass) + "\r\n"; }
// Send the HTTP headers
Debug("Websocket TLS setup, sending HTTP header...");
string header = "GET " + url.PathAndQuery + " HTTP/1.1\r\nHost: " + url.Host + "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n" + extraHeaders + "\r\n";
wsstream.Write(UTF8Encoding.UTF8.GetBytes(header));
// Start receiving data
wsstream.BeginRead(readBuffer, readBufferLen, readBuffer.Length - readBufferLen, new AsyncCallback(OnTlsDataSink), this);
}
private void OnTlsDataSink(IAsyncResult ar)
{
if (wsstream == null) return;
int len = 0;
try { len = wsstream.EndRead(ar); } catch (Exception) { }
if (len == 0)
{
// Disconnect
Debug("Websocket disconnected, length = 0.");
Dispose();
return;
}
//parent.Debug("#" + counter + ": Websocket got new data: " + len);
readBufferLen += len;
// Consume all of the data
int consumed = 0;
int ptr = 0;
do
{
consumed = ProcessBuffer(readBuffer, ptr, readBufferLen - ptr);
if (consumed < 0) { Dispose(); return; } // Error, close the connection
ptr += consumed;
} while ((consumed > 0) && ((readBufferLen - consumed) > 0));
// Move the data forward
if ((ptr > 0) && (readBufferLen - ptr) > 0)
{
//Console.Write("MOVE FORWARD\r\n");
Array.Copy(readBuffer, ptr, readBuffer, 0, (readBufferLen - ptr));
}
readBufferLen = (readBufferLen - ptr);
// If the buffer is too small, double the size here.
if (readBuffer.Length - readBufferLen == 0)
{
Debug("Increasing the read buffer size from " + readBuffer.Length + " to " + (readBuffer.Length * 2) + ".");
byte[] readBuffer2 = new byte[readBuffer.Length * 2];
Array.Copy(readBuffer, 0, readBuffer2, 0, readBuffer.Length);
readBuffer = readBuffer2;
}
// Receive more data
try { wsstream.BeginRead(readBuffer, readBufferLen, readBuffer.Length - readBufferLen, new AsyncCallback(OnTlsDataSink), this); } catch (Exception) { }
}
private int ProcessBuffer(byte[] buffer, int offset, int len)
{
string ss = UTF8Encoding.UTF8.GetString(buffer, offset, len);
if (state == 1)
{
// Look for the end of the http header
string header = UTF8Encoding.UTF8.GetString(buffer, offset, len);
int i = header.IndexOf("\r\n\r\n");
if (i == -1) return 0;
Dictionary<string, string> parsedHeader = ParseHttpHeader(header.Substring(0, i));
if ((parsedHeader == null) || (parsedHeader["_Path"] != "101")) { Debug("Websocket bad header."); return -1; } // Bad header, close the connection
Debug("Websocket got setup upgrade header.");
state = 2;
this.parent.onWebSocketConnected();
return len; // TODO: Technically we need to return the header length before UTF8 convert.
}
else if (state == 2)
{
// Parse a websocket fragment header
if (len < 2) return 0;
int headsize = 2;
accopcodes = buffer[offset];
accmask = ((buffer[offset + 1] & 0x80) != 0);
acclen = (buffer[offset + 1] & 0x7F);
if ((accopcodes & 0x0F) == 8)
{
// Close the websocket
Debug("Websocket got closed fragment.");
return -1;
}
if (acclen == 126)
{
if (len < 4) return 0;
headsize = 4;
acclen = (buffer[offset + 2] << 8) + (buffer[offset + 3]);
}
else if (acclen == 127)
{
if (len < 10) return 0;
headsize = 10;
acclen = (buffer[offset + 6] << 24) + (buffer[offset + 7] << 16) + (buffer[offset + 8] << 8) + (buffer[offset + 9]);
Debug("Websocket receive large fragment: " + acclen);
}
if (accmask == true)
{
// TODO: Do unmasking here.
headsize += 4;
}
//parent.Debug("#" + counter + ": Websocket frag header - FIN: " + ((accopcodes & 0x80) != 0) + ", OP: " + (accopcodes & 0x0F) + ", LEN: " + acclen + ", MASK: " + accmask);
state = 3;
return headsize;
}
else if (state == 3)
{
// Parse a websocket fragment data
if (len < acclen) return 0;
//Console.Write("WSREAD: " + acclen + "\r\n");
ProcessWsBuffer(buffer, offset, acclen, accopcodes);
state = 2;
return acclen;
}
return 0;
}
private void ProcessWsBuffer(byte[] data, int offset, int len, int op)
{
bool binary = ((op & 1) == 0);
Debug("Websocket got data.");
//try { parent.processServerData(UTF8Encoding.UTF8.GetString(data, offset, len)); } catch (Exception ex) { }
if (binary == false) {
parent.processServerData(UTF8Encoding.UTF8.GetString(data, offset, len));
} else {
parent.processServerBinaryData(data, offset, len);
}
}
private Dictionary<string, string> ParseHttpHeader(string header)
{
string[] lines = header.Replace("\r\n", "\r").Split('\r');
if (lines.Length < 2) { return null; }
string[] directive = lines[0].Split(' ');
Dictionary<string, string> values = new Dictionary<string, string>();
values["_Action"] = directive[0];
values["_Path"] = directive[1];
values["_Protocol"] = directive[2];
for (int i = 1; i < lines.Length; i++)
{
var j = lines[i].IndexOf(":");
values[lines[i].Substring(0, j).ToLower()] = lines[i].Substring(j + 1).Trim();
}
return values;
}
// Return a modified base64 SHA384 hash string of the certificate public key
public static string GetMeshKeyHash(X509Certificate cert)
{
return ByteArrayToHexString(new SHA384Managed().ComputeHash(cert.GetPublicKey()));
}
// Return a modified base64 SHA384 hash string of the certificate
public static string GetMeshCertHash(X509Certificate cert)
{
return ByteArrayToHexString(new SHA384Managed().ComputeHash(cert.GetRawCertData()));
}
public static string ByteArrayToHexString(byte[] Bytes)
{
StringBuilder Result = new StringBuilder(Bytes.Length * 2);
string HexAlphabet = "0123456789ABCDEF";
foreach (byte B in Bytes) { Result.Append(HexAlphabet[(int)(B >> 4)]); Result.Append(HexAlphabet[(int)(B & 0xF)]); }
return Result.ToString();
}
private bool VerifyServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return (parent.server.certHash == GetMeshKeyHash(certificate));
}
public void WriteStringWebSocket(string data)
{
if (state < 2) return;
// Convert the string into a buffer with 4 byte of header space.
int len = UTF8Encoding.UTF8.GetByteCount(data);
byte[] buf = new byte[4 + len];
UTF8Encoding.UTF8.GetBytes(data, 0, data.Length, buf, 4);
len = buf.Length - 4;
// Check that everything is ok
if ((state < 2) || (len < 1) || (len > 65535)) { Dispose(); return; }
//Console.Write("Length: " + len + "\r\n");
//System.Threading.Thread.Sleep(0);
if (len < 126)
{
// Small fragment
buf[2] = 129; // Fragment op code (129 = text, 130 = binary)
buf[3] = (byte)(len & 0x7F);
//try { wsstream.BeginWrite(buf, 2, len + 2, new AsyncCallback(WriteWebSocketAsyncDone), args); } catch (Exception) { Dispose(); return; }
wsstream.Write(buf, 2, len + 2);
}
else
{
// Large fragment
buf[0] = 129; // Fragment op code (129 = text, 130 = binary)
buf[1] = 126;
buf[2] = (byte)((len >> 8) & 0xFF);
buf[3] = (byte)(len & 0xFF);
//try { wsstream.BeginWrite(buf, 0, len + 4, new AsyncCallback(WriteWebSocketAsyncDone), args); } catch (Exception) { Dispose(); return; }
wsstream.Write(buf, 0, len + 4);
}
}
public void WriteBinaryWebSocket(byte[] data, int offset, int len)
{
if (state < 2) return;
// Convert the string into a buffer with 4 byte of header space.
byte[] buf = new byte[4 + len];
Array.Copy(data, offset, buf, 4, len);
len = buf.Length - 4;
// Check that everything is ok
if ((state < 2) || (len < 1) || (len > 65535)) { Dispose(); return; }
//Console.Write("Length: " + len + "\r\n");
//System.Threading.Thread.Sleep(0);
if (len < 126)
{
// Small fragment
buf[2] = 130; // Fragment op code (129 = text, 130 = binary)
buf[3] = (byte)(len & 0x7F);
//try { wsstream.BeginWrite(buf, 2, len + 2, new AsyncCallback(WriteWebSocketAsyncDone), args); } catch (Exception) { Dispose(); return; }
wsstream.Write(buf, 2, len + 2);
}
else
{
// Large fragment
buf[0] = 130; // Fragment op code (129 = text, 130 = binary)
buf[1] = 126;
buf[2] = (byte)((len >> 8) & 0xFF);
buf[3] = (byte)(len & 0xFF);
//try { wsstream.BeginWrite(buf, 0, len + 4, new AsyncCallback(WriteWebSocketAsyncDone), args); } catch (Exception) { Dispose(); return; }
wsstream.Write(buf, 0, len + 4);
}
}
}
}
}

555
KVMViewer.resx Normal file
View File

@@ -0,0 +1,555 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="mainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="mainStatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>127, 17</value>
</metadata>
<metadata name="updateTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>264, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAkAEBAQAAEABAAoAQAAlgAAABAQAAABAAgAaAUAAL4BAAAgIBAAAQAEAOgCAAAmBwAAICAAAAEA
CACoCAAADgoAADAwEAABAAQAaAYAALYSAAAwMAAAAQAIAKgOAAAeGQAAEBAAAAEAIABoBAAAxicAACAg
AAABACAAqBAAAC4sAAAwMAAAAQAgAKglAADWPAAAKAAAABAAAAAgAAAAAQAEAAAAAACAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8A
AAD/AP8A//8AAP///wAACIiHh4eAAAAPiIh4eAAAAAAIh3eAAACIiIiIiIh4eI+IiIiIiIiIiEREREZE
Z4iIRGRMfIyMiIhlxMTIeMeIiFZEbHjIjoiIbExMiIiHiIhWxsyIiIiIiExMx4iIiIiITGzIj4+IiIhM
TM6I6OiIiHiIiIeIiIgI+IiIiIiIiOAHAADgDwAA+B8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAoAAAAEAAAACAAAAABAAgAAAAAAAABAAAAAAAAAAAAAAAB
AAAAAQAAAAAAAIAAAACGCwkAlAAAAJQNAgCfEQAAnBsQAJgdEQCiDgAAqQ0AAKgSAACqFQAApxkNAKUc
DwCyEgAAsRUAALQXAAC/FgIAuBgAAL0YAACaJhwArCcVAKMnHQC7Mh8AmDAoAJ42LACqMCMApTctAKU+
MwDAGwAAwRwAAMUdAADKGgAAyh4FANIbAADdGQAA4RoAAOcaAADRIQAA1SMAAPEnCQDkMxMAvkwqALpI
OADMSjYA81A1AKVIQACtSkEAr1ZMAM5dTADUXUgA1GZKANhgSwDdYUwA3WpXAON5ZgDgfWsA6HxoAPp9
aADmgWgA7IBrAPiKawDqi3oA8JtyAPahdwD6qH8AiYuLAIyOjgCXmpoAmp2dAJ6fnwCeoaEAoKGhAKOj
pACipKQApKamAKaoqQCoqqoAqaytAKyurwCvsbEAsbS1ALO3uAC1uLkAtru8ALm+vgDvk4IA7ZuNAPOX
hQDzn4oA9ZyLAPuuiQD3qpsA+q6eAPu0kQD0saYA+7KjAPi1oAD+sqQA+7+iAP7DswD6xrQA/8a2AP7G
ugD/yboA+s2+ALzBwQC+xMQAvsvNAL/MzQDFyMkAwczNAMnMzADDztAAxM7QAMbQ0QDJ0dIAytLUAMzT
1QDN1NUA1NbXANjY2ADc3NwA/9LGAP/UxgD/1cgA/9rLAP/i2QD/5twA/+nfAN7h4QDo6OgA/+rgAP/r
5gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AAAAAFVVUk1GRkZGRkYAAAAAAACDeXduU0tGTUYAAAAAAAAAAAB5T0RDQ24AAAAAAIJr
a1VVU1JPT09NTEtLRm53d3J0cnNuc3JucW1tbW1Ld08BAQIBAQMVFRUVFSttS3dNBxQHBAUKFzEyNDUq
bUt3TRgYBwoKDyw4Nzk8NG1Ld0wuHAcPDxE2V1ZYWjtuTXdLMBsIDxIhPl9cXWJZc013Sy8WDxIiKWJn
ZGRoX21Pd0saCR0nJC17fXt+fmVtT3dGDRAdJyU6hX9/hIRoc093SwwRISMoPWNeW0FAP3NSd0ZGRktL
S01PT09SUlNzUgB3d3d3d3d3d3d3c3dzcnjgBwAA4A8AAPgfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAKAAAACAAAABAAAAAAQAEAAAAAAAAAgAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8A
AAD/AP8A//8AAP///wAAAAAAAAAAj4AAAAAAAAAAAAAAAAAIj4iIiAAAAAAAAAAAAAAIj4+Pj4iIAAAA
AAAAAAAAiIj4+I+IiIcAAAAAAAAACIiIj4iIiIh4cAAAAAAAAAiIiPiPiIiHeAAAAAAAAAAIiIiIiIiH
d4cAAAAAAAAAAAiIiId3d3eIiIAAAAAAAAAAh3d3d3eIiIiAAAAAAAAAAACHd3iIiIiIgAAAAAAAAIeH
iIiIh8fEeHAAAAAId4iIiId3xExETH+AAAAAeIiId3RExExsbGx4gAAAD3d3RERERExnx8fHz3AAAACE
RERETExEx8fIx8+IAAAAhERkTERGxnyMjI54iAAAAIR8VkRGxEyMjnjIyIgAAACHRkxExEzGh3fIjIiI
AAAAh0d8RkxsTIeIh4joiAAAAIfHx0xExMiHd46HiIgAAACIR3xExsbHiI6IiHiHAAAAiEjERMTMyI6I
iIiIiAAAAAhHxMbGzGiIiIiIiIiAAAAIbEZMzGzPiIiIiIiIgAAACFZMTGzMj4+Pj4+IiIAAAAhsTGxM
bIj4+Pj/+PiAAAAIVETEzMz/+P+Pj4iIgAAACHTGzGzOiIiIiIiIj3AAAAiETEzGx4iIiIiI+PgAAAAI
hHd3iIiIj4//AAAAAAAACIiIj4+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/8f///4A///4AD//8A
AP/+AAB//gAA//4AAP//gAAf/8AAH//wAB//AAAf4AAAH8AAAB+AAAAfwAAAD8AAAA/AAAAPwAAAD8AA
AA/AAAAPwAAAD8AAAA/gAAAH4AAAB+AAAAfgAAAH4AAAB+AAAAfgAAAP4AAD/+AH////////KAAAACAA
AABAAAAAAQAIAAAAAAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAB+AQAAZmdmAGlpagB2dnYAfX1+AIIA
AACMAgAAhQsCAIwMAQCSAAAAmAcAAJMLAQCbDgAAkwwIAIsUCgCUEgUAnRAAAJIYDACLHBQAkB4WAJoe
EgCmAAAAqgYAAKELAAC5CAAApBIAAKsUAACqGAYArBwJALIVAAC5EwAAsxgBALsZAACNJBwAkyQcAKYg
DwC2IA0AoCATAKwjEQCgJxoAsy0bALcxHgCSJiAAliskAJYvKACfMCUAmjIqAI85NACZNjAAmz01AJc+
OAC0MiEAvDUhAL0/LQDFEwAAwhsAAMsdAADQHAAA2BwAAO8UAADkGwAA6x0AANMgAADbIgAA2iQMAMAs
FQDlIQAA5S4LAPIqAwDhLhgA9j8dAMs8JQDOPygAmUQ8AKhANgCgQTkAr0U6AMNCLwDDRTIAyUYyAMxI
MwDBTD8AzVI/ANZROQDaVj8A8UQiAP5UMgCZU00Al1RRAKRKRACuVUwAsVJHALBUSgCiWlUArFhRALFc
VQCzZF0AmmtqALFvZgC5a2QAr3FtALdwawC+dWsAoHVyALZ4cQDHU0IAzF1MANFWQQDVWUQA2FpFANVe
SAD1X0IAxGlaANVlUgDcZlIA3WhUANhuXQDiY0kA4mZQAOJqVADpcFoAxnRoAN10YgDjd2QA5nllAOp8
ZgDyfGYA6IBtAPqFbgDjhHQA6YZ0AOyIdgDuingA8Y16APqNeQCDhIQAi4yOAIuOkgCOlZoAlZWVAJSV
mACWm5wAnZ2dAKGFhQCzhIEAp5KSAKCfnwCqnZ4AspOTAL2VkwC5nJsAuaGcAJeepACVoaYAnKCmAJit
qgCfrrEAoqKiAKukpwCmpqgApqmrAKurqwCyp6kAsKqsAKyssAClsLMArbKzAKS6tgCttbkAs7O0ALW5
vAC6ursA0ZWSAO2WhgDrmIoA8piHAPWbigD7nowAy6KcAOKqnADtrJ0A8qOVAPikkwDwqZ0A/KubAPG1
ngD/sJ0A9bieAMCtrADbtKoAwre0AMq1sQDFuLYAwbu9ANG1sADbuLMA4K6jAOu8pwDgtKgA57+tAPWw
ogD7tKUA+b+mAPS3qwD+vK0A/r+xANXCvgD1wKoA+8euAOjGuAD+xLIA/sm1AP7EuQD9y7sAvb/DAMG/
wQC3wcQAvMLDALnGyAC+y8wAw8PDAMTFyADDyswAy8vLANXKxgDSzcsA2M/LAMLP0ADMz9AAx9XWAMzT
1ADK1tgA09PTANLW2ADU2twA29zcAOzPwgD/zsEA/9LDAP/VyQD/2coA5NvXAOvc1gDs3tgA/93SAP/h
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
AADwAAAAAB8AAPAAAAAAHwAA8AAAAAAfAADwAAAAAB8AAPAAAAAAHwAA8AAAAAAfAADwAAAAAB8AAPgA
AAAAHwAA+AAAAAAPAAD4AAAAAB8AAPgAAAAAPwAA+AAAAD//AAD4AAA///8AAPgAP////wAA/D//////
AAD///////8AACgAAAAwAAAAYAAAAAEACAAAAAAAAAkAAAAAAAAAAAAAAAEAAAABAAAAAAAAX19fAGVl
ZQBrbGsAdHR1AHp6egCDAQAAhAoBAIsMAACUBgAAmQYAAJMNAACaDQAAhxEIAIoUCwCOGAwAlBIEAJwQ
AQCTFgkAnhsNAIwaEgCnDAAAtAYAAKMSAACqFAAAphgGAKMbCwCqHgwAshUAALYYAAC7GQAAsR4LAIsj
GgCVJRsAtSILALkgCwCnJBUAqyQSAK4oFwCxJRIAsCoXALsrFwCzLBoAuS4aALIwHwC6MBwAii8oAJUq
IwCJMCkAmTAnAJkzKwCcOS8Aijs0AJw8NACvNicApTYrALUzIAC8NSIAtzopALo7KQClPDIAwxsAAMsd
AADTHQAA5RoAAMYjCADYIQAAzzAVAOckAADwKAIA9TEKAO85FgD0OBIAwTciAMI5JADBPisAyT4oANY8
IgClQzsAvUQ0ALdKNwDFQS0AykQvANBDLADCRjQAykUwAMRINgDKSjYAwko6AM5NOADXTjYA0VA8APRK
KACNSUEAk0pFAJtTTgCXWFQApktEAKpRSgCzUEUAuVBCALFWTAC4VEoArVdQAKtYUgCmXVgAtF1TALBf
WgCbY14At2BUAJVlYQCcfHkAomZhALhrYwC7c2wAoHRzAL54cAC2f3sAylVDANVaRgDiWkIA12JOANlo
VQDpZUwA+GFDAORrVQDncl0AxHVqAM56bgDRcGIA3XRiAN57awDBfHUA5XpnAPt+ZQCugXsA3oFvAMWF
fADYinwA5oBuAPOBawDqiHYA9Yp1APaRfQCCgoMAioqMAJ2EgwCIkI4AgJ2MAIyNkQCOkZUAjJOYAJKS
lACWlpkAmpqbAKSKigC0iIUAs42LALGSjgCmmJgAh6SYAJ2eogCaoaYAnaWpAJ+trACjo6MApKaqAKim
qACjqawAq6urALWpqQCurrAArLK1AK+4uwC0tLQAurO0ALW2uAC8t7gAtby/ALu7uwDOkIUAyZaPAMSf
nADan5QA6peHAPWZhwDtn5EA8Z+QAMWhmgDaqpgA+qWNAOeolQD3qJgA97SaAMGlpADDrKsAyK2qAMqx
rgDRsacA2LOjANSyrgDatKwAw7W0AMa4twDHvLwAyb28ANu7tADUvbgA5a+jAPOvogDks6gA+7enAOjA
rgD8wqoA5ci8AP7HtwD/0b0Atr7BALi+wQC7wsMAv8rNAMLCwgDJxsUAxMXIAMPKzADLy8sA1MfGANTJ
xgDaysUA3c/JANnSzwDOz9AAxdDTAMzT1ADO19gA09PTANrV1ADR19gA1dnaANrb2wDlzcMA/87DAP/W
xwDi1tEA/93TAObh3wD/5NoA3N7gANvg4QDj4+MA6errAP/q4gDu8vQA8fP0AAAAAAD///8AAAAAAAAA
AAAAAAAAAAAAAAAAAAAA6+vr4d0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOHh
4ev5+ff37Ovr4bOurgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADd6+v39/fs9+vr4ef37OHd
s7OuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs+Hh4efr6/f37Ozr4ev397Ozs+GurqUAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAACz4d3d4efr7Oz39+7n4ev357Hd57OpqbOYAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAN2zs93d4eHr7vfs7+zr3uv33d3es6urqaWpAAAAAAAAAAAAAAAAAAAAAAAAAAAAALOzs93d3eHh
6/f39+7h4eHe3d2wrqulmpipmAAAAAAAAAAAAAAAAAAAAAAAAAAAAK6zs7Pd3d3h5+fs6+fh3d3d3bCr
qaWYmJqpmAAAAAAAAAAAAAAAAAAAAAAAAAAAAN2urrOz3d3d3uHn4d7e3d2zq6mlmJiYmpqpAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAACus66zs7Pd3d3e3t2zsKmnmpEFBZGYmqWaAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAqbOurq6urq6rq6eamJEFAwECBZOfqbGrseGzpQAAAAAAAAAAAAAAAAAAAAAAAAAAAAClrqWl
mpqamJAFBAMDBJGapauxsLPd3bPdmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJqapaWRBZCQkZWaqamp
q6uws9vc4d2zpQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsZmRlZiYmJmhpams2d7p6+TOz9/dpQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAArqmhmJWVkZWVlaOt4eHjyL2BUT0catzeoeEAAAAAAAAAAAAAAAAA
AAAAALOupqGamZWVlZeiqamuzcS1gFgjHBgXGRkXZeHepbMAAAAAAAAAAAAAAACupZmaoaWhoaGho6Sr
scu2dGY2GxsXFxsbJSUnJSciZOHhqawAAAAAAAAAAACamZaUk5WapqzZ2rHLwnVoNxAJCQsLEyQlJiYm
JyoqLS0pUN7hpKkAAAAAAAAAAACVlZago6ywscOcaTMOBgYICAsLCxEXJTYsODg5OTlKSkpKS8vnrKUA
AAAAAAAAAACWparDnnA1DgYGBgYHCAgICwsRERcZKjo7OztLS0tVVVVVTMXnsaUAAAAAAAAAAACimxQG
BgcHBwcHBwcHCAsLCxERFxcbO1BUVFdXV1tXW1tbU7zn3aIAAAAAAAAAAACunwYNFA4ODg0HBwcICwsL
EBcXGBgnVHZ2W1t3d3d3d3h5WrTq3qUAAAAAAAAAAADdphQUICAUFBQODggLCAwQFxcYGBgrW3l5eXl5
enl9fX19eIrq56EAAAAAAAAAAADrrDAULy8gIBQUDwgMDBAXFxgYGBxKeYF5eoF9fX59fn5+fYru56UA
AAAAAAAAAAD32V4UMy8vLy8hDwsMDBAYGBgcHB5UgX2BgoWFg4OFhYuLfovn66XdAAAAAAAAAAAA2WwO
NTMzMTEvEAsMEBgYGBgcHh5bg4iIiIuLi4yNjouOjIXr66euAAAAAAAAAAAA2nMUTjU1NTwkCBEQGBgY
GB4eHkF5jY2NjY2Pj7iPj4+5j4zj7qmpAAAAAAAAAAAA2pIUYWFhNU4SCxEXFxgYHh4ePUGFuLi4ubq4
ubm5ub65vozP97ClAAAAAAAAAAAA3Z8gYmFhZjcLEREYGBgdHR49PkOLurq6uru7u8C7wMDAwI7J97Oa
AAAAAAAAAAAA4a4wYmtoaCERERcXGB0dHj09Pk24wMDAwMDAwMDTwNPA04/S+N2aAAAAAAAAAAAA69o0
aGtrZgwLFxcYGB0dHj0+Plq70dHR0dPT09PT09PT077R+OGZAAAAAAAAAAAA+eFeYXFxTgsQFxgYHR09
PT5CQnvT09PT09PT09fT19fX18HQ7+eaAAAAAAAAAAAAAOFfYXJxJBEXGBgeHj1CQkJERozX19fX1/Hx
8dfx1/HX2NW/7+ua3QAAAAAAAAAAAOFgYYRqEBcYHB49PkE/QkRER7nX19fX8fHx8fHY2NjY2NjB7O+h
rgAAAAAAAAAAAOhuNYk8FxUYHB49Pj9CQkREXMDy8fHx8djY2Njy8vLy9NjB5velqQAAAAAAAAAAAOdv
PH8aFxgcHh49PkJCQkREfNfy8fTy8vT09PL09PT09PTB5fqnpQAAAAAAAAAAAOefNWMRFxgcHT09PkJC
RERFhvL09PT09PT09PT09vb29vbV8PqwoQAAAAAAAAAAAPexIBoRFxgcHj0+QkJCREVIufT09PT29Pb0
9vv79vv2+/bY8PzdmgAAAAAAAAAAAPfdIBERGBgeHj0+QkJCRURc0/v29vb29vv79vv7+/v7+/vY1vzh
mQAAAAAAAAAAAADhMAoXGBwdHj0+QkJEREV88vv2+/v7+/b7+/v7+/v7+/vY1P3umgAAAAAAAAAAAADo
XQoXGBweHj4+QkJEREWG9Pv7+/v7+/v79vTy8tjY1dW/vfz5mt4AAAAAAAAAAADhbgkXGBwePT1BQkJE
REaP9PTy8fHT09PRwcG/x8fO5PP19f36pwAAAAAAAAAAAADhkgkXGBwePT4/P0BAQEV+ube3t9DFzefm
7O7s7+/4+Pjv9fX8AAAAAAAAAAAAAADhnwkXFRwcHCM5UG2BtLzK3ufu7u7t7Ovu6/fv+gAAAAAAAAAA
AAAAAAAAAAAAAADfqTRdbIedqqrd3Ojn5+nr6+vu7vkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADd
3dnd4d/h4ejn6/f4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4eHu7gAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA///4P///AAD//wAB//8AAP/8AAB//wAA//AAAB//AAD/4AAAD/8AAP/A
AAAP/wAA/8AAAAf/AAD/wAAAB/8AAP/AAAAP/wAA/+AAAA//AAD/8AAAAP8AAP/8AAAA/wAA//8AAAD/
AAD//8AAAP8AAP/+AAAAfwAA/8AAAAB/AAD4AAAAAH8AAMAAAAAAfwAAwAAAAAB/AADAAAAAAH8AAMAA
AAAAfwAAwAAAAAB/AADAAAAAAH8AAMAAAAAAfwAAwAAAAAA/AADgAAAAAD8AAOAAAAAAPwAA4AAAAAA/
AADgAAAAAD8AAOAAAAAAPwAA4AAAAAA/AADgAAAAAD8AAPAAAAAAHwAA8AAAAAAfAADwAAAAAB8AAPAA
AAAAHwAA8AAAAAAfAADwAAAAAB8AAPAAAAAAHwAA+AAAAAAfAAD4AAAAAA8AAPgAAAAAHwAA+AAAAAA/
AAD4AAAAP/8AAPgAAD///wAA+AA/////AAD8P/////8AAP///////wAAKAAAABAAAAAgAAAAAQAgAAAA
AABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALm/v/+5v7//sre3/6eqq/+en5//m56e/5qd
nf+anZ3/nqGh/6Chof8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADS0tKC2NjY/83U1f/Eycr/tbi5/6Sm
pv+hpKT/qa2t/6Chof+goaFhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN7e3ja7u7uCqa6u/5ea
mv+Mjo7/iYuL/6isrJygoaE2AAAAAAAAAAAAAAAAAAAAAMHHx4a+xMT/vMHB/7m9vv+3urv/tLi4/7G0
tP+vsbL/q66u/6mrq/+nqKn/paem/6OlpP+hoqP/oKGh/6ChoZXK0tP/ydLT/8nQ0//I0dL/x9DR/8bQ
0f/Ez9D/xM7Q/8PO0P/Dzc7/ws3O/8HNzv/AzM3/wMzN/77Lzf+goaH/ytLU/6yvr/+AAAD/gAAA/4YL
Cf+AAAD/gAAA/5QAAP+sJxX/rCcV/6wnFf+sJxX/rCcV/7pIOP/AzM3/oaKi/8zT1f+qrK3/mB0S/5om
HP+YHRL/lA0C/58SAP+oEQD/uzIf/85dTP/UXUj/2GBL/91hTP++TCr/v8zN/6OjpP/M09X/qKqq/5gw
KP+eNiz/mB4R/58QAP+qFQD/shIA/8xKNv/gfWv/43lm/+h8aP/sgGv/1GZK/8DNzv+kpab/zNPV/6ao
qP+lSED/pT4z/5wbEP+pEwD/tBcA/78WAv/dalf/7ZuN/++Tgv/zl4X/9ZyL/+aBaP/Bzc7/pqio/83T
1v+kpab/r1ZM/6U3Lf+iDgD/sBYA/70YAP/KHgX/6ot6//Sxpv/3qpv/+q6e//6ypP/zn4r/ws3O/6iq
qv/O1NX/oqSk/61KQf+jJx3/sBQA/8EcAP/SGwD/5DMT//uyo//+xrr//sOz///Gtv//ybr/+LWg/8LO
z/+qrKz/zdTW/6Gjo/+qMCP/qQ0A/8AbAP/RIQD/4RoA//NQNf//0sb//9TI///Uxv//18j//9rL//rG
tP/Dzs//rK6v/87U1v+goaH/pRwP/7MWAP/FHQD/1SMA/+caAP/6fWj//+vm///i2f//5tz//+nf///q
4P/6zb7/xM7Q/6+ysv/O1Nb/oKGh/6cZDf+4GAD/yhoA/90ZAP/xJwn/+Ipr//u/ov/7tJH/+66J//qo
f//2oXf/8Jty/8XO0P+xtLX/ztTW/6Chof+goaH/oKGh/6Gio/+jpaX/paen/6epqf+prKz/rK+v/6+x
sf+xtLX/tLi4/7a7vP/Fz9H/s7e4/87U1njO1Nb/ztTW/87U1v/N1Nb/zdPV/83T1f/M09X/y9LU/8rS
1P/K0tP/ydHT/8jR0v/H0NH/xs/R/7a6u5XgBwAA4AcAAPAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAACAEAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACjo6MDurq6I7S0
tFatra18t7e3hbm5uYeoqKiGjo6Of4KCgmB7e3stg4ODCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkJCQHbCw
sHzHx8fIzs7O8NXV1fvZ2dn+1tbW/s7Ozv7MzMz8wsLC9Kurq9WUlJRrjo6OMAAAAAAAAAAAAAAAAAAA
AAEAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJWV
lWu+vr7r0tLS/9fX1//b29v/3t7e/9zc3P/U1NT/zc3N/93d3f/b29v/wcHB/8XFxf+4uLj+eXl5UBMT
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIiCyqqqrOzc3N/83Nzf/Ly8v/z8/P/9PT
0//X19f/2tra/9vb2//a2tr/19fX/9LS0v/MzMz/0dHR/9/f3//Z2dn/wMDA/7e3t/++vr7/ycnJ/7i4
uP+wsLD9WVlZiAAAABYAAAAjAAAAKwAAACsAAAAlAAAAGQAAAA0AAAAGAAAAAwAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi4uLJbS0tOfIyMj/w8PD/8bG
xv/Ly8v/zs7O/9LS0v/X19f/29vb/9zc3P/c3Nz/2NjY/9HR0f/Kysr/09PT/+Hh4f/Q0ND/ubm5/8DA
wP/Pz8//urq6/62trf+urq7/ubm5/2FhYawAAABDAAAARgAAAEAAAAA2AAAAKQAAABwAAAARAAAACQAA
AAQAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJiYkDq6urvcDA
wP++vr7/wsLC/8TExP/IyMj/zMzM/9HR0f/X19f/29vb/93d3f/c3Nz/2NjY/9HR0f/Jycn/0tLS/9vb
2//FxcX/wcHB/8nJyf+6urr/sLCw/66urv+oqKj/oqKi/6qqqv8fHx93AAAATgAAAEkAAAA+AAAAMwAA
ACYAAAAbAAAAEQAAAAoAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAChoaEXtra29Lm5uf+8vLz/v7+//8LCwv/FxcX/ycnJ/87Ozv/U1NT/2dnZ/9zc3P/b29v/1tbW/87O
zv/Hx8f/zMzM/8zMzP/AwMD/w8PD/7e3t/+ysrL/rq6u/6SkpP+ampr/l5eX/6qqqv9GRkaXAAAARwAA
AEgAAABAAAAANQAAACgAAAAfAAAAFgAAAA4AAAAHAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAC6uroWtLS08be3t/+5ubn/vLy8/7+/v//BwcH/xcXF/8nJyf/Pz8//1NTU/9bW
1v/V1dX/0dHR/8rKyv/ExMT/xcXF/8DAwP++vr7/t7e3/7Gxsf+pqan/n5+f/5WVlf+SkpL/mJiY/6ur
q/9RUVGcAAAAPAAAAEEAAAA6AAAAMQAAACcAAAAeAAAAFgAAAA4AAAAHAAAAAwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0tLQCtbW1y7W1tf+3t7f/ubm5/729vf+/v7//wcHB/8TE
xP/Hx8f/y8vL/83Nzf/MzMz/ycnJ/8XFxf/BwcH/v7+//7q6uv+ysrL/qamp/6Ghof+Xl5f/kpKS/5OT
k/+YmJj/nZ2d/6urq/8pKSltAAAALgAAADQAAAAzAAAALAAAACMAAAAaAAAAEwAAAAwAAAAHAAAAAgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqampQrOzs/e7u7v/t7e3/7q6
uv+8vLz/vr6+/8DAwP/CwsL/xMTE/8bGxv/FxcX/wsLC/7y8vP+1tbX/ra2t/6ampv+bm5v/jIyM/3t7
e/95eXn/ioqK/5SUlP+bm5v/pqam/4GBgcoWFhZFODk5YTk5Olpubm5aEhISKQAAABwAAAAWAAAADgAA
AAgAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGdn
Z0WZmZnNu7u7/7a2tv+zs7P/tLS0/7S0tP+zs7P/srKy/7CwsP+tra3/pqam/5ubm/+SkpL/iIiI/3x8
fP9qamn/X19f/2VlZf97e3z/jY6O/56en/+sra3/tre3/pubnM6urq/iycrK/7a2t+6IiIi+Z2dnKwAA
ABEAAAALAAAABwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAICAgGTk5ObJ2dneiurq7/qamp/6Ojo/+enp7/m5ub/5ycnP+Pj4//goGB/3p6
ev9zc3P/bm5u/2tsbP91dnf/hIWG/5iYmv+goaL/sLCx/7e3uP+3t7f/u7u7/8HBwf/AwMD/v7+//L6+
vv+Xl5ftgICAMQAAAAMAAAADAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAYAAAAGAAAAABAQECNGRkZ0eXl5v4+PjuKgoKD4o6Oj/ouL
iv97e3v/gICB/4SEhf+IiYv/kJCT/5manP+oqKv/rq6w/66ur/+vr7D/r6+w/7a3t/+1t7f/u8LD/8LM
zf/Jzs//wcDA/by8vPyfn5/6b29vUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAGAAAACQAAAAwAAAAOAAAADQAAAAUAAAAAFhYXC0BA
QjBvb3GBjo+R7oqKjf+OjpL/kJCU/4+QlP+Skpb/lpaZ/56eof+lpaf/p6mr/6yxtP+1vsD/wMnL/87T
1P/W09P/2cnG/9+4tP/Wvrn/wMXF/cHBwfyioqL8jIyMbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAQEARQUFQgtLS8XSkpMNWpq
bGaCgoaYj4+TxJSUmOWQkJT4jY2R/42Nkf+MjJH/i42R/4uOk/+Nkpf/nKSo/6+4u//Dycv/z87P/9TH
xv/Usq7/2p+U/9FwYv/HQS7/wBwE/7QGAP+zX1X/w87P/sTExPyhoaH+n5+fiwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhoHJCQlHT8/QTBbW15MfX2AgY6O
kbCYmJ3anJyh+Zubn/+Xl5v/jo6S/4yMkf+KjpL/jJOY/5ihpf+hqKv/rauv/7mwsv/HvLz/yK2q/8mW
j//Oem7/wko6/7kgC/+0FAD/rBAA/6URAP+lFgP/phoI/6YTAf+yVkv/xczN/8fHx/2kpKT/nJycqwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI+PkxNwcHM3dHV4ZouIjqKOjZHTkZGW7piY
nPufn6P/oKCk/5+fov+fn6P/nZ+j/5mfpP+fp6v/oquu/6usr/+8tbb/xra1/8SfnP++eHD/uFRK/682
J/+nHg7/phgH/6UTAv+lFQP/phoJ/6gfDv+qIRD/rCMR/68kEf+wJRL/sSYT/7EeC/+5UEL/x8vM/8nJ
yf6pqan/nJycxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkZGVao+Pk+aTk5f/kpCW/4Cd
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
T//kiXr/5ol5/+iKef/qjHv/7I17/+2OfP/vj33/8JB+//KRf//zkoD/9JOB//WVgv/3kX7/7H1n/9TI
xv/W2dn/ra2t/5mZmdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOfn5zO5vsH+noSE/4wc
Ff+mS0T/pEhB/6JGP/+kRj7/pkA2/5UWCP+VDQD/mw8A/6ISAP+nFAD/qhUA/64VAP+0FwD/uRkA/74a
AP/DGgD/yScM/+B0Yv/plYb/65SF/+yVhf/ulob/8JeH//GZiP/zmYj/9JqJ//abiv/2nIv/952M//ie
jf/5noz/84Jr/9W8uP/Y3N3/t7e3/5mZmeoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO7u
7xe9wMLwqJyd/4ojHP+pUEn/qFFK/6dOR/+sUUj/pDYs/5MOAP+ZDwD/nxEA/6YTAP+pFAD/rBUA/7IW
AP+4GAD/vhoA/8McAP/GGwD/zzAV/+aFdP/tn5H/7p2P//Cej//xn5D/86GR//Whkf/2o5L/96ST//il
lP/5ppX/+qaW//unl//8p5f/+4t0/9q0rP/Y3uD/vr6+/5mZmfSenp4HAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPLy8ge/wMLbs7Gz/4ovKP+qUUv/q1hS/61YT/+wV07/nCQX/5UMAP+cEAD/ohIA/6gU
AP+rFQD/sBYA/7YYAP+7GQD/whsA/8YcAP/KGwD/1jwi/+uVhv/wp5v/8aaY//Onmf/1qJr/9qma//iq
m//5q5z/+ayc//utnv/8rp7//a+f//6woP//sKD//5aA/+SzqP/Y4OH/w8PD/5mZmfucnJwiAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADGxsi/vMDC/48+Of+qUEr/sF9a/7NhWf+xVUv/lhQG/5kN
AP+gEQD/pRMA/6kVAP+uFQD/tBcA/7kYAP+/GgD/xBwA/8gdAP/NHQD/3Ewz/++jlv/yr6P/86+i//Wv
ov/3sKP/+LGk//mypP/7s6X//LSm//62pv//tqf//7ao//+4qf//uar//6KN/+Wvo//a4eL/yMjI/5mZ
mf6bm5tJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADNzs+bw8jL/5hNSP+oTkj/tmpi/7lr
Y/+rRDr/lgwA/50QAP+jEgD/pxQA/6sVAP+xFgD/txgA/78aAP/GHQD/zB4A/9MfAP/aIwL/6WVM//e0
p//5ua3/+7mr//y6rP/9u63//b2u//6+rv/+v6///8Gw///CsP//w7H//8Sy///Esv//xrT//7Sc/+iv
nP/b4OL/zc3N/5qamv+bm5tzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADW1th3w8nM/5tT
Tv+oTET/u3Ns/7tsZP+eKBv/mAsA/6ERAP+oFAD/rhUA/7cYAP+/GwD/xx0A/88fAP/XIQD/3iIA/+Qj
AP/sLgn/9oFq//3Btf//wrX//8K1///Etv//xbb//8e3///IuP//ybj//8m5///Luv//zLv//827///O
vP//0L3//8Oq/+yulf/c3t//0dHR/5ubm/+ampqcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADc3N5TxMvN/5dYVP+mR0D/wXx1/7ZbUv+aEgT/oxEA/6oUAP+xFgD/uRkA/8EbAP/HHQD/zR4A/9Qg
AP/aIgD/4CMA/+cjAP/vORb/+ZmF//7Jvv//yL3//8m9///Kvf//zL7//82////Ov///z8D//9DA///R
wf//0sH//9PC///Uw///1cT//8y2//Guk//b2tn/2NnZ/56env+ampq6AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADh4eI4xs3P/5dlYv+lQjn/xoF5/6s9Mf+eDAD/qBQA/6wVAP+0FwD/uxkA/8Ib
AP/JHQD/0B8A/9YhAP/cIwD/5CQA/+sjAP/ySyn//K6f///Pxv//zsP//8/E///QxP//0sX//9PF///U
xv//1cb//9bH///Xx///2Mj//9jJ///Zyv//28z//9XD//Wxlv/b09D/3+Dh/6Ghof+ZmZnTAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADU1NYbyc/R85x8ef+iPTP/wnZt/6AeD/+hDwD/qRQA/68V
AP+3GAD/vhoA/8QcAP/LHgD/0yAA/9ghAP/fIwD/6CQA/+0lAP/2YUP//8K2///VzP//1Mr//9XK///W
yv//18v//9jL///ZzP//2sz//9vN///czv//3c///93Q///f0f//4NP//93O//q5nv/dz8n/4+bn/6mp
qf+ZmZnkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt7e4Jys3Q3qmZmP+cOS//s1BF/5sO
AP+kEgD/qxUA/7EWAP+5GQD/vxsA/8cdAP/OHgD/1SAA/9siAP/jJAD/6yUA//ArBP/6fmX//9LI///a
0f//2dD//9rQ///b0f//3NH//93S///e0v//39L//+DT///h1f//4tb//+PX///k2P//5dn//+LW//3C
qf/lz8b/6Ozu/7Ozs/+YmJjynp6eBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzM7QuLq0
tf+SKB7/nhsN/50PAP+mEwD/rBUA/7QXAP+8GQD/wRsA/8kdAP/RHwD/1yEA/90jAP/mJQD/7SQA//Q4
Ev/+oI3//97X///e1///39b//9/X///g1///4df//+LY///j2P//5Nn//+Xa///m2///593//+fe///o
3v//6d///+je///Mtv/mzMH/7fHz/8HBwf+Xl5f6nJycJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAwMHDlcPExf+NIxn/lwkA/6ARAP+nFAD/rhUA/7YXAP+9GgD/wxwA/8sdAP/TIAD/2SIA/98j
AP/oJQD/7iUA//dKJ///uq3//+Pd///i2///49v//+Pb///j2///5dz//+bc///n3P//597//+je///p
4P//6uH//+vi///r4///7OT//+zk///Uwv/lyLz/7/P1/8zMzP+YmJj+nJycSQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAy8vNdsLJyv+KMSj/mQgA/6ERAP+oFAD/rxYA/7gYAP++GgD/xBwA/80e
AP/VIAD/2yIA/+EkAP/pJQD/8CUA//piQ///z8X//+fh///l3///5t///+bf///n4P//6OD//+nh///q
4f//6+L//+vj///s5P//7OT//+3l///s5P//7OT//+rg///Uv//owK7/8fX3/9bW1v+YmJj/m5ubawAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArq6xVcjR0/+NSUH/mQYA/6MSAP+pFAD/sBYA/7kY
AP+/GwD/xhwA/84eAP/WIQD/3CIA/+MkAP/rJQD/8ioC//x+Zf//39j//+rl///p5P//6uT//+rk///q
4///6uH//+nf///m3P//5Nj//+HU///czP//18T//9G8//3JtP/5w6v/9ryk//Gtjv/WppL/7/P1/+Xl
5f+YmJj/np6ejAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0tLUNsXNz/6UZWD/lwUA/6QS
AP+pFAD/sRYA/7oZAP/AGwD/xh0A/9AfAP/WIQD/3SIA/+QkAP/sJAD/9TEK//+TfP//39f//9/W///X
y///0MH//8m4//3DsP/3vqn/9Lqk//S5of/0tp3/9LOY/+mulv/frpr/2LOj/9i+tP/cy8T/4tbR/+bh
3//m5ub/8fHx/+jo6P+mpqb6s7OzTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAubm7F8HG
yO+dhIL/lAcA/6USAP+qFAD/sxYA/7wZAP/DGgD/yhsA/9UaAP/bGgD/4BoA/+YaAP/rGwD/7CsE/+1s
Uv/qmYf/4pyM/+GgkP/hpZX/2qqd/9Gxp//Rvrn/1MrH/9nSz//c19b/2dfX/9jZ2v/X29z/297f/9zf
4Pvb3d3u2tvc39XW1tnb29vG3Nzcst7e3o3MzMxLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAw8PGBby/wdeomZn/lQcA/6YJAP+oCwD/rw0A/7URAP+1GAD/tSIL/7c1IP+3Sjf/vGBQ/8Z1
aP/Fin//wKCa/8W3tP/LxsX/zs/Q/9HW1//T2Nr/0tfZ/9PX2f/T1db50dPT7NDR0d3Nzs7Xz8/Pwc/P
z63U1NSP0NDQdNLS0k/Ozs8rysrKFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAALCytb2zra7/hTgw/5FKQ/+cZV//roF7/7GSjv+xoaD/tLGy/7vB
w/+/ys3/xdDT/8rU1v/N1db/ztPU983P0OvNzs7dy8vL1MvLy8HKysqmzs7Oj8vLzHnOzs5Oy8vLM8rK
yhrKysoDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2tr7PCw8P/t7/C/73Fx//Dy83/xMrM/cXJ
y/XHycrqxsfI3MbGx83Hx8jAx8fHp8rKyovIyMhzy8vLUsrKyjnKysoaysrKCwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCgo3a5ubvAvLy9wr+/
wK28vL6NwMDBb8LCw1fHx8g8ysrKIMrKyhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADKysoOysrKAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AD//8AAP/8
AAD4fwAA//AAACAPAAD/4AAAAAcAAP/AAAAAAQAA/4AAAAABAAD/gAAAAAEAAP+AAAAAAQAA/4AAAAAB
AAD/wAAAAAEAAP/gAAAAAAAA//AAAAAHAAD/hAAAAH8AAP4BAAAAfwAA/4AAAAB/AAD8AAAAAH8AAMAA
AAAAfwAAgAAAAAB/AACAAAAAAH8AAIAAAAAAPwAAgAAAAAA/AACAAAAAAD8AAIAAAAAAPwAAwAAAAAA/
AADAAAAAAD8AAMAAAAAAPwAAwAAAAAA/AADAAAAAAD8AAMAAAAAAHwAAwAAAAAAfAADgAAAAAB8AAOAA
AAAAHwAA4AAAAAAfAADgAAAAAB8AAOAAAAAAHwAA4AAAAAAfAADgAAAAAA8AAPAAAAAADwAA8AAAAAAP
AADwAAAAAA8AAPAAAAAADwAA8AAAAAAPAADwAAAAAB8AAPAAAAAD/wAA+AAAAf//AAD4AAH///8AAPgB
/////wAA/P//////AAA=
</value>
</data>
</root>

257
MainForm.Designer.cs generated
View File

@@ -83,6 +83,19 @@
this.devicesTabControl = new System.Windows.Forms.TabControl();
this.devicesTabPage = new System.Windows.Forms.TabPage();
this.devicesPanel = new System.Windows.Forms.Panel();
this.devicesListView = new System.Windows.Forms.ListView();
this.nameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.stateColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.devicesContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.addMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addRelayMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.httpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.httpsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.rdpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.sshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.devicesImageList = new System.Windows.Forms.ImageList(this.components);
this.noSearchResultsLabel = new System.Windows.Forms.Label();
this.noDevicesLabel = new System.Windows.Forms.Label();
this.portMapTabPage = new System.Windows.Forms.TabPage();
@@ -110,19 +123,7 @@
this.saveMappingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openMapFileDialog = new System.Windows.Forms.OpenFileDialog();
this.saveMapFileDialog = new System.Windows.Forms.SaveFileDialog();
this.devicesListView = new System.Windows.Forms.ListView();
this.devicesImageList = new System.Windows.Forms.ImageList(this.components);
this.nameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.stateColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.devicesContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.httpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.httpsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.rdpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.sshToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.addMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addRelayMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.remoteDesktopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.panel5.SuspendLayout();
this.mainPanel.SuspendLayout();
this.mainTabControl.SuspendLayout();
@@ -143,6 +144,7 @@
this.devicesTabControl.SuspendLayout();
this.devicesTabPage.SuspendLayout();
this.devicesPanel.SuspendLayout();
this.devicesContextMenuStrip.SuspendLayout();
this.portMapTabPage.SuspendLayout();
this.mapPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.settingsPictureBox)).BeginInit();
@@ -151,7 +153,6 @@
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.trayIconContextMenuStrip.SuspendLayout();
this.mappingsContextMenuStrip.SuspendLayout();
this.devicesContextMenuStrip.SuspendLayout();
this.SuspendLayout();
//
// panel5
@@ -554,6 +555,118 @@
this.devicesPanel.Controls.Add(this.noDevicesLabel);
this.devicesPanel.Name = "devicesPanel";
//
// devicesListView
//
this.devicesListView.BackColor = System.Drawing.SystemColors.Window;
this.devicesListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.nameColumnHeader,
this.stateColumnHeader});
this.devicesListView.ContextMenuStrip = this.devicesContextMenuStrip;
this.devicesListView.FullRowSelect = true;
this.devicesListView.GridLines = true;
this.devicesListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.devicesListView.LargeImageList = this.devicesImageList;
resources.ApplyResources(this.devicesListView, "devicesListView");
this.devicesListView.MultiSelect = false;
this.devicesListView.Name = "devicesListView";
this.devicesListView.SmallImageList = this.devicesImageList;
this.devicesListView.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.devicesListView.UseCompatibleStateImageBehavior = false;
this.devicesListView.View = System.Windows.Forms.View.Details;
this.devicesListView.DoubleClick += new System.EventHandler(this.devicesListView_DoubleClick);
//
// nameColumnHeader
//
resources.ApplyResources(this.nameColumnHeader, "nameColumnHeader");
//
// stateColumnHeader
//
resources.ApplyResources(this.stateColumnHeader, "stateColumnHeader");
//
// devicesContextMenuStrip
//
this.devicesContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addMapToolStripMenuItem,
this.addRelayMapToolStripMenuItem,
this.toolStripMenuItem3,
this.remoteDesktopToolStripMenuItem,
this.httpToolStripMenuItem,
this.httpsToolStripMenuItem,
this.rdpToolStripMenuItem,
this.sshToolStripMenuItem,
this.scpToolStripMenuItem});
this.devicesContextMenuStrip.Name = "devicesContextMenuStrip";
resources.ApplyResources(this.devicesContextMenuStrip, "devicesContextMenuStrip");
this.devicesContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.devicesContextMenuStrip_Opening);
//
// addMapToolStripMenuItem
//
resources.ApplyResources(this.addMapToolStripMenuItem, "addMapToolStripMenuItem");
this.addMapToolStripMenuItem.Name = "addMapToolStripMenuItem";
this.addMapToolStripMenuItem.Click += new System.EventHandler(this.addMapToolStripMenuItem_Click);
//
// addRelayMapToolStripMenuItem
//
this.addRelayMapToolStripMenuItem.Name = "addRelayMapToolStripMenuItem";
resources.ApplyResources(this.addRelayMapToolStripMenuItem, "addRelayMapToolStripMenuItem");
this.addRelayMapToolStripMenuItem.Click += new System.EventHandler(this.addRelayMapToolStripMenuItem_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
resources.ApplyResources(this.toolStripMenuItem3, "toolStripMenuItem3");
//
// httpToolStripMenuItem
//
this.httpToolStripMenuItem.Name = "httpToolStripMenuItem";
resources.ApplyResources(this.httpToolStripMenuItem, "httpToolStripMenuItem");
this.httpToolStripMenuItem.Click += new System.EventHandler(this.httpToolStripMenuItem_Click);
//
// httpsToolStripMenuItem
//
this.httpsToolStripMenuItem.Name = "httpsToolStripMenuItem";
resources.ApplyResources(this.httpsToolStripMenuItem, "httpsToolStripMenuItem");
this.httpsToolStripMenuItem.Click += new System.EventHandler(this.httpsToolStripMenuItem_Click);
//
// rdpToolStripMenuItem
//
this.rdpToolStripMenuItem.Name = "rdpToolStripMenuItem";
resources.ApplyResources(this.rdpToolStripMenuItem, "rdpToolStripMenuItem");
this.rdpToolStripMenuItem.Click += new System.EventHandler(this.rdpToolStripMenuItem_Click);
//
// sshToolStripMenuItem
//
this.sshToolStripMenuItem.Name = "sshToolStripMenuItem";
resources.ApplyResources(this.sshToolStripMenuItem, "sshToolStripMenuItem");
this.sshToolStripMenuItem.Click += new System.EventHandler(this.sshToolStripMenuItem_Click);
//
// scpToolStripMenuItem
//
this.scpToolStripMenuItem.Name = "scpToolStripMenuItem";
resources.ApplyResources(this.scpToolStripMenuItem, "scpToolStripMenuItem");
this.scpToolStripMenuItem.Click += new System.EventHandler(this.scpToolStripMenuItem_Click);
//
// devicesImageList
//
this.devicesImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("devicesImageList.ImageStream")));
this.devicesImageList.TransparentColor = System.Drawing.Color.Transparent;
this.devicesImageList.Images.SetKeyName(0, "icons01.png");
this.devicesImageList.Images.SetKeyName(1, "icons01t.png");
this.devicesImageList.Images.SetKeyName(2, "icons02.png");
this.devicesImageList.Images.SetKeyName(3, "icons02t.png");
this.devicesImageList.Images.SetKeyName(4, "icons03.png");
this.devicesImageList.Images.SetKeyName(5, "icons03t.png");
this.devicesImageList.Images.SetKeyName(6, "icons04.png");
this.devicesImageList.Images.SetKeyName(7, "icons04t.png");
this.devicesImageList.Images.SetKeyName(8, "icons05.png");
this.devicesImageList.Images.SetKeyName(9, "icons05t.png");
this.devicesImageList.Images.SetKeyName(10, "icons06.png");
this.devicesImageList.Images.SetKeyName(11, "icons06t.png");
this.devicesImageList.Images.SetKeyName(12, "icons07.png");
this.devicesImageList.Images.SetKeyName(13, "icons07t.png");
this.devicesImageList.Images.SetKeyName(14, "icons08.png");
this.devicesImageList.Images.SetKeyName(15, "icons08t.png");
//
// noSearchResultsLabel
//
resources.ApplyResources(this.noSearchResultsLabel, "noSearchResultsLabel");
@@ -734,116 +847,11 @@
this.saveMapFileDialog.DefaultExt = "mcrouter";
resources.ApplyResources(this.saveMapFileDialog, "saveMapFileDialog");
//
// devicesListView
// remoteDesktopToolStripMenuItem
//
this.devicesListView.BackColor = System.Drawing.SystemColors.Window;
this.devicesListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.nameColumnHeader,
this.stateColumnHeader});
this.devicesListView.ContextMenuStrip = this.devicesContextMenuStrip;
this.devicesListView.FullRowSelect = true;
this.devicesListView.GridLines = true;
this.devicesListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.devicesListView.LargeImageList = this.devicesImageList;
resources.ApplyResources(this.devicesListView, "devicesListView");
this.devicesListView.MultiSelect = false;
this.devicesListView.Name = "devicesListView";
this.devicesListView.SmallImageList = this.devicesImageList;
this.devicesListView.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.devicesListView.UseCompatibleStateImageBehavior = false;
this.devicesListView.View = System.Windows.Forms.View.Details;
this.devicesListView.DoubleClick += new System.EventHandler(this.devicesListView_DoubleClick);
//
// devicesImageList
//
this.devicesImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("devicesImageList.ImageStream")));
this.devicesImageList.TransparentColor = System.Drawing.Color.Transparent;
this.devicesImageList.Images.SetKeyName(0, "icons01.png");
this.devicesImageList.Images.SetKeyName(1, "icons01t.png");
this.devicesImageList.Images.SetKeyName(2, "icons02.png");
this.devicesImageList.Images.SetKeyName(3, "icons02t.png");
this.devicesImageList.Images.SetKeyName(4, "icons03.png");
this.devicesImageList.Images.SetKeyName(5, "icons03t.png");
this.devicesImageList.Images.SetKeyName(6, "icons04.png");
this.devicesImageList.Images.SetKeyName(7, "icons04t.png");
this.devicesImageList.Images.SetKeyName(8, "icons05.png");
this.devicesImageList.Images.SetKeyName(9, "icons05t.png");
this.devicesImageList.Images.SetKeyName(10, "icons06.png");
this.devicesImageList.Images.SetKeyName(11, "icons06t.png");
this.devicesImageList.Images.SetKeyName(12, "icons07.png");
this.devicesImageList.Images.SetKeyName(13, "icons07t.png");
this.devicesImageList.Images.SetKeyName(14, "icons08.png");
this.devicesImageList.Images.SetKeyName(15, "icons08t.png");
//
// nameColumnHeader
//
resources.ApplyResources(this.nameColumnHeader, "nameColumnHeader");
//
// stateColumnHeader
//
resources.ApplyResources(this.stateColumnHeader, "stateColumnHeader");
//
// devicesContextMenuStrip
//
this.devicesContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addMapToolStripMenuItem,
this.addRelayMapToolStripMenuItem,
this.toolStripMenuItem3,
this.httpToolStripMenuItem,
this.httpsToolStripMenuItem,
this.rdpToolStripMenuItem,
this.sshToolStripMenuItem,
this.scpToolStripMenuItem});
this.devicesContextMenuStrip.Name = "devicesContextMenuStrip";
resources.ApplyResources(this.devicesContextMenuStrip, "devicesContextMenuStrip");
this.devicesContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.devicesContextMenuStrip_Opening);
//
// httpToolStripMenuItem
//
this.httpToolStripMenuItem.Name = "httpToolStripMenuItem";
resources.ApplyResources(this.httpToolStripMenuItem, "httpToolStripMenuItem");
this.httpToolStripMenuItem.Click += new System.EventHandler(this.httpToolStripMenuItem_Click);
//
// httpsToolStripMenuItem
//
this.httpsToolStripMenuItem.Name = "httpsToolStripMenuItem";
resources.ApplyResources(this.httpsToolStripMenuItem, "httpsToolStripMenuItem");
this.httpsToolStripMenuItem.Click += new System.EventHandler(this.httpsToolStripMenuItem_Click);
//
// rdpToolStripMenuItem
//
this.rdpToolStripMenuItem.Name = "rdpToolStripMenuItem";
resources.ApplyResources(this.rdpToolStripMenuItem, "rdpToolStripMenuItem");
this.rdpToolStripMenuItem.Click += new System.EventHandler(this.rdpToolStripMenuItem_Click);
//
// sshToolStripMenuItem
//
this.sshToolStripMenuItem.Name = "sshToolStripMenuItem";
resources.ApplyResources(this.sshToolStripMenuItem, "sshToolStripMenuItem");
this.sshToolStripMenuItem.Click += new System.EventHandler(this.sshToolStripMenuItem_Click);
//
// scpToolStripMenuItem
//
this.scpToolStripMenuItem.Name = "scpToolStripMenuItem";
resources.ApplyResources(this.scpToolStripMenuItem, "scpToolStripMenuItem");
this.scpToolStripMenuItem.Click += new System.EventHandler(this.scpToolStripMenuItem_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
resources.ApplyResources(this.toolStripMenuItem3, "toolStripMenuItem3");
//
// addMapToolStripMenuItem
//
resources.ApplyResources(this.addMapToolStripMenuItem, "addMapToolStripMenuItem");
this.addMapToolStripMenuItem.Name = "addMapToolStripMenuItem";
this.addMapToolStripMenuItem.Click += new System.EventHandler(this.addMapToolStripMenuItem_Click);
//
// addRelayMapToolStripMenuItem
//
this.addRelayMapToolStripMenuItem.Name = "addRelayMapToolStripMenuItem";
resources.ApplyResources(this.addRelayMapToolStripMenuItem, "addRelayMapToolStripMenuItem");
this.addRelayMapToolStripMenuItem.Click += new System.EventHandler(this.addRelayMapToolStripMenuItem_Click);
this.remoteDesktopToolStripMenuItem.Name = "remoteDesktopToolStripMenuItem";
resources.ApplyResources(this.remoteDesktopToolStripMenuItem, "remoteDesktopToolStripMenuItem");
this.remoteDesktopToolStripMenuItem.Click += new System.EventHandler(this.remoteDesktopToolStripMenuItem_Click);
//
// MainForm
//
@@ -880,6 +888,7 @@
this.devicesTabControl.ResumeLayout(false);
this.devicesTabPage.ResumeLayout(false);
this.devicesPanel.ResumeLayout(false);
this.devicesContextMenuStrip.ResumeLayout(false);
this.portMapTabPage.ResumeLayout(false);
this.mapPanel.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.settingsPictureBox)).EndInit();
@@ -888,7 +897,6 @@
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.trayIconContextMenuStrip.ResumeLayout(false);
this.mappingsContextMenuStrip.ResumeLayout(false);
this.devicesContextMenuStrip.ResumeLayout(false);
this.ResumeLayout(false);
}
@@ -987,6 +995,7 @@
private System.Windows.Forms.ToolStripMenuItem addMapToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addRelayMapToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem remoteDesktopToolStripMenuItem;
}
}

View File

@@ -1445,6 +1445,22 @@ namespace MeshCentralRouter
addButton_Click(null, null);
}
private void remoteDesktopToolStripMenuItem_Click(object sender, EventArgs e)
{
if (devicesListView.SelectedItems.Count != 1) { return; }
ListViewItem selecteditem = devicesListView.SelectedItems[0];
NodeClass node = (NodeClass)selecteditem.Tag;
if ((node.conn & 1) == 0) { return; } // Agent not connected on this device
if (node.desktopViewer == null)
{
node.desktopViewer = new KVMViewer(meshcentral, node);
node.desktopViewer.Show();
node.desktopViewer.MenuItemConnect_Click(null, null);
} else {
node.desktopViewer.Focus();
}
}
/*
private delegate void displayMessageHandler(string msg, int buttons, string extra, int progress);
private void displayMessage(string msg, int buttons = 0, string extra = "", int progress = 0)

View File

@@ -1342,52 +1342,58 @@
<value>Segoe UI, 9pt, style=Bold</value>
</data>
<data name="addMapToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="addMapToolStripMenuItem.Text" xml:space="preserve">
<value>Add &amp;Map...</value>
</data>
<data name="addRelayMapToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="addRelayMapToolStripMenuItem.Text" xml:space="preserve">
<value>Add &amp;Relay Map...</value>
</data>
<data name="toolStripMenuItem3.Size" type="System.Drawing.Size, System.Drawing">
<value>160, 6</value>
<value>167, 6</value>
</data>
<data name="remoteDesktopToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>170, 22</value>
</data>
<data name="remoteDesktopToolStripMenuItem.Text" xml:space="preserve">
<value>Remote Desktop...</value>
</data>
<data name="httpToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="httpToolStripMenuItem.Text" xml:space="preserve">
<value>HTTP</value>
</data>
<data name="httpsToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="httpsToolStripMenuItem.Text" xml:space="preserve">
<value>HTTPS</value>
</data>
<data name="rdpToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="rdpToolStripMenuItem.Text" xml:space="preserve">
<value>RDP</value>
</data>
<data name="sshToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="sshToolStripMenuItem.Text" xml:space="preserve">
<value>SSH</value>
</data>
<data name="scpToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>163, 22</value>
<value>170, 22</value>
</data>
<data name="scpToolStripMenuItem.Text" xml:space="preserve">
<value>SCP</value>
</data>
<data name="devicesContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>164, 164</value>
<value>171, 208</value>
</data>
<data name="&gt;&gt;devicesContextMenuStrip.Name" xml:space="preserve">
<value>devicesContextMenuStrip</value>
@@ -1403,7 +1409,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADg
HQAAAk1TRnQBSQFMAgEBEAEAARgBAAEIAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA
HQAAAk1TRnQBSQFMAgEBEAEAATABAAEQAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABUAMAAQEBAAEYBgABPP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AJYAA/0D+AP3A/sD/yEAA/0D+gP5
A/wD/xgAAfoB+wH6A/4qAAP9A/8tAAP7A88D1QPbA88D1AO+A9QYAAP8A90D4APjA90D4APUA+MSAAP8
AZEBjwF9AU4BaAEhAfQB9QH0JAAD/gPRA8YD+ioAAcYCxwHPAtAB2ALZA90DywPBA68DmgP3FQAD2APd
@@ -1570,7 +1576,7 @@
<value>2, 88</value>
</data>
<data name="noSearchResultsLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>454, 52</value>
<value>450, 52</value>
</data>
<data name="noSearchResultsLabel.TabIndex" type="System.Int32, mscorlib">
<value>5</value>
@@ -1609,7 +1615,7 @@
<value>2, 88</value>
</data>
<data name="noDevicesLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>454, 52</value>
<value>450, 52</value>
</data>
<data name="noDevicesLabel.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
@@ -1699,7 +1705,7 @@
<value>2, 79</value>
</data>
<data name="noMapLabel.Size" type="System.Drawing.Size, System.Drawing">
<value>454, 52</value>
<value>450, 52</value>
</data>
<data name="noMapLabel.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
@@ -5703,6 +5709,72 @@ Click "Add" to get started.</value>
<data name="&gt;&gt;sortByGroupToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;nameColumnHeader.Name" xml:space="preserve">
<value>nameColumnHeader</value>
</data>
<data name="&gt;&gt;nameColumnHeader.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;stateColumnHeader.Name" xml:space="preserve">
<value>stateColumnHeader</value>
</data>
<data name="&gt;&gt;stateColumnHeader.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;addMapToolStripMenuItem.Name" xml:space="preserve">
<value>addMapToolStripMenuItem</value>
</data>
<data name="&gt;&gt;addMapToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;addRelayMapToolStripMenuItem.Name" xml:space="preserve">
<value>addRelayMapToolStripMenuItem</value>
</data>
<data name="&gt;&gt;addRelayMapToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem3.Name" xml:space="preserve">
<value>toolStripMenuItem3</value>
</data>
<data name="&gt;&gt;toolStripMenuItem3.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;httpToolStripMenuItem.Name" xml:space="preserve">
<value>httpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;httpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;httpsToolStripMenuItem.Name" xml:space="preserve">
<value>httpsToolStripMenuItem</value>
</data>
<data name="&gt;&gt;httpsToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;rdpToolStripMenuItem.Name" xml:space="preserve">
<value>rdpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;rdpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;sshToolStripMenuItem.Name" xml:space="preserve">
<value>sshToolStripMenuItem</value>
</data>
<data name="&gt;&gt;sshToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;scpToolStripMenuItem.Name" xml:space="preserve">
<value>scpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;scpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;devicesImageList.Name" xml:space="preserve">
<value>devicesImageList</value>
</data>
<data name="&gt;&gt;devicesImageList.Type" xml:space="preserve">
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;stateClearTimer.Name" xml:space="preserve">
<value>stateClearTimer</value>
</data>
@@ -5769,70 +5841,10 @@ Click "Add" to get started.</value>
<data name="&gt;&gt;saveMapFileDialog.Type" xml:space="preserve">
<value>System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;devicesImageList.Name" xml:space="preserve">
<value>devicesImageList</value>
<data name="&gt;&gt;remoteDesktopToolStripMenuItem.Name" xml:space="preserve">
<value>remoteDesktopToolStripMenuItem</value>
</data>
<data name="&gt;&gt;devicesImageList.Type" xml:space="preserve">
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;nameColumnHeader.Name" xml:space="preserve">
<value>nameColumnHeader</value>
</data>
<data name="&gt;&gt;nameColumnHeader.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;stateColumnHeader.Name" xml:space="preserve">
<value>stateColumnHeader</value>
</data>
<data name="&gt;&gt;stateColumnHeader.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;httpToolStripMenuItem.Name" xml:space="preserve">
<value>httpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;httpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;httpsToolStripMenuItem.Name" xml:space="preserve">
<value>httpsToolStripMenuItem</value>
</data>
<data name="&gt;&gt;httpsToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;rdpToolStripMenuItem.Name" xml:space="preserve">
<value>rdpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;rdpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;sshToolStripMenuItem.Name" xml:space="preserve">
<value>sshToolStripMenuItem</value>
</data>
<data name="&gt;&gt;sshToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;scpToolStripMenuItem.Name" xml:space="preserve">
<value>scpToolStripMenuItem</value>
</data>
<data name="&gt;&gt;scpToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem3.Name" xml:space="preserve">
<value>toolStripMenuItem3</value>
</data>
<data name="&gt;&gt;toolStripMenuItem3.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;addMapToolStripMenuItem.Name" xml:space="preserve">
<value>addMapToolStripMenuItem</value>
</data>
<data name="&gt;&gt;addMapToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;addRelayMapToolStripMenuItem.Name" xml:space="preserve">
<value>addRelayMapToolStripMenuItem</value>
</data>
<data name="&gt;&gt;addRelayMapToolStripMenuItem.Type" xml:space="preserve">
<data name="&gt;&gt;remoteDesktopToolStripMenuItem.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">

View File

@@ -106,6 +106,30 @@
<Compile Include="InstallForm.Designer.cs">
<DependentUpon>InstallForm.cs</DependentUpon>
</Compile>
<Compile Include="KVMControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="KVMControl.Designer.cs">
<DependentUpon>KVMControl.cs</DependentUpon>
</Compile>
<Compile Include="KVMResizeControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="KVMResizeControl.Designer.cs">
<DependentUpon>KVMResizeControl.cs</DependentUpon>
</Compile>
<Compile Include="KVMSettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="KVMSettingsForm.Designer.cs">
<DependentUpon>KVMSettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="KVMViewer.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="KVMViewer.Designer.cs">
<DependentUpon>KVMViewer.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -394,6 +418,18 @@
<EmbeddedResource Include="InstallForm.zh-chs.resx">
<DependentUpon>InstallForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="KVMControl.resx">
<DependentUpon>KVMControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="KVMResizeControl.resx">
<DependentUpon>KVMResizeControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="KVMSettingsForm.resx">
<DependentUpon>KVMSettingsForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="KVMViewer.resx">
<DependentUpon>KVMViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.cs.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
@@ -667,6 +703,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="MeshServer.ico" />
<None Include="Resources\50-Computer.png" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">

View File

@@ -35,7 +35,7 @@ namespace MeshCentralRouter
public class MeshCentralServer
{
private Uri wsurl = null;
public Uri wsurl = null;
private string user = null;
private string pass = null;
private string token = null;
@@ -52,6 +52,7 @@ namespace MeshCentralRouter
public bool disconnectSms2FASent = false;
public X509Certificate2 disconnectCert;
public string authCookie = null;
public string rauthCookie = null;
public string loginCookie = null;
public string wshash = null;
public string certHash = null;
@@ -157,6 +158,15 @@ namespace MeshCentralRouter
}
}
public void sendCommand(string cmd)
{
if (wc != null)
{
if (debug) { try { File.AppendAllText("debug.log", "sendCommand: " + cmd + "\r\n"); } catch (Exception) { } }
wc.WriteStringWebSocket(cmd);
}
}
public void refreshCookies()
{
if (wc != null) {
@@ -209,6 +219,7 @@ namespace MeshCentralRouter
case "authcookie":
{
authCookie = jsonAction["cookie"].ToString();
rauthCookie = jsonAction["rcookie"].ToString();
changeState(2);
break;
}
@@ -541,7 +552,7 @@ namespace MeshCentralRouter
public delegate void onLoginTokenChangedHandler();
public event onLoginTokenChangedHandler onLoginTokenChanged;
private class xwebclient : IDisposable
public class xwebclient : IDisposable
{
private MeshCentralServer parent = null;
private TcpClient wsclient = null;

View File

@@ -20,6 +20,7 @@ namespace MeshCentralRouter
public MeshClass mesh;
public ListViewItem listitem;
public DeviceUserControl control;
public KVMViewer desktopViewer;
public Dictionary<string, ulong> links;
public override string ToString() { return name; }

View File

@@ -60,6 +60,16 @@ namespace MeshCentralRouter.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap _50_Computer {
get {
object obj = ResourceManager.GetObject("50-Computer", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized string similar to Agent.
/// </summary>

View File

@@ -121,109 +121,112 @@
<data name="Help20" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Help20.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="HelpRelayMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HelpRelayMap.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Folder36" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Folder36.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="SearchPlaceHolder" xml:space="preserve">
<value>Search</value>
</data>
<data name="MC2Banner" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\MC2-Banner.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="MeshCentral" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\MeshCentral.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="PuttyAppName" xml:space="preserve">
<value>PuTTY SSH client</value>
</data>
<data name="Gear20" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gear20.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="WinscpAppName" xml:space="preserve">
<value>WinSCP client</value>
</data>
<data name="xinstall" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\xinstall.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icons01" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icons01.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="EmptyBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Empty-Banner.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Agent" xml:space="preserve">
<value>Agent</value>
<data name="HelpRelayMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\HelpRelayMap.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="AMT" xml:space="preserve">
<value>AMT</value>
</data>
<data name="LanguagesChanging" xml:space="preserve">
<value>Changing language will close this tool. Are you sure?</value>
</data>
<data name="Starting" xml:space="preserve">
<value>Starting...</value>
</data>
<data name="UnableToConnect" xml:space="preserve">
<value>Unable to connect</value>
</data>
<data name="CIRA" xml:space="preserve">
<value>CIRA</value>
</data>
<data name="SendTokenEmail" xml:space="preserve">
<value>Send token to registered email address?</value>
</data>
<data name="Agent" xml:space="preserve">
<value>Agent</value>
</data>
<data name="Stopped" xml:space="preserve">
<value>Stopped.</value>
</data>
<data name="MeshCentral" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\MeshCentral.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Offline" xml:space="preserve">
<value>Offline</value>
</data>
<data name="SmsSent" xml:space="preserve">
<value>SMS sent</value>
</data>
<data name="Gear20" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Gear20.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Relay" xml:space="preserve">
<value>Relay</value>
</data>
<data name="xinstall" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\xinstall.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="EmailSent" xml:space="preserve">
<value>Email sent</value>
</data>
<data name="EmailVerificationRequired" xml:space="preserve">
<value>Email verification required</value>
</data>
<data name="InvalidUsernameOrPassword" xml:space="preserve">
<value>Invalid username or password</value>
</data>
<data name="LanguagesChanging" xml:space="preserve">
<value>Changing language will close this tool. Are you sure?</value>
</data>
<data name="LanguagesTitle" xml:space="preserve">
<value>Languages</value>
</data>
<data name="ManyConnections" xml:space="preserve">
<value>, {0} connections.</value>
<data name="SendTokenSMS" xml:space="preserve">
<value>Send token to registered phone number?</value>
</data>
<data name="MeshCentralRouter" xml:space="preserve">
<value>MeshCentral Router</value>
</data>
<data name="MeshCentralTitle" xml:space="preserve">
<value>MeshCentral</value>
</data>
<data name="MQTT" xml:space="preserve">
<value>MQTT</value>
</data>
<data name="Offline" xml:space="preserve">
<value>Offline</value>
</data>
<data name="OneConnection" xml:space="preserve">
<value>, 1 connection.</value>
</data>
<data name="PuttyAppName" xml:space="preserve">
<value>PuTTY SSH client</value>
</data>
<data name="Relay" xml:space="preserve">
<value>Relay</value>
</data>
<data name="SearchPlaceHolder" xml:space="preserve">
<value>Search</value>
</data>
<data name="SendTokenEmail" xml:space="preserve">
<value>Send token to registered email address?</value>
</data>
<data name="SendTokenSMS" xml:space="preserve">
<value>Send token to registered phone number?</value>
</data>
<data name="SmsSent" xml:space="preserve">
<value>SMS sent</value>
</data>
<data name="Starting" xml:space="preserve">
<value>Starting...</value>
</data>
<data name="Stopped" xml:space="preserve">
<value>Stopped.</value>
</data>
<data name="Stopped2" xml:space="preserve">
<value>Stopped</value>
</data>
<data name="ManyConnections" xml:space="preserve">
<value>, {0} connections.</value>
</data>
<data name="icons01" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icons01.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="TwoFactorAuthentication" xml:space="preserve">
<value>Two-factor Authentication</value>
</data>
<data name="MQTT" xml:space="preserve">
<value>MQTT</value>
</data>
<data name="MeshCentralTitle" xml:space="preserve">
<value>MeshCentral</value>
</data>
<data name="LanguagesTitle" xml:space="preserve">
<value>Languages</value>
</data>
<data name="EmptyBanner" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Empty-Banner.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OneConnection" xml:space="preserve">
<value>, 1 connection.</value>
</data>
<data name="UnableToBindToLocalPort" xml:space="preserve">
<value>Unable to bind to local port</value>
</data>
<data name="UnableToConnect" xml:space="preserve">
<value>Unable to connect</value>
<data name="InvalidUsernameOrPassword" xml:space="preserve">
<value>Invalid username or password</value>
</data>
<data name="WinscpAppName" xml:space="preserve">
<value>WinSCP client</value>
<data name="50-Computer" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\50-Computer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
Resources/50-Computer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
Resources/Padlock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
Resources/User.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB