API и Unicode

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

ism
Постоялец
Постоялец
 
Сообщения: 337
Зарегистрирован: 12.12.2001 (Ср) 12:59
Откуда: Russia, Saint-Petersburg

API и Unicode

Сообщение ism » 17.04.2007 (Вт) 12:19

Вобщем порблема нерешаемая, был код на VB6. Паботал прекрасно, переделал под .NET ерунда.
Код в зависемости от заданных кодировок создает либо соединение с идеально правильными параметрами, которое незапускается т.к. невозможно найти адресную книгу. Либо нормально запускающееся соединение, но с кривыми параметрами. В VB6 никаких проблем небыло. Что делать?

Код: Выделить всё
Imports System.Runtime.InteropServices
Imports System.Text

Public Class RAS

    Public Structure RASIPADDR
        Dim a As Byte
        Dim b As Byte
        Dim c As Byte
        Dim d As Byte
    End Structure

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode )> _
    Public Structure RASENTRY
        Public dwSize As Integer
        Public Options As Integer
        Public CountryID As Integer
        Public CountryCode As Integer
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=10 + 1)> Public AreaCode As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=128 + 1)> Public LocalPhoneNumber As String
        Public dwAlternateOffset As Integer
        Public ipAddr As RASIPADDR
        Public ipAddrDns As RASIPADDR
        Public ipAddrDnsAlt As RASIPADDR
        Public ipAddrWins As RASIPADDR
        Public ipAddrWinsAlt As RASIPADDR
        Public FrameSize As Integer
        Public fNetProtocols As Integer 'RASNetProtocols
        Public FramingProtocol As Integer 'RasFramingProtocols
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public ScriptName As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public AutodialDll As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public AutodialFunc As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=16 + 1)> Public DeviceType As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=128 + 1)> Public DeviceName As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32 + 1)> Public X25PadType As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25Address As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25Facilities As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25UserData As String
        Public Channels As Integer
        Public dwReserved1 As Integer
        Public dwReserved2 As Integer
        Public NT4En_SubEntries As Integer
        Public NT4En_DialMode As Integer
        Public NT4En_DialExtraPercent As Integer
        Public NT4En_DialExtraSampleSeconds As Integer
        Public NT4En_HangUpExtraPercent As Integer
        Public NT4En_HangUpExtraSampleSeconds As Integer
        Public NT4En_IdleDisconnectSeconds As Integer
        Public Win2000_Type As Integer
        Public Win2000_EncryptionType As Integer
        Public Win2000_CustomAuthKey As Integer
        Public Win2000_guidId() As Guid
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public Win2000_CustomDialDll As String
        Public Win2000_VpnStrategy As Integer
    End Structure

    '<DllImport("rasapi32.dll", CharSet:=CharSet.Auto)> _
    'Private Shared Function RasSetEntryProperties(ByVal lpszPhonebook As _
    'String, _
    'ByVal lpszEntry As String, _
    'ByVal lpRasEntry As IntPtr, _
    'ByRef lpdwEntryInfoSize As Integer, _
    'ByVal lpbDeviceInfo As Integer, ByVal _
    'lpdwDeviceInfoSize As Integer) As Integer
    'End Function

    Public Declare Function RasSetEntryProperties _
          Lib "rasapi32.dll" Alias "RasSetEntryPropertiesW" _
            (ByVal lpszPhonebook As String, _
            ByVal lpszEntry As String, _
    ByVal lpRasEntry As IntPtr, _
            ByRef dwEntryInfoSize As Integer, _
    ByVal lpbDeviceInfo As Integer, _
            ByVal dwDeviceInfoSize As Integer) As Integer


    'Public Declare Function RasSetEntryProperties _
    '          Lib "rasapi32.dll" Alias "RasSetEntryPropertiesW" _
    '            (ByVal lpszPhonebook As Integer, _
    '            ByVal lpszEntry As String, _
    '    ByVal lpRasEntry As IntPtr, _
    '            ByRef dwEntryInfoSize As Integer, _
    '    ByVal lpbDeviceInfo As Integer, _
    '            ByVal dwDeviceInfoSize As Integer) As Integer


    '<DllImport("rasapi32.dll", CharSet:=CharSet.Auto)> _
    'Private Shared Function RasSetEntryProperties(ByVal lpszPhonebook As String, _
    'ByVal lpszEntry As String, _
    'ByVal lpRasEntry As Integer, _
    'ByRef lpdwEntryInfoSize As Integer, _
    'ByVal lpbDeviceInfo As Integer, _
    'ByVal lpdwDeviceInfoSize As Integer) As Integer
    'End Function


    'Public Declare Function RasSetEntryProperties _
    '      Lib "rasapi32.dll" Alias "RasSetEntryPropertiesW" _
    '        (ByVal lpszPhonebook As String, _
    '        ByVal lpszEntry As String, _
    'ByVal lpRasEntry As Integer, _
    '        ByRef dwEntryInfoSize As Integer, _
    'ByVal lpbDeviceInfo As Integer, _
    '        ByVal dwDeviceInfoSize As Integer) As Integer



    Public Declare Function RasGetErrorString Lib "rasapi32.dll" Alias "RasGetErrorStringA" (ByVal uErrorValue As Integer, ByVal lpszErrorString As String, ByRef cBufSize As Integer) As Integer
    Public Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Integer, ByVal lpSource As Integer, ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByVal lpBuffer As String, ByVal nSize As Integer, ByRef Arguments As Integer) As Integer



    Public Function SetRASEntryDialProperities( _
    ByVal strEntryName As String, ByRef stRasEntry As RASENTRY) As Integer

        Dim re As New RASENTRY
        Dim res As Integer
        Dim buff As IntPtr
        Dim s As String
        Dim sp As String

        s = strEntryName

        Dim structsize As Integer = Marshal.SizeOf(GetType(RASENTRY))
        Dim bufsize As Integer = structsize

        Dim bufptr As IntPtr
   
        res = RasGetEntryProperties(vbNullString, vbNullString, 0&, structsize, 0&, 0&)
        If res <> 603 Then Return res

        bufptr = Marshal.AllocHGlobal(bufsize)

        Marshal.StructureToPtr(stRasEntry, bufptr, True)


        Marshal.WriteInt32(bufptr, structsize)

        res = RasSetEntryProperties(Nothing, s, bufptr, bufsize, 0&, 0&)

        Return res
