Modem Configuration after creating direct serial connection

Dec 14, 2009 at 2:22 AM

Hi

I am creating a PPP over serial connection for communication with some custom hardware.

I can successfully create the connection manually in windows and also using RasEntry.CreateVpnEntry. However, when I create it using CreateVpnEntry, the Modem Configuration always has "Enable hardware flow control" checked. Creating it manually leaves this unchecked which obeys the modems Default Preferences setting. Can DotRas set these properties? It appears to be ignoring the default setting for the modem.

 

 

Coordinator
Dec 14, 2009 at 1:56 PM
Edited Dec 14, 2009 at 2:01 PM

It sure can!

Those static methods on RasEntry are really just helper methods to generate default connections in Windows when you don't set any options. If you want control over the entire entry when creating one, just call the constructor on the object and feed the information that you want into it. The project can't read hardware directly, that's a whole other area of RAS that I haven't had time to implement yet.

The easiest way I've found to determine exactly what options to set (because there are a lot of them) was to create the connection in Windows which I know works, and then opening up that entry in a RasPhoneBook and copying all the properties that were set by Windows and replicating those settings in code when creating the entry.

Edit: I thought I'd give a code example as well:

RasPhoneBook pbk = new RasPhoneBook();
pbk.Open();

RasEntry entry = pbk.Entries["Some Connection"];

// This is the point where you'd look at the entry and see exactly what needs to be set 
// programmatically to ensure your connection works. This bit of code would need to be
// removed once you've finished copying them down on paper, or wherever you like.

RasEntry entry = new RasEntry("VPN Connection");

// Now the property settings you saw earlier you can set here to ensure your entry works
// as you expected it to.

pbk.Entries.Add(entry);
Dec 14, 2009 at 10:05 PM

Hi Jeff

I have had a close look at all the RasEntry properties of an existing, working, connection but none seem to be related to the the modem configuration settings. I have cross checked them with my newly created (CreateVpnEntry) connection but can see no obvious differences...

The constructor for RasEntry has only one parameter, the name. I'm not sure which constructors you are referring to above.

This is my test code:

	Dim phonebook As New RasPhoneBook
        phonebook.Open()

        Dim entry As RasEntry = RasEntry.CreateVpnEntry("DotRasConn", "169.254.179.13", RasVpnStrategy.Default, RasDevice.GetDevicesByType("modem")(0))
        If Not phonebook.Entries.Contains(entry.Name) Then
            entry.IPAddress = New IPAddress(IPAddress.Parse("192.168.1.200").GetAddressBytes)
            entry.DnsAddress = New IPAddress(IPAddress.Parse("192.168.1.3").GetAddressBytes)
            entry.Options = RasEntryOptions.SpecificIPAddress Or RasEntryOptions.SpecificNameServers Or RasEntryOptions.ShowDialingProgress
            phonebook.Entries.Add(entry)
        End If

I was hoping for a method or property like 'entry.SetModemCommSettings' or  'entry.UseModemDefaults', something easy like that :-)

 

Thanks

 

 

 

Dim phonebook As New RasPhoneBook
        phonebook.Open()
        Dim entry As RasEntry = RasEntry.CreateVpnEntry("DotRasConn", "169.254.179.13", RasVpnStrategy.Default, RasDevice.GetDevicesByType("modem")(0))
        If Not phonebook.Entries.Contains(entry.Name) Then
            entry.IPAddress = New IPAddress(IPAddress.Parse("192.168.1.200").GetAddressBytes)
            entry.DnsAddress = New IPAddress(IPAddress.Parse("192.168.1.3").GetAddressBytes)
            entry.Options = RasEntryOptions.SpecificIPAddress Or RasEntryOptions.SpecificNameServers Or RasEntryOptions.ShowDialingProgress
            phonebook.Entries.Add(entry)
        End Dim phonebook As New RasPhoneBook
        phonebook.Open()
        Dim entry As RasEntry = RasEntry.CreateVpnEntry("DotRasConn", "169.254.179.13", RasVpnStrategy.Default, RasDevice.GetDevicesByType("modem")(0))
        If Not phonebook.Entries.Contains(entry.Name) Then
            entry.IPAddress = New IPAddress(IPAddress.Parse("192.168.1.200").GetAddressBytes)
            entry.DnsAddress = New IPAddress(IPAddress.Parse("192.168.1.3").GetAddressBytes)
            entry.Options = RasEntryOptions.SpecificIPAddress Or RasEntryOptions.SpecificNameServers Or RasEntryOptions.ShowDialingProgress
            phonebook.Entries.Add(entry)
        End If

 

