2010-02-06 96 views
4

我知道如何从IPv4网络使用GetHostByAddr的Windows API调用(this的伟大工程)查找主机名在VB。但是,该功能不允许指定要使用的DNS服务器。有时默认的公司DNS服务器是好的,但有时候我需要指定一个外部的DNS服务器来查找,我不认为在这里,做一个shell nslookup和解析输出是最好的方法。VB6查找主机在IP,指定DNS服务器

注:这实际上是将要使用的VBA代码在Excel工作簿,以帮助别人做他的工作,而当一些简单的功能,他就满足它不值得写一个大的应用程序。

想法我可能在API调用getnameinfo中找到答案,但仔细阅读似乎表明它不提供servername参数。

经过一番激烈的搜索,我发现reference to the pExtra parameter to the DNSQuery function。但我甚至不知道如何开始在VB6中使用它。

谁能帮我在从VB6做DNS查找,指定要使用的服务器名什么办法?当然

一个完整的可行的解决方案将是不错,但我愿意努力工作:只是点我朝着正确的方向发展。

更新:对于一些奇怪的原因,它并没有点击DNSQuery是Windows API调用。它听起来不像一个。如果我收集了一个细节,我当然可以在这个问题上取得更大的进展。

回答

4

试试这个:

Option Explicit 

Private Declare Function DnsQuery Lib "dnsapi" Alias "DnsQuery_A" (ByVal strname As String, ByVal wType As Integer, ByVal fOptions As Long, ByVal pServers As Long, ppQueryResultsSet As Long, ByVal pReserved As Long) As Long 
Private Declare Function DnsRecordListFree Lib "dnsapi" (ByVal pDnsRecord As Long, ByVal FreeType As Long) As Long 
Private Declare Function lstrlen Lib "kernel32" (ByVal straddress As Long) As Long 
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long) 
Private Declare Function inet_ntoa Lib "ws2_32.dll" (ByVal pIP As Long) As Long 
Private Declare Function inet_addr Lib "ws2_32.dll" (ByVal sAddr As String) As Long 

Private Const DnsFreeRecordList   As Long = 1 
Private Const DNS_TYPE_A    As Long = &H1 
Private Const DNS_QUERY_BYPASS_CACHE As Long = &H8 

Private Type VBDnsRecord 
    pNext   As Long 
    pName   As Long 
    wType   As Integer 
    wDataLength  As Integer 
    flags   As Long 
    dwTel   As Long 
    dwReserved  As Long 
    prt    As Long 
    others(35)  As Byte 
End Type 

Private Sub Command1_Click() 
    MsgBox Resolve("google.com", "208.67.222.222") 
End Sub 

Private Function Resolve(sAddr As String, Optional sDnsServers As String) As String 
    Dim pRecord  As Long 
    Dim pNext  As Long 
    Dim uRecord  As VBDnsRecord 
    Dim lPtr  As Long 
    Dim vSplit  As Variant 
    Dim laServers() As Long 
    Dim pServers As Long 
    Dim sName  As String 

    If LenB(sDnsServers) <> 0 Then 
     vSplit = Split(sDnsServers) 
     ReDim laServers(0 To UBound(vSplit) + 1) 
     laServers(0) = UBound(laServers) 
     For lPtr = 0 To UBound(vSplit) 
      laServers(lPtr + 1) = inet_addr(vSplit(lPtr)) 
     Next 
     pServers = VarPtr(laServers(0)) 
    End If 
    If DnsQuery(sAddr, DNS_TYPE_A, DNS_QUERY_BYPASS_CACHE, pServers, pRecord, 0) = 0 Then 
     pNext = pRecord 
     Do While pNext <> 0 
      Call CopyMemory(uRecord, pNext, Len(uRecord)) 
      If uRecord.wType = DNS_TYPE_A Then 
       lPtr = inet_ntoa(uRecord.prt) 
       sName = String(lstrlen(lPtr), 0) 
       Call CopyMemory(ByVal sName, lPtr, Len(sName)) 
       If LenB(Resolve) <> 0 Then 
        Resolve = Resolve & " " 
       End If 
       Resolve = Resolve & sName 
      End If 
      pNext = uRecord.pNext 
     Loop 
     Call DnsRecordListFree(pRecord, DnsFreeRecordList) 
    End If 
End Function 
+0

嘿,那真是太棒了。谢谢。你有没有在图书馆的某个地方使用它,或者你是否为这个答案定制了它? – ErikE 2010-02-10 01:24:15

+0

不得不定制清理一些来自代码浴室墙上的样品:-) – wqw 2010-02-10 09:04:21

+0

将回复给您,不要担心... – ErikE 2010-02-12 02:02:29

0

您可以使用DNS WMI提供程序来设置系统的DNS然后使用GetHostByAddr

+0

我会检查,看看用户是好这个问题,但我怀疑他不会(我也不喜欢它),好像它需要改回来一样,并且可能发生错误,导致它指向错误的DNS服务器,这是不正确的。 – ErikE 2010-02-06 23:55:51

+0

这是真的。 这是遗留代码的一部分,还是您有一些空间可以利用像.net这样的新的框架? – joejoeson 2010-02-07 00:02:42

+0

这只是帮助网络安全人员完成他的工作的一些自动化。花了大约30分钟来为他“增加”他的Excel工作簿。他还问我是否可以给他一个指定服务器名称的参数。现在我很好奇!如果涉及到编写整个应用程序,那么我可以使用C#来记录我的内容。但是Excel(2003)已经完成了他想要的99%。 – ErikE 2010-02-07 00:32:53

相关问题