gpt4 book ai didi

winapi - 如何正确调用 netapi32!NetSessionEnum()?

转载 作者:数据小太阳 更新时间:2023-10-29 03:15:56 25 4
gpt4 key购买 nike

我一直在尝试使用 netapi32.dll,但结果好坏参半。

以下按预期工作

type SERVER_INFO_101 struct {
PlatformID uint32
Name *uint16
VersionMajor uint32
VersionMinor uint32
Type uint32
Comment *uint16
}


func NetServerGetInfo() {
info := &SERVER_INFO_101{}
ret, _, err := procNetServerGetInfo.Call(0, 101, uintptr(unsafe.Pointer(&info)))
if ret != 0 {
log.Fatal(err)
}
spew.Dump(info)
}

但是,我不确定为什么 info 也必须在 unsafe.Pointer 中包含 &。

以下不起作用,我似乎无法找出原因。不会抛出任何错误代码。结构或变量都不会被填充。

type SESSION_INFO_10 struct {
Cname *uint16
Username *uint16
Time uint32
IdleTime uint32
}

func NetSessionEnum() {
info := &SESSION_INFO_10{}
var prefmaxlen int32 = -1
var entriesread uint32
var totalentries uint32
var resumehandle uint32
x, y, z := procNetSessionEnum.Call(0, 0, 0, 10, uintptr(unsafe.Pointer(info)), uintptr(prefmaxlen), uintptr(unsafe.Pointer(&entriesread)), uintptr(unsafe.Pointer(&totalentries)), uintptr(unsafe.Pointer(&resumehandle)))
fmt.Println(x, y, z)
fmt.Println(entriesread, totalentries)
spew.Dump(info)
}

最佳答案

…因为你不应该在那里传递一个指向你的内存块的指针——引用the manual :

This buffer is allocated by the system and must be freed using the NetApiBufferFree function.

该指针的类型具有误导性,但您应该将指针传递给那里的指针,如下所示:

func NetSessionEnum() {
var pinfo *SESSION_INFO_10
var prefmaxlen int32 = -1
var entriesread uint32
var totalentries uint32
var resumehandle uint32
x, y, z := procNetSessionEnum.Call(0, 0, 0, 10,
uintptr(unsafe.Pointer(&pinfo)), uintptr(prefmaxlen),
uintptr(unsafe.Pointer(&entriesread)),
uintptr(unsafe.Pointer(&totalentries)),
uintptr(unsafe.Pointer(&resumehandle)))
fmt.Println(x, y, z)
fmt.Println(entriesread, totalentries)
spew.Dump(info)
}

// Now use `*pinfo.Cname` etc
// Don't forget to later call `NetApiBufferFree()` on that pointer.

这里发生了什么:

  1. 变量 pinfo 是一个指向 SESSION_INFO_10 类型值的指针。

  2. 您获取保存在该变量(指针)中的值所占用的内存块的地址,并将其传递给 NetSessionEnum()

  3. 该函数自行分配缓冲区,并将其地址写入您传递给该函数的地址所指向的内存块。

    由于您传递了 pinfo 变量的地址,因此缓冲区的地址最终被写入变量 pinfo

  4. 然后您使用存储在 pinfo 中的地址访问由 NetSessionEnum() 分配的内存。

这就是所谓的“双重间接”,在 Win32 API 的很多地方都有使用。请阅读手册页并研究其中包含的代码示例。

更新:事实证明,原始代码存在更多问题,因此我花时间提供了完整的解决方案— here是要点(在 Windows XP 32 位、Windows 2003 R2 64 位和 Windows 8.1 64 位上使用 Go 1.6 amd64 和 i386 进行测试)。

关于winapi - 如何正确调用 netapi32!NetSessionEnum()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35885460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com