Coordinator
Dec 15, 2009 at 12:54 AM

Sorry, I was a bit vague on the constructor comment. Yes, there's only a single constructor available which takes a name since that's the only required setting on the entry.

I don't know off hand what the answer is to your question on translating it to the project. All I can really suggest is google how to disable the flag through RAS, if it's even possible. It could be getting set by TAPI which I don't have implemented in this project.

If you find out how to do it let me know, I'd like to get it into the documentation somewhere.

Dec 15, 2009 at 4:20 AM

Jeff

I will certainly keep looking into it, and will let you know if I discover anything more.

I do have another option with this which is to loopback the handshaking lines on the null modem cable, then the flow control setting can be left at 'Hardware'.

 

Thanks anyway...

 

 

Coordinator
Dec 15, 2009 at 1:47 PM

Just a helpful hint, the IPAddress.Parse method returns an IPAddress object directly so you don't need to call GetAddressBytes and pass that into the constructor for the object.

entry.IPAddress = IPAddress.Parse("192.168.1.200")

That will work just fine. :)

 

Good luck on your search!

Feb 23, 2010 at 3:42 AM

Jeff,

Sorry to drag an old issue up again but I have come up with a solution to this issue you may be interested in. After investigating the rasapi32.dll, TAPI, modifying the comport DCB on the fly, without success, I eventually worked out that I can edit the ras phonebook file directly. A bit of a workaround solution but it seems to work.