errHdl:
        MsgBox(Err.Description)
    End Function

    Public Function RASErrorHandler(ByRef rtn As Integer) As String
        Dim strError As String
        Dim i As Integer
        strError = New String(Chr(0), 512)
        If rtn > 600 Then
            RasGetErrorString(rtn, strError, 512)
        Else
            FormatMessage(&H1000S, 0, rtn, 0, strError, 512, 0)
        End If
        i = InStr(strError, Chr(0))
        If i > 1 Then RASErrorHandler = Left(strError, i - 1)
    End Function

End Class

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.04.2007 (Вт) 13:14

Странный код.

Ты путаешь предназначения RASENTRY.dwSize и dwEntryInfoSize. Причём сильно. Не мешает изучить азы, а то непонятно, почему это вообще работало на VB6. Если работало, то случайно, а вообще это buffer overrun.

Если ты не устанавливаешь дополнительные номера дозвона (а ты их не устанавливаешь), то dwSize для тебя = dwEntryInfoSize. А весь код процедуры сокращается до
Код: Выделить всё
  Public Function SetRASEntryDialProperities( _
    ByVal strEntryName As String, ByRef stRasEntry As RASENTRY) As Integer

    Return RasSetEntryProperties(Nothing, strEntryName, stRasEntry, stRasEntry.dwSize, 0, 0)
  End Function

Разумеется, определения тоже надо привести в норму.
Код: Выделить всё
  <StructLayout(LayoutKind.Sequential, pack:=1)> _
  Public Structure RASIPADDR
    Dim a As Byte
    Dim b As Byte
    Dim c As Byte
    Dim d As Byte
  End Structure

  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto, pack:=1)> _
  Public Structure RASENTRY
    Public dwSize As Integer
    Public Options As Integer
    Public CountryID As Integer
    Public CountryCode As Integer
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=10 + 1)> Public AreaCode As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=128 + 1)> Public LocalPhoneNumber As String
    Public dwAlternateOffset As Integer
    Public ipAddr As RASIPADDR
    Public ipAddrDns As RASIPADDR
    Public ipAddrDnsAlt As RASIPADDR
    Public ipAddrWins As RASIPADDR
    Public ipAddrWinsAlt As RASIPADDR
    Public FrameSize As Integer
    Public fNetProtocols As Integer 'RASNetProtocols
    Public FramingProtocol As Integer 'RasFramingProtocols
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public ScriptName As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public AutodialDll As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public AutodialFunc As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=16 + 1)> Public DeviceType As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=128 + 1)> Public DeviceName As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=32 + 1)> Public X25PadType As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25Address As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25Facilities As String
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=200 + 1)> Public X25UserData As String
    Public Channels As Integer
    Public dwReserved1 As Integer
    Public dwReserved2 As Integer
    Public NT4En_SubEntries As Integer
    Public NT4En_DialMode As Integer
    Public NT4En_DialExtraPercent As Integer
    Public NT4En_DialExtraSampleSeconds As Integer
    Public NT4En_HangUpExtraPercent As Integer
    Public NT4En_HangUpExtraSampleSeconds As Integer
    Public NT4En_IdleDisconnectSeconds As Integer
    Public Win2000_Type As Integer
    Public Win2000_EncryptionType As Integer
    Public Win2000_CustomAuthKey As Integer
    <MarshalAs(UnmanagedType.Struct)> Public Win2000_guidId As Guid
    <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=260)> Public Win2000_CustomDialDll As String
    Public Win2000_VpnStrategy As Integer
  End Structure

  Public Declare Auto Function RasSetEntryProperties Lib "rasapi32.dll" _
         (ByVal lpszPhonebook As String, _
          ByVal lpszEntry As String, _
          <[In](), Out()> ByRef lpRasEntry As RASENTRY, _
          ByRef dwEntryInfoSize As Integer, _
          ByVal lpbDeviceInfo As Integer, _
          ByVal dwDeviceInfoSize As Integer) _
  As Integer
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

ism
Постоялец
Постоялец
 
Сообщения: 337
Зарегистрирован: 12.12.2001 (Ср) 12:59
Откуда: Russia, Saint-Petersburg

Сообщение ism » 17.04.2007 (Вт) 17:09

Насчет азов .NET приpзнаю :oops:

Но в моем случае необходимо создавать соединение в всех ОС, а для них размеры структуры разные. Его и предусмотрено

Код: Выделить всё
res = RasGetEntryProperties(Nothing, Nothing, 0, structsize, 0, 0)
        If res <> 603 Then Return res
        'и далее все зависемости от разменра


Код на VB6 предусматривал все, а код выше неработает ни прикакой длинне

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.04.2007 (Вт) 17:18

ism, я не про азы .net, я про вообще.

RasGetEntryProperties возвращает размер буфера, равный размеру структуры плюс размер дополнительных номеров дозвона.

Размер структуры - константа для каждой версии windows, и для каждой ты должен знать и указывать её сам.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 39

    TopList