podman-build/vendor/github.com/containers/libhvee/pkg/wmiext/enum.go
2025-10-11 12:30:35 +09:00

95 lines
2.2 KiB
Go

//go:build windows
// +build windows
package wmiext
import (
"fmt"
"syscall"
"unsafe"
"github.com/go-ole/go-ole"
)
type IEnumWbemClassObjectVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
Reset uintptr
Next uintptr
NextAsync uintptr
Clone uintptr
Skip uintptr
}
type Enum struct {
enum *ole.IUnknown
vTable *IEnumWbemClassObjectVtbl
service *Service
}
func (e *Enum) Close() {
if e != nil && e.enum != nil {
e.enum.Release()
}
}
func newEnum(enumerator *ole.IUnknown, service *Service) *Enum {
return &Enum{
enum: enumerator,
vTable: (*IEnumWbemClassObjectVtbl)(unsafe.Pointer(enumerator.RawVTable)),
service: service,
}
}
// NextObject obtains the next instance in an enumeration and sets all fields
// of the struct pointer passed through the target parameter. Otherwise, if
// the target parameter is not a struct pointer type, an error will be
// returned.
func NextObject(enum *Enum, target interface{}) (bool, error) {
var err error
var instance *Instance
if instance, err = enum.Next(); err != nil {
return false, err
}
if instance == nil {
return true, nil
}
defer instance.Close()
return false, instance.GetAll(target)
}
// Next returns the next object instance in this iteration
func (e *Enum) Next() (instance *Instance, err error) {
var res uintptr
var apObjects *ole.IUnknown
var uReturned uint32
res, _, _ = syscall.SyscallN(
e.vTable.Next, // IEnumWbemClassObject::Next()
uintptr(unsafe.Pointer(e.enum)), // IEnumWbemClassObject ptr
uintptr(WBEM_INFINITE), // [in] long lTimeout,
uintptr(1), // [in] ULONG uCount,
uintptr(unsafe.Pointer(&apObjects)), // [out] IWbemClassObject **apObjects,
uintptr(unsafe.Pointer(&uReturned))) // [out] ULONG *puReturned)
if int(res) < 0 {
return nil, NewWmiError(res)
}
if uReturned < 1 {
switch res {
case WBEM_S_NO_ERROR, WBEM_S_FALSE:
// No more elements
return nil, nil
default:
return nil, fmt.Errorf("failure advancing enumeration (%d)", res)
}
}
return newInstance(apObjects, e.service), nil
}