The format of the file is the same as a standard .ini file so I created the class below. I edit the phonebook just after I create the new connection.

 

 

Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Text
''' <summary>
''' This class provides a means to directly edit the RAS Phonebook file. 
''' NOTE: Direct editing of the phonebook is not recommended, the rasapi32.dll or DotRas.dll should be used. However, some
''' settings such as the Modem Configuration settings cannot be changed programatically any other way.
''' </summary>
''' <remarks>
''' Format of the phonebook file is the same as a standard .ini file so the win32 api function for .ini files are used
''' </remarks>
Public Class PhonebookFileEditor
    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Shared Function WritePrivateProfileString( _
                ByVal lpApplicationName As String, _
                ByVal lpKeyName As String, _
                ByVal lpString As String, _
                ByVal lpFileName As String) As Int32
    End Function
    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Shared Function GetPrivateProfileString( _
                ByVal lpApplicationName As String, _
                ByVal lpKeyName As String, _
                ByVal lpDefault As String, _
                ByVal lpReturnedString As StringBuilder, _
                ByVal nSize As Int32, _
                ByVal lpFileName As String) As Int32
    End Function
    Private Const DEFAULT_VALUE As String = "N/A"
    Private mErrorInfo As Exception
    Private mPhonebookPath As String
    Private mDefaultValue As String
    Public Function GetErrorInfo() As Exception
        Return mErrorInfo
    End Function
    Public Property PhonebookPath() As String
        Get
            Return mPhonebookPath
        End Get
        Set(ByVal value As String)
            mPhonebookPath = value
        End Set
    End Property
    Public Property DefaultValue() As String
        Get
            Return mDefaultValue
        End Get
        Set(ByVal value As String)
            mDefaultValue = value
        End Set
    End Property
    Public Sub New(ByVal pbkPath As String)
        mPhonebookPath = pbkPath
        mDefaultValue = DEFAULT_VALUE
    End Sub
    Public Enum SettingKey
        Encoding
        Type
        AutoLogon
        UseRasCredentials
        DialParamsUID
        Guid
        BaseProtocol
        VpnStrategy
        ExcludedProtocols
        LcpExtensions
        DataEncryption
        SwCompression
        NegotiateMultilinkAlways
        SkipNwcWarning
        SkipDownLevelDialog
        SkipDoubleDialDialog
        DialMode
        DialPercent
        DialSeconds
        HangUpPercent
        HangUpSeconds
        OverridePref
        RedialAttempts
        RedialSeconds
        IdleDisconnectSeconds
        RedialOnLinkFailure
        CallbackMode
        CustomDialDll
        CustomDialFunc
        CustomRasDialDll
        AuthenticateServer
        ShareMsFilePrint
        BindMsNetClient
        SharedPhoneNumbers
        GlobalDeviceSettings
        PrerequisiteEntry
        PrerequisitePbk
        PreferredPort
        PreferredDevice
        PreferredBps
        PreferredHwFlow
        PreferredProtocol
        PreferredCompression
        PreferredSpeaker
        PreferredMdmProtocol
        PreviewUserPw
        PreviewDomain
        PreviewPhoneNumber
        ShowDialingProgress
        ShowMonitorIconInTaskBar
        CustomAuthKey
        AuthRestrictions
        TypicalAuth
        IpPrioritizeRemote
        IpHeaderCompression
        IpAddress
        IpDnsAddress
        IpDns2Address
        IpWinsAddress
        IpWins2Address
        IpAssign
        IpNameAssign
        IpFrameSize
        IpDnsFlags
        IpNBTFlags
        TcpWindowSize
        UseFlags
        IpSecFlags
        IpDnsSuffix
        ms_msclient
        ms_server
        Port
        Device
        ConnectBPS
        PhoneNumber
        AreaCode
        CountryCode
        CountryID
        UseDialingRules
        Comment
        LastSelectedPhone
        PromoteAlternates
        TryNextAlternateOnFail
        HwFlowControl
        Protocol
        Compression
        Speaker
        MdmProtocol
    End Enum
    ''' <summary>
    ''' Retreives the value of the setting for the connectionName contained in the RAS Phonebook 
    ''' specified by the PhoneBookPath property.
    ''' </summary>
    ''' <param name="connectionName"></param>
    ''' <param name="settingName"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' Strings returned from unmanaged win32 functions are 'non-blittable', hence the use of a StringBuilder for
    ''' the lpReturnedString parameter.
    ''' </remarks>
    Public Function GetPhonebookSetting(ByVal connectionName As String, ByVal settingName As SettingKey) As String
        Try
            Dim buffer As New StringBuilder(255)
            Dim settingStr As String = [Enum].GetName(GetType(SettingKey), settingName)
            Dim returnStringSize As Int32 = GetPrivateProfileString(connectionName, settingStr, mDefaultValue, buffer, buffer.Capacity, mPhonebookPath)
            If returnStringSize > 0 Then
                Return buffer.ToString
            Else
                Return mDefaultValue
            End If
        Catch ex As Exception
            mErrorInfo = ex
            Return mDefaultValue
        End Try
    End Function
    ''' <summary>
    ''' Sets the value of the setting for the connectionName contained in the RAS Phonebook 
    ''' specified by the PhoneBookPath property.
    ''' </summary>
    ''' <param name="connectionName"></param>
    ''' <param name="settingName"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetPhonebookSetting(ByVal connectionName As String, ByVal settingName As SettingKey, ByVal value As String) As Boolean
        Try
            Dim retval As Integer
            Dim settingStr As String = [Enum].GetName(GetType(SettingKey), settingName)
            retval = WritePrivateProfileString(connectionName, settingStr, value, mPhonebookPath)
            If retval > 0 Then
                Return True
            Else
                Throw New Win32Exception(Marshal.GetLastWin32Error())
            End If
        Catch ex As Exception
            mErrorInfo = ex
            Return False
        End Try
    End Function
End Class

Imports System.Runtime.InteropServices

Imports System.ComponentModel

Imports System.Text

 

