記事を書いたら、自己解決する法則でもあるのかなぁ。
package main
import (
"fmt"
"unsafe"
"golang.org/x/sys/windows"
)
const RESOURCE_CONNECTED = 1
const RESOURCE_CONTEXT = 5
const RESOURCE_GLOBALNET = 2
const RESOURCE_REMEMBERED = 3
const RESOURCETYPE_ANY = 0
const RESOURCETYPE_DISK = 1
const RESOURCETYPE_PRINT = 2
const RESOURCEDISPLAYTYPE_NETWORK = 6
const RESOURCEUSAGE_CONNECTABLE = 1
const RESOURCEUSAGE_CONTAINER = 2
const RESOURCEUSAGE_ATTACHED = 16
const RESOURCEUSAGE_ALL = 19
const ERROR_NO_MORE_ITEMS = 259
var mpr = windows.NewLazySystemDLL("mpr.dll")
var procWNetOpenEnum = mpr.NewProc("WNetOpenEnumW")
var procWNetEnumResource = mpr.NewProc("WNetEnumResourceW")
var procWNetCloseEnum = mpr.NewProc("WNetCloseEnum")
type netresourceT struct {
Scope uint32
Type uint32
DisplayType uint32
Usage uint32
LocalName *uint16
RemoteName *uint16
Comment *uint16
Provider *uint16
}
func u2str(u *uint16) string {
if u == nil {
return ""
}
buffer := make([]uint16, 0, 100)
for *u != 0 {
buffer = append(buffer, *u)
u = (*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(u)) + 2))
}
return windows.UTF16ToString(buffer)
}
func WNetEnum(nr *netresourceT, handler func(localName string, remoteName string)) error {
var handle uintptr
rc, _, err := procWNetOpenEnum.Call(
RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
0,
uintptr(unsafe.Pointer(nr)),
uintptr(unsafe.Pointer(&handle)))
if rc != windows.NO_ERROR {
return fmt.Errorf("NetOpenEnum: %s", err)
}
defer procWNetCloseEnum.Call(handle)
for {
var buffer [16*1024]byte
count := int32(-1)
size := len(buffer)
rc, _, err := procWNetEnumResource.Call(
handle,
uintptr(unsafe.Pointer(&count)),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(unsafe.Pointer(&size)))
if rc == windows.NO_ERROR {
println("open")
for i := int32(0) ; i < count ; i++ {
var p *netresourceT
p = (*netresourceT)(unsafe.Pointer(&buffer[ uintptr(i)*unsafe.Sizeof(*p) ]))
handler(u2str(p.LocalName), u2str(p.RemoteName))
WNetEnum(p,handler)
}
println("close")
} else if rc == ERROR_NO_MORE_ITEMS {
return nil
} else {
return fmt.Errorf("NetEnumResource: %s", err)
}
}
}
func main() {
err := WNetEnum(nil,func(localName, remoteName string) {
println(localName, " -> ", remoteName)
})
if err != nil {
println(err.Error())
}
}
要は再帰的に呼ばないとダメというわけですね
$ go run eachnetdrive_run.go
open
-> Microsoft Terminal Services
-> Microsoft Windows Network
open
-> MICROSOFTACCOUNT
-> WORKGROUP
open
-> \\ATERM-71C395
-> \\DESKTOP-LGGUCRA
open
-> \\DESKTOP-LGGUCRA\tmp
close
close
close
-> Web Client Network
close