' General note for Vista users: You need to run Visual Studio in elevated (Admin) mode for this project to work. 
Option Strict Off
Option Explicit On
Imports VB = Microsoft.VisualBasic

Friend Class Form1
    Inherits System.Windows.Forms.Form
    ' Create a new VSP Manager object. This is what we'll be using to manipulate the ports.
    Dim VSPMan As New TVSPLib.TVspDeviceManager


    Private Sub Create_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Create.Click
        CreateNewVsp()
    End Sub

    ' If you pass VSP parameters, a new VSP will silenty be created using these parameters. 
    ' Otherwise, a dialog will be shown.
    Private Sub CreateNewVsp(Optional ByRef Parameters As TVSPLib.ITVspParameters = Nothing)

        On Error GoTo ErrorHandler

        VSPMan.CreateDevice(Me.Handle.ToInt32, Parameters)

        Reenumerate_Click(Reenumerate, New System.EventArgs())
        Exit Sub

ErrorHandler:
        If Err.Number = &H800704C7 Then Exit Sub ' ERROR_CANCELLED -- user aborted VSP creation

        MsgBox(Err.Description, MsgBoxStyle.Critical)

    End Sub
    ' Close the dialog when ESC is pressed
    Private Sub Form1_KeyDown(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
        Dim KeyCode As Short = eventArgs.KeyCode
        Dim Shift As Short = eventArgs.KeyData \ &H10000
        If KeyCode = 27 Then Me.Close()
    End Sub
    ' When loading the form, enter some default values into the textboxes, and populate port list.
    Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
        Reenumerate_Click(Reenumerate, New System.EventArgs())
        AddressCtrl.Text = "127.0.0.1:1003"
        PortNameCtrl.Text = "COM3"
    End Sub
    'Returns the interface of the port currently selected in the port list (for removing, configuring, etc.)
    Private Function GetSelectedVsp() As TVSPLib.ITiVirtualDevice
        Dim TreeItem As System.Windows.Forms.TreeNode
        TreeItem = PortListCtrl.SelectedNode
        If TreeItem Is Nothing Then
            GetSelectedVsp = Nothing
            Exit Function
        End If

        GetSelectedVsp = VSPMan.Device(TreeItem.Index)
    End Function

    Private Sub PortListCtrl_DoubleClick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles PortListCtrl.DoubleClick
        Properties_Click(Properties, New System.EventArgs())
    End Sub

    Private Sub Properties_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Properties.Click
        Dim Vsp As TVSPLib.ITiVirtualDevice
        Vsp = GetSelectedVsp()
        If Vsp Is Nothing Then Exit Sub
        Vsp.DoDevicePropertiesDlg(Handle.ToInt32)
    End Sub

    Private Sub Remove_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Remove.Click
        Dim Result As Integer
        Dim Vsp As TVSPLib.ITiVirtualDevice
        Vsp = GetSelectedVsp()
        If Vsp Is Nothing Then Exit Sub

        Result = MsgBox("Remove " & Vsp.FriendlyName & "?", MsgBoxStyle.OkCancel)
        If Result <> MsgBoxResult.Ok Then Exit Sub

        Vsp.DeleteDevice()
        Reenumerate_Click(Reenumerate, New System.EventArgs())
    End Sub

    Private Sub Reenumerate_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Reenumerate.Click
        Dim i As Integer
        Dim PortCount As Integer
        VSPMan.ReenumerateDevices()

        PortListCtrl.Nodes.Clear() ' Remove any existing entries in the list first

        ' Iterate through all ports
        PortCount = VSPMan.DeviceCount
        Dim Vsp As TVSPLib.ITiVirtualDevice
        Dim TreeItem As System.Windows.Forms.TreeNode
        For i = 0 To PortCount - 1
            Vsp = VSPMan.Device(i) ' Select the next port
            TreeItem = PortListCtrl.Nodes.Add(Vsp.FriendlyName) ' Get its friendly name and add to the list.
        Next i
    End Sub
    ' Locate a port by explicit name.
    Function FindPort(ByRef PortName As String) As TVSPLib.ITiVirtualDevice
        Dim i As Integer
        Dim PortCount As Integer

        ' Iterate through all ports and look for the name ("COM3", etc) passed to the function.
        PortCount = VSPMan.DeviceCount
        For i = 0 To PortCount - 1
            Dim Vsp As TVSPLib.ITiVirtualDevice
            Dim Parameters As TVSPLib.ITVspParameters

            Vsp = VSPMan.Device(i)
            Parameters = Vsp.Parameters

            If Parameters.PortName = PortName Then
                FindPort = Vsp
                Exit Function
            End If
        Next i
        FindPort = Nothing
    End Function
    ' Shows how to modify VSP parameters
    Sub SetVspParameters(ByRef Parameters As TVSPLib.ITVspParameters, ByRef PortName As String, ByRef Address As String)
        Dim Colon As Integer
        Dim IpAddress As String
        Dim Port As Short
        Port = 1001

        Colon = InStr(Address, ":")
        If Colon Then
            Port = Val(Mid(Address, Colon + 1))
            IpAddress = VB.Left(Address, Colon - 1)
        Else
            IpAddress = Address
        End If

        Parameters.SetDefaults()

        Parameters.PortName = PortName
        Parameters.OtfMode = TVSPLib.TVSP_OTF_MODE.TVSPOTFM_NONE
        Parameters.TransportProtocol = TVSPLib.TVSP_TRANSPORT_PROTOCOL.TVSPTP_TCP
        Parameters.ConnectionTimeout = 5
        Parameters.RoutingMode = TVSPLib.TVSP_ROUTING_MODE.TVSPRM_CLIENT
        Parameters.ConnectMode = TVSPLib.TVSP_CONNECT_MODE.TVSPCM_CONNECT_IMMEDIATLY
        Parameters.SingleDestination.IpAddress = IpAddress
        Parameters.SingleDestination.Port = Port

        ' use Object Browser (F2) to explore the rest of VSP Parameters

    End Sub
    ' If a certain port exists, this sub configures it. Otherwise, it creates a new VSP.
    Private Sub DirectAccessTest_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles DirectAccessTest.Click
        Dim Vsp As TVSPLib.ITiVirtualDevice
        Dim PortName As String

        PortName = PortNameCtrl.Text

        Vsp = FindPort(PortName)

        If Vsp Is Nothing Then
            ' VSP with given name is not found, create it
            Dim Parameters As New TVSPLib.TVspParameters
            SetVspParameters(Parameters, PortName, (AddressCtrl.Text))
            CreateNewVsp(Parameters)
        Else
            ' modify existing VSP parameters
            SetVspParameters(Vsp.Parameters, PortName, AddressCtrl.Text)
            Vsp.UpdateParameters(True) ' write modifications to registry
        End If
    End Sub
End Class