为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
千万里不及你 2021-12-20 15:55:56
我一直在尝试使用 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)}
查看完整描述

1 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

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


该缓冲区由系统分配,必须使用 NetApiBufferFree 函数释放。


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


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 的很多地方都有使用。请阅读手册页并研究其中包含的代码示例。

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


查看完整回答
反对 回复 2021-12-20
  • 1 回答
  • 0 关注
  • 318 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号