Imports mRemote.App.Native Imports System.Threading Imports Microsoft.Win32 Imports System.Drawing Imports mRemote.App.Runtime Namespace Connection Namespace Protocol Public Class PuttyBase Inherits Connection.Protocol.Base #Region "Private Properties" Private PuttyProcessStartInfo As New ProcessStartInfo() Private Arguments As String #End Region #Region "Public Properties" Private _PuttyProtocol As Putty_Protocol Public Property PuttyProtocol() As Putty_Protocol Get Return Me._PuttyProtocol End Get Set(ByVal value As Putty_Protocol) Me._PuttyProtocol = value End Set End Property Private _PuttySSHVersion As Putty_SSHVersion Public Property PuttySSHVersion() As Putty_SSHVersion Get Return Me._PuttySSHVersion End Get Set(ByVal value As Putty_SSHVersion) Me._PuttySSHVersion = value End Set End Property Private _PuttyHandle As IntPtr Public Property PuttyHandle() As IntPtr Get Return Me._PuttyHandle End Get Set(ByVal value As IntPtr) Me._PuttyHandle = value End Set End Property Private _PuttyProcess As Process Public Property PuttyProcess() As Process Get Return Me._PuttyProcess End Get Set(ByVal value As Process) Me._PuttyProcess = value End Set End Property Private Shared _PuttyPath As String Public Shared Property PuttyPath() As String Get Return _PuttyPath End Get Set(ByVal value As String) _PuttyPath = value End Set End Property 'Private borderWidth As Integer = frmMain.Size.Width - frmMain.ClientSize.Width 'Private borderHeight As Integer = frmMain.Size.Height - frmMain.ClientSize.Height Private Shared _BorderSize As Size Public Shared Property BorderSize() As Size Get Return _BorderSize End Get Set(ByVal value As Size) _BorderSize = value End Set End Property Public ReadOnly Property Focused() As Boolean Get If GetForegroundWindow() = PuttyHandle Then Return True Else Return False End If End Get End Property #End Region #Region "Private Events & Handlers" Private Sub ProcessExited(ByVal sender As Object, ByVal e As System.EventArgs) MyBase.Event_Closed(Me) End Sub #End Region #Region "Public Methods" Public Sub New() End Sub Public Overrides Function Connect() As Boolean Try PuttyProcessStartInfo.FileName = _PuttyPath Select Case Me._PuttyProtocol Case Putty_Protocol.raw Arguments = "-load " & """" & Me.InterfaceControl.Info.PuttySession & """" & " -" & Me._PuttyProtocol.ToString & " -P " & Me.InterfaceControl.Info.Port & " """ & Me.InterfaceControl.Info.Hostname & """" Case Putty_Protocol.rlogin Arguments = "-load " & """" & Me.InterfaceControl.Info.PuttySession & """" & " -" & Me._PuttyProtocol.ToString & " -P " & Me.InterfaceControl.Info.Port & " """ & Me.InterfaceControl.Info.Hostname & """" Case Putty_Protocol.ssh Dim UserArg As String = "" Dim PassArg As String = "" If My.Settings.EmptyCredentials = "windows" Then UserArg = " -l """ & Environment.UserName & """" ElseIf My.Settings.EmptyCredentials = "custom" Then UserArg = " -l """ & My.Settings.DefaultUsername & """" PassArg = " -pw """ & Security.Crypt.Decrypt(My.Settings.DefaultPassword, App.Info.General.EncryptionKey) & """" End If If Me.InterfaceControl.Info.Username <> "" Then UserArg = " -l """ & Me.InterfaceControl.Info.Username & """" End If If Me.InterfaceControl.Info.Password <> "" Then PassArg = " -pw """ & Me.InterfaceControl.Info.Password & """" End If Arguments = "-load " & """" & Me.InterfaceControl.Info.PuttySession & """" & " -" & Me._PuttyProtocol.ToString & " -" & Me._PuttySSHVersion & UserArg & PassArg & " -P " & Me.InterfaceControl.Info.Port & " """ & Me.InterfaceControl.Info.Hostname & """" Case Putty_Protocol.telnet Arguments = "-load " & """" & Me.InterfaceControl.Info.PuttySession & """" & " -" & Me._PuttyProtocol.ToString & " -P " & Me.InterfaceControl.Info.Port & " """ & Me.InterfaceControl.Info.Hostname & """" Case Putty_Protocol.serial Arguments = "-load " & """" & Me.InterfaceControl.Info.PuttySession & """" & " -" & Me._PuttyProtocol.ToString & " -P " & Me.InterfaceControl.Info.Port & " """ & Me.InterfaceControl.Info.Hostname & """" End Select 'REMOVE IN RELEASE! 'mC.AddMessage(Messages.MessageClass.InformationMsg, "PuTTY Arguments: " & Arguments, True) PuttyProcessStartInfo.Arguments = Arguments PuttyProcess = Process.Start(PuttyProcessStartInfo) PuttyProcess.EnableRaisingEvents = True PuttyProcess.WaitForInputIdle() AddHandler PuttyProcess.Exited, AddressOf ProcessExited Dim TryCount As Integer = 0 Do Until PuttyProcess.MainWindowHandle <> IntPtr.Zero And Me.InterfaceControl.Handle <> IntPtr.Zero And Me.PuttyProcess.MainWindowTitle <> "Default IME" If TryCount >= My.Settings.MaxPuttyWaitTime * 2 Then Exit Do End If PuttyProcess.Refresh() Thread.Sleep(500) TryCount += 1 Loop PuttyHandle = PuttyProcess.MainWindowHandle mC.AddMessage(Messages.MessageClass.InformationMsg, "--- PuTTY Stuff ---", True) mC.AddMessage(Messages.MessageClass.InformationMsg, "PuTTY Handle: " & PuttyHandle.ToString, True) mC.AddMessage(Messages.MessageClass.InformationMsg, "PuTTY Title: " & PuttyProcess.MainWindowTitle, True) mC.AddMessage(Messages.MessageClass.InformationMsg, "Panel Handle: " & Me.InterfaceControl.Parent.Handle.ToString, True) SetParent(Me.PuttyHandle, Me.InterfaceControl.Parent.Handle) SetWindowLong(Me.PuttyHandle, 0, WS_VISIBLE) ShowWindow(Me.PuttyHandle, SW_SHOWMAXIMIZED) Resize() MyBase.Connect() Return True Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't Connect" & vbNewLine & ex.Message) Return False End Try End Function Public Overrides Sub Focus() Try SetForegroundWindow(PuttyHandle) Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't Focus (Connection.Protocol.PuttyBase)" & vbNewLine & ex.Message, True) End Try End Sub Public Overrides Sub Resize() Try MoveWindow(PuttyHandle, -SystemInformation.FrameBorderSize.Width, -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height), Me.InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width * 2), Me.InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height * 2), True) Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't Resize (Connection.Protocol.PuttyBase)" & vbNewLine & ex.Message, True) End Try End Sub Public Overrides Sub Close() Try If PuttyProcess.HasExited = False Then PuttyProcess.Kill() End If Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Killing Putty Process failed (Connection.Protocol.PuttyBase)" & vbNewLine & ex.Message, True) End Try Try PuttyProcess.Dispose() Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Dispose of Putty process failed (Connection.Protocol.PuttyBase)" & vbNewLine & ex.Message, True) End Try MyBase.Close() End Sub #End Region #Region "Public Shared Methods" Public Shared Function GetSessions() As Array Try Dim regKey As RegistryKey regKey = Registry.CurrentUser.OpenSubKey("Software\SimonTatham\PuTTY\Sessions") Dim arrKeys() As String arrKeys = regKey.GetSubKeyNames() Array.Resize(arrKeys, arrKeys.Length + 1) arrKeys(arrKeys.Length - 1) = "Default Settings" For i As Integer = 0 To arrKeys.Length - 1 arrKeys(i) = System.Web.HttpUtility.UrlDecode(arrKeys(i)) Next Return arrKeys Catch ex As Exception App.Runtime.mC.AddMessage(Messages.MessageClass.WarningMsg, "Couldn't get Putty sessions" & vbNewLine & ex.Message, True) Return Nothing End Try End Function Public Shared Sub StartPutty() Try Dim p As Process Dim pSI As New ProcessStartInfo pSI.FileName = PuttyPath p = Process.Start(pSI) p.WaitForExit() mRemote.Connection.PuttySession.PuttySessions = GetSessions() Catch ex As Exception mC.AddMessage(Messages.MessageClass.ErrorMsg, "Couldn't Start Putty (Connection.Protocol.PuttyBase)" & vbNewLine & ex.Message, True) End Try End Sub #End Region #Region "Enums" Public Enum Putty_Protocol ssh = 0 telnet = 1 rlogin = 2 raw = 3 serial = 4 End Enum Public Enum Putty_SSHVersion ssh1 = 1 ssh2 = 2 End Enum #End Region End Class End Namespace End Namespace