首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确地调用netapi32!NetSessionEnum()?

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

Stack Overflow用户
提问于 2016-03-09 07:27:25
回答 1查看 279关注 0票数 0

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

下列工作按预期进行

代码语言:javascript
复制
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)
}

然而,我不知道为什么信息必须有&在unsafe.Pointer中也有。

以下内容不起作用,我似乎也找不出原因。没有错误代码被抛出。结构或变量都不会被填写。

代码语言:javascript
复制
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)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-09 14:36:10

…因为你不应该传递一个指向你的内存块的指针--引用手册

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

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

代码语言:javascript
复制
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 32位、R2 64位和Windows8.1 64位上进行了Go 1.6 amd64和i386测试)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35885460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档