go - 调用win的api DnsQueryConfig,但总是返回代码:87 ERROR_INVALID_PARAMETER
问题描述
DnsQueryConfig 文档在这里:
https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig
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)
}
- 我项目中的代码:
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
}
推荐阅读
- assembly - 为什么 SEG 不给出此代码片段的错误消息?
- docker - 我为同一个 Web 应用程序部署了多个服务器。如何自动化部署,以便可以更新一台服务器而不更新其他服务器?
- numpy - 如何从数字数组 A 中计算每个参数 a 的每个总和
- msbuild - 如何摆脱 VSIX 项目中的包引用冲突
- python - 如何实现定时后台功能?
- javascript - 如何使用 Ruby 验证 webhook?(在 Rails 中)
- ocaml - 覆盖变体时如何访问全局构造函数?
- c# - 对话一直卡在最后一句话
- node.js - npm 错误!cb() 从未在 windows10 中调用过
- javascript - React.js 材质 UI - 具有弹性显示的 CardActionArea - 子元素不使用全宽