go - 调用win的api DnsQueryConfig,但它始终返回代码:87 ERROR_INVALID_PARAMETER

标签 go

DnsQueryConfig的文档在这里:

https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig
  • 在项目dnsapi.go中添加文件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)
    }
    
    

    我项目中的
  • 代码:

  • 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,能否给我一些建议,非常感谢。

    最佳答案

    解决这个问题

    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
    }
    
    

    关于go - 调用win的api DnsQueryConfig,但它始终返回代码:87 ERROR_INVALID_PARAMETER,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61554845/

    相关文章:

    html - 使用go模板解析页面中显示为纯文本的HTML代码

    使用 init() 进行 Google 云函数 Golang 单元测试

    google-app-engine - 批量查询分页?是否可以从数据存储中批量获取并获取游标?

    go - 如何在 gin 包中使用 golang 将 url 的某些部分作为子字符串?

    mongodb - 为什么mongo-go-driver聚合结果对象键返回 "Key"

    loops - 如何循环遍历包含多个数字的行的文本文件,同时计算数字

    go - 使用 URL 下载 zip 文件

    json - GO 中 JSON 对象的结构

    go - net/http 呈现根路由,即使我转到不存在的路由

    go - golang如何使用ctags?