首页 > 解决方案 > 调用win的api DnsQueryConfig,但总是返回代码:87 ERROR_INVALID_PARAMETER

问题描述

DnsQueryConfig 文档在这里:

https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig
  1. dnsapi.go在 project: 中添加文件github.com/kbinani/win,文件内容为:
// +build windows

package win

import "unsafe"

var (
    // Library
    libdnsapi uintptr

    // function
    dnsQueryConfig  uintptr
)

type DNS_CONFIG_TYPE uint32

type IP4_ARRAY struct {
    AddrCount   DWORD
    IP4_ADDRESS [1]IP_ADDRESS_STRING
}

type PIP4_ARRAY *IP4_ARRAY

func init(){
    // Library
    libdnsapi = doLoadLibrary("Dnsapi.dll")

    // Functions
    dnsQueryConfig = doGetProcAddress(libdnsapi, "DnsQueryConfig")
}

// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig
func DnsQueryConfig(config DNS_CONFIG_TYPE, flag DWORD, pwsAdapterName PCWSTR, pReserved PVOID, pBuffer PVOID, pBufLen DWORD_PTR) int32 {
    ret1 := syscall6(dnsQueryConfig,
        6,
        uintptr(unsafe.Pointer(&config)),
        uintptr(unsafe.Pointer(&flag)),
        uintptr(unsafe.Pointer(pwsAdapterName)),
        uintptr(pReserved),
        uintptr(pBuffer),
        uintptr(unsafe.Pointer(pBufLen)),
        )
    return int32(ret1)
}

  1. 我项目中的代码:
package main

import (
    "fmt"
    "github.com/kbinani/win"
    "unsafe"
)

func main(){
    // func DnsQueryConfig(config DNS_CONFIG_TYPE, flag DWORD, pwsAdapterName PCWSTR, pReserved PVOID, pBuffer PVOID, pBufLen DWORD_PTR) int32 {
    config := win.DNS_CONFIG_TYPE(6)
    flag := win.DWORD(0)
    pwsAdapterName := win.PCWSTR(nil)
    pReserved := win.PVOID(unsafe.Pointer(nil))
    buffer := win.IP4_ARRAY{}
    a := win.PVOID(unsafe.Pointer(&buffer))
    l := uint32(unsafe.Sizeof(buffer))
    pBufLen := win.DWORD_PTR(unsafe.Pointer(&l))
    r := win.DnsQueryConfig(config, flag, pwsAdapterName, pReserved, a, pBufLen)
    fmt.Println(r, buffer)
}

它总是返回代码87,你能给我一些建议吗,非常感谢。

标签: go

解决方案


解决这个问题

package main

import (
    "fmt"
    "golang.org/x/sys/windows"
    "net"
    "strings"
    "unsafe"
)

const (
    DnsConfigDnsServerList int32 = 6
)

type char byte
type IpAddressString struct {
    DNS [4 * 10]char
}

type Ip4Array struct {
    AddrCount  uint32
    Ip4Address [1]IpAddressString
}

func main() {
    fmt.Println(dns())
}

func dns() []string {
    dns := []string{}
    dnsapi := windows.NewLazyDLL("Dnsapi.dll")
    dnsQuery := dnsapi.NewProc("DnsQueryConfig")
    bufferBytes := make([]byte, 60)
loop:
    buffer := (*Ip4Array)(unsafe.Pointer(&bufferBytes[0]))
    blen := len(bufferBytes)
    r1, _, _ := dnsQuery.Call(uintptr(DnsConfigDnsServerList), uintptr(0), uintptr(0), uintptr(0), uintptr(unsafe.Pointer(&bufferBytes[0])), uintptr(unsafe.Pointer(&blen)))
    if r1 == 234 {
        bufferBytes = make([]byte, blen)
        goto loop
    } else if r1 == 0 {

    } else {
        return dns
    }
    for i := uint32(1); i <= buffer.AddrCount; i++ {
        right := i * 4
        left := right - 4
        tmpChars := buffer.Ip4Address[0].DNS[left:right]
        tmpStr := []string{}
        for j := 0; j < len(tmpChars); j++ {
            tmpStr = append(tmpStr, fmt.Sprint(tmpChars[j]))
        }
        tmpDNS := strings.Join(tmpStr, ".")
        pDns := net.ParseIP(tmpDNS)
        if pDns == nil {
            continue
        }
        if !pDns.IsGlobalUnicast() {
            continue
        }
        dns = append(dns, tmpDNS)
    }
    return dns
}


推荐阅读