Public Class PhonebookFileEditor

 

    <DllImport("kernel32.dll", SetLastError:=True)> _

    Private Shared Function WritePrivateProfileString( _

                ByVal lpApplicationName As String, _

                ByVal lpKeyName As String, _

                ByVal lpString As String, _

                ByVal lpFileName As String) As Int32

    End Function

 

    <DllImport("kernel32.dll", SetLastError:=True)> _

    Private Shared Function GetPrivateProfileString( _

                ByVal lpApplicationName As String, _

                ByVal lpKeyName As String, _

                ByVal lpDefault As String, _

                ByVal lpReturnedString As StringBuilder, _

                ByVal nSize As Int32, _

                ByVal lpFileName As String) As Int32

    End Function

 

    Private Const DEFAULT_VALUE As String = "N/A"

 

    Private mErrorInfo As Exception

    Private mPhonebookPath As String

    Private mDefaultValue As String

 

    Public Function GetErrorInfo() As Exception

        Return mErrorInfo

    End Function

 

    Public Property PhonebookPath() As String

        Get

            Return mPhonebookPath

        End Get

        Set(ByVal value As String)

            mPhonebookPath = value

        End Set

    End Property

 

    Public Property DefaultValue() As String

        Get

            Return mDefaultValue

        End Get

        Set(ByVal value As String)

            mDefaultValue = value

        End Set

    End Property

 

    Public Sub New(ByVal pbkPath As String)

        mPhonebookPath = pbkPath

        mDefaultValue = DEFAULT_VALUE

    End Sub

 

 

    Public Enum SettingKey

        Encoding

        Type

        AutoLogon

        UseRasCredentials

        DialParamsUID

        Guid

        BaseProtocol

        VpnStrategy

        ExcludedProtocols

        LcpExtensions

        DataEncryption

        SwCompression

        NegotiateMultilinkAlways

        SkipNwcWarning

        SkipDownLevelDialog

        SkipDoubleDialDialog

        DialMode

        DialPercent

        DialSeconds

        HangUpPercent

        HangUpSeconds

        OverridePref

        RedialAttempts

        RedialSeconds

        IdleDisconnectSeconds

        RedialOnLinkFailure

        CallbackMode

        CustomDialDll

        CustomDialFunc

        CustomRasDialDll

        AuthenticateServer

        ShareMsFilePrint

        BindMsNetClient

        SharedPhoneNumbers

        GlobalDeviceSettings

        PrerequisiteEntry

        PrerequisitePbk

        PreferredPort

        PreferredDevice

        PreferredBps

        PreferredHwFlow

        PreferredProtocol

        PreferredCompression

        PreferredSpeaker

        PreferredMdmProtocol

        PreviewUserPw

        PreviewDomain

        PreviewPhoneNumber

        ShowDialingProgress

        ShowMonitorIconInTaskBar

        CustomAuthKey

        AuthRestrictions

        TypicalAuth

        IpPrioritizeRemote

        IpHeaderCompression

        IpAddress

        IpDnsAddress

        IpDns2Address

        IpWinsAddress

        IpWins2Address

        IpAssign

        IpNameAssign

        IpFrameSize

        IpDnsFlags

        IpNBTFlags

        TcpWindowSize

        UseFlags

        IpSecFlags

        IpDnsSuffix

        ms_msclient

        ms_server

        Port

        Device

        ConnectBPS

        PhoneNumber

        AreaCode

        CountryCode

        CountryID

        UseDialingRules

        Comment

        LastSelectedPhone

        PromoteAlternates

        TryNextAlternateOnFail

        HwFlowControl

        Protocol

        Compression

        Speaker

        MdmProtocol

    End Enum

 

    Public Function GetPhonebookSetting(ByVal connectionName As String, ByVal settingName As SettingKey) As String

        Try

            Dim buffer As New StringBuilder(255)

            Dim settingStr As String = [Enum].GetName(GetType(SettingKey), settingName)

            Dim returnStringSize As Int32 = GetPrivateProfileString(connectionName, settingStr, mDefaultValue, buffer, buffer.Capacity, mPhonebookPath)

            If returnStringSize > 0 Then

                Return buffer.ToString

            Else

                Return mDefaultValue

            End If

        Catch ex As Exception

            mErrorInfo = ex

            Return mDefaultValue

        End Try

    End Function

 

 

    Public Function SetPhonebookSetting(ByVal connectionName As String, ByVal settingName As SettingKey, ByVal value As String) As Boolean

        Try

            Dim retval As Integer

            Dim settingStr As String = [Enum].GetName(GetType(SettingKey), settingName)

            retval = WritePrivateProfileString(connectionName, settingStr, value, mPhonebookPath)

            If retval > 0 Then

                Return True

            Else

                Throw New Win32Exception(Marshal.GetLastWin32Error())

            End If

        Catch ex As Exception

            mErrorInfo = ex

            Return False

        End Try

 

    End Function

 

 

End Class

 

 

 

Coordinator
Feb 23, 2010 at 1:48 PM

Thanks but I won't be adding code into the project that bypasses the RAS api and begin modifying the files directly. If the implementation changes I'll have to keep track of it myself to ensure the project continues to work on all the operating systems and platforms supported.