Solved

How do I call GetPerAdapterInfo from Visual Basic 6

Posted on 2009-04-15
2
565 Views
Last Modified: 2012-05-06
I have some experience with Visual Basic 6 and a good amount of experience with C/C++ .  I have been trying to get some basic Network Adapter information (the code has to be VB6), and I have gotten some of the way there.  

However I have spent many hours on this and I still cannot call the function GetPerAdapterInfo.  
I have managed to call the function GetAdaptersInfo which is very similar however I still cannot call GetPerAdapterInfo. Every time I call the function GetPerAdapterInfo I get a 232 error (ERROR_NO_DATA).  This happens the first time I call the function with a buffer length of 0.

I have passed in the indices from IP_ADAPTER_INFO and I have also entered these indices manually but I always get the same 232 error.  The indices for my network adapters are 2-4.  I have written the equivalent code in c++ with indices 2-4 and it works flawlessly.  However I have no idea what could be wrong with the vb6 code.

The very first call to GetPerAdapterInfo to get the correct buffer size fails with error 232.  I have looked at the sizes of the various structures such as IP_ADAPTER_INFO and they are exactly the same size as in my C++ code.

Any help/suggestions would be very appreciated.
Private Declare Function GetNetworkParams Lib "IPHlpApi.dll" _

       (FixedInfo As Any, pOutBufLen As Long) As Long

Private Declare Function GetAdaptersInfo Lib "IPHlpApi.dll" _

       (IpAdapterInfo As Any, pOutBufLen As Long) As Long

Private Declare Function GetPerAdapterInfo Lib "IPHlpApi.dll" _

       (IfIndex As Long, pPerAdapterInfo As Any, pOutBufLen As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _

       (Destination As Any, Source As Any, ByVal Length As Long)
 

Private Type IP_ADDR_STRING

            Next As Long

            IpAddress As String * 16

            IpMask As String * 16

            Context As Long

End Type
 

Private Type IP_PER_ADAPTER_INFO

            AutoconfigEnabled As Long

            AutoconfigActive As Long

            CurrentDnsServer As Long

            DnsServerList As IP_ADDR_STRING

End Type
 

Private Type IP_ADAPTER_INFO

            Next As Long

            ComboIndex As Long

            AdapterName As String * MAX_ADAPTER_NAME_LENGTH

            Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH

            AddressLength As Long

            Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte

            Index As Long

            Type As Long

            DhcpEnabled As Long

            CurrentIpAddress As Long

            IpAddressList As IP_ADDR_STRING

            GatewayList As IP_ADDR_STRING

            DhcpServer As IP_ADDR_STRING

            HaveWins As Long

            PrimaryWinsServer As IP_ADDR_STRING

            SecondaryWinsServer As IP_ADDR_STRING

            LeaseObtained As Long

            LeaseExpires As Long

End Type
 

Public Function HasDNS(Index As Long) As Boolean

    Dim error As Long

    Dim DNSInfoBuffer() As Byte

    Dim DNSInfoSize As Long

    Dim DNSInfo As IP_PER_ADAPTER_INFO

    Dim NumStructs As Integer

    Dim DNSInfoPtr As Long

    Dim CurrDNSString As String

    Dim i As Integer

    

    DNSInfoSize = 0

    error = GetPerAdapterInfo(Index, ByVal 0&, DNSInfoSize)

    If error <> 0 Then

        If error <> ERROR_BUFFER_OVERFLOW Then

           HasDNS = False

           Exit Function

        End If

    End If

    ReDim DNSInfoBuffer(DNSInfoSize - 1)
 

    error = GetPerAdapterInfo(Index, DNSInfoBuffer(0), DNSInfoSize)

    If error <> 0 Then

       HasDNS = False

       Exit Function

    End If

   

    NumStructs = DNSInfoSize / Len(DNSInfo)

    DNSInfoPtr = VarPtr(DNSInfoBuffer(0))
 

    If (DNSInfoPtr = 0) Then

       HasDNS = False

       Exit Function

    End If
 

    CopyMemory DNSInfo, ByVal DNSInfoPtr, Len(DNSInfo)

        

    CurrDNSString = ZTrim(DNSInfo.DnsServerList.IpAddress)

    

    If (LenB(CurrDNSString) <> 0) Then

        HasDNS = True

    Else

        HasDNS = False

    End If

End Function

Open in new window

0
Comment
Question by:limemac85
2 Comments
 
LVL 16

Accepted Solution

by:
HooKooDooKu earned 500 total points
Comment Utility
In VB6, unless a function parameter is specifically declared with ByVal, then ByRef is assumed and every parameter gets passed as a pointer.  That means in your declaration for GetPerAdapterInfo, it thinks all three parameters are pointers.

But programmer experience and instinct tell me that the 1st parameter is likely supposed to be the index VALUE rather than a pointer to the index variable.

If so, then you need to change the declaration for the function like this...

Private Declare Function GetPerAdapterInfo Lib "IPHlpApi.dll" _
(ByVal IfIndex As Long, ByRef pPerAdapterInfo As Any, ByRef pOutBufLen As Long) As Long

Note that the two ByRef are not required (because without ByVal, ByRef is assumed).  But I like to include it went calling Lib functions to help make it obvious where values are needed and where pointers are needed.
0
 

Author Closing Comment

by:limemac85
Comment Utility
Thank you ! That was it.  I did not even realize the index was being passed by reference instead of by value.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now