Update to libhvee 0.5.0

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2023-11-17 13:16:25 -06:00
parent a6bb601400
commit 60d9f9b807
18 changed files with 298 additions and 61 deletions

2
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.7.1
github.com/containers/image/v5 v5.29.0
github.com/containers/libhvee v0.4.1-0.20231106202301-9651e31ae734
github.com/containers/libhvee v0.5.0
github.com/containers/ocicrypt v1.1.9
github.com/containers/psgo v1.8.0
github.com/containers/storage v1.51.0

4
go.sum
View File

@ -262,8 +262,8 @@ github.com/containers/gvisor-tap-vsock v0.7.1 h1:+Rc+sOPplrkQb/BUXeN0ug8TxjgyrIq
github.com/containers/gvisor-tap-vsock v0.7.1/go.mod h1:WSSsjcuYZkvP8i0J+Ht3LF8yvysn3krD5zxQ74wz7y0=
github.com/containers/image/v5 v5.29.0 h1:9+nhS/ZM7c4Kuzu5tJ0NMpxrgoryOJ2HAYTgG8Ny7j4=
github.com/containers/image/v5 v5.29.0/go.mod h1:kQ7qcDsps424ZAz24thD+x7+dJw1vgur3A9tTDsj97E=
github.com/containers/libhvee v0.4.1-0.20231106202301-9651e31ae734 h1:R6e4nMpxUWRTn+QoiS1dnWL3qa0hpFb2+8/ltKtSnWE=
github.com/containers/libhvee v0.4.1-0.20231106202301-9651e31ae734/go.mod h1:3lTcwI2g7qe8Ekgk9hdDxQeT9KrqXPilQvxJfIJp8TQ=
github.com/containers/libhvee v0.5.0 h1:rDhfG2NI8Q+VgeXht2dXezanxEdpj9pHqYX3vWfOGUw=
github.com/containers/libhvee v0.5.0/go.mod h1:yvU3Em2u1ZLl2VLd2glMIBWriBwfhWsDaRJsvixUIB0=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/luksy v0.0.0-20231030195837-b5a7f79da98b h1:8XvNAm+g7ivwPUkyiHvBs7z356JWpK9a0FDaek86+sY=

View File

@ -43,7 +43,7 @@ func (d *SyntheticDiskDriveSettings) DefineVirtualHardDisk(vhdxFile string, befo
func createDiskResourceInternal(systemPath string, drivePath string, file string, settings diskAssociation, resourceType string, cb func()) error {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()

View File

@ -6,6 +6,8 @@ package hypervctl
import (
"errors"
"fmt"
"github.com/containers/libhvee/pkg/wmiext"
)
// VM State errors
@ -155,3 +157,18 @@ func translateModifyError(code int) error {
return &modifyResourceError{code, message}
}
var (
ErrHyperVNamespaceMissing = errors.New("HyperV namespace not found, is HyperV enabled?")
)
func translateCommonHyperVWmiError(wmiError error) error {
if werr, ok := wmiError.(*wmiext.WmiError); ok {
switch werr.Code() {
case wmiext.WBEM_E_INVALID_NAMESPACE:
return ErrHyperVNamespaceMissing
}
}
return wmiError
}

View File

@ -68,7 +68,7 @@ func (p *SyntheticEthernetPortSettings) DefineEthernetPortConnection(switchName
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return nil, err
}
defer service.Close()

View File

@ -53,7 +53,7 @@ func (s *ResourceSettings) Path() string {
func createResourceSettingGeneric(settings interface{}, resourceType string) (string, error) {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return "", err
}
@ -84,7 +84,7 @@ func createResourceSettingGeneric(settings interface{}, resourceType string) (st
func populateDefaults(subType string, settings interface{}) error {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()

View File

@ -42,7 +42,7 @@ func (c *ScsiControllerSettings) AddSyntheticDvdDrive(slot uint) (*SyntheticDvdD
func (c *ScsiControllerSettings) createSyntheticDriveInternal(slot uint, settings driveAssociation, resourceType string) error {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()

View File

@ -106,7 +106,7 @@ func (s *SystemSettings) AddScsiController() (*ScsiControllerSettings, error) {
func (s *SystemSettings) createSystemResourceInternal(settings interface{}, resourceType string, cb func()) error {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()
@ -186,7 +186,7 @@ func addResource(service *wmiext.Service, systemSettingPath string, resourceSett
func (s *SystemSettings) GetVM() (*VirtualMachine, error) {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return nil, err
}
defer service.Close()

View File

@ -90,7 +90,7 @@ func (builder *SystemSettingsBuilder) Build() (*SystemSettings, error) {
return nil, err
}
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return nil, err
}
defer service.Close()

View File

@ -114,7 +114,7 @@ func (vm *VirtualMachine) GetKeyValuePairs() (map[string]string, error) {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return nil, err
}
@ -153,7 +153,7 @@ func (vm *VirtualMachine) kvpOperation(op string, key string, value string, ille
var vsms, job *wmiext.Instance
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()
@ -226,7 +226,7 @@ func (vm *VirtualMachine) stop(force bool) error {
res int32
srv *wmiext.Service
)
if srv, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if srv, err = NewLocalHyperVService(); err != nil {
return err
}
wmiInst, err := srv.FindFirstRelatedInstance(vm.Path(), "Msvm_ShutdownComponent")
@ -303,7 +303,7 @@ func (vm *VirtualMachine) Start() error {
func getService(_ *wmiext.Service) (*wmiext.Service, error) {
// any reason why when we instantiate a vm, we should NOT just embed a service?
return wmiext.NewLocalService(HyperVNamespace)
return NewLocalHyperVService()
}
func (vm *VirtualMachine) GetConfig(diskPath string) (*HyperVConfig, error) {
@ -350,7 +350,7 @@ func (vm *VirtualMachine) GetConfig(diskPath string) (*HyperVConfig, error) {
// SummaryRequestCommon and SummaryRequestNearAll provide predefined combinations for this
// parameter
func (vm *VirtualMachine) GetSummaryInformation(requestedFields SummaryRequestSet) (*SummaryInformation, error) {
service, err := wmiext.NewLocalService(HyperVNamespace)
service, err := NewLocalHyperVService()
if err != nil {
return nil, err
}
@ -469,7 +469,7 @@ func (vm *VirtualMachine) fetchExistingResourceSettings(service *wmiext.Service,
}
func (vm *VirtualMachine) getMemorySettings(m *MemorySettings) error {
service, err := wmiext.NewLocalService(HyperVNamespace)
service, err := NewLocalHyperVService()
if err != nil {
return err
}
@ -479,7 +479,7 @@ func (vm *VirtualMachine) getMemorySettings(m *MemorySettings) error {
// Update processor and/or mem
func (vm *VirtualMachine) UpdateProcessorMemSettings(updateProcessor func(*ProcessorSettings), updateMemory func(*MemorySettings)) error {
service, err := wmiext.NewLocalService(HyperVNamespace)
service, err := NewLocalHyperVService()
if err != nil {
return err
}
@ -556,7 +556,7 @@ func (vm *VirtualMachine) remove() (int32, error) {
if !Disabled.equal(vm.EnabledState) {
return -1, ErrMachineStateInvalid
}
if srv, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if srv, err = NewLocalHyperVService(); err != nil {
return -1, err
}

View File

@ -12,6 +12,7 @@ import (
const (
HyperVNamespace = "root\\virtualization\\v2"
VirtualSystemManagementService = "Msvm_VirtualSystemManagementService"
MsvmComputerSystem = "Msvm_ComputerSystem"
)
// https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-computersystem
@ -23,12 +24,22 @@ func NewVirtualMachineManager() *VirtualMachineManager {
return &VirtualMachineManager{}
}
func NewLocalHyperVService() (*wmiext.Service, error) {
service, err := wmiext.NewLocalService(HyperVNamespace)
if err != nil {
return nil, translateCommonHyperVWmiError(err)
}
return service, nil
}
func (vmm *VirtualMachineManager) GetAll() ([]*VirtualMachine, error) {
const wql = "Select * From Msvm_ComputerSystem Where Description = 'Microsoft Virtual Machine'"
// Fetch through settings to avoid locale sensitive properties
const wql = "Select * From Msvm_VirtualSystemSettingData Where VirtualSystemType = 'Microsoft:Hyper-V:System:Realized'"
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return []*VirtualMachine{}, err
}
defer service.Close()
@ -38,22 +49,31 @@ func (vmm *VirtualMachineManager) GetAll() ([]*VirtualMachine, error) {
return nil, err
}
defer enum.Close()
var vms []*VirtualMachine
for {
vm := &VirtualMachine{vmm: vmm}
done, err := wmiext.NextObject(enum, vm)
settings, err := enum.Next()
if err != nil {
return vms, err
}
if done {
// Finished iterating
if settings == nil {
break
}
vm, err := vmm.findVMFromSettings(service, settings)
settings.Close()
if err != nil {
return vms, err
}
vms = append(vms, vm)
}
return vms, nil
}
func (vmm *VirtualMachineManager) Exists(name string) (bool, error) {
vms, err := vmm.GetAll()
if err != nil {
@ -68,14 +88,14 @@ func (vmm *VirtualMachineManager) Exists(name string) (bool, error) {
return false, nil
}
func (*VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) {
const wql = "Select * From Msvm_ComputerSystem Where Description = 'Microsoft Virtual Machine' And ElementName='%s'"
func (vmm *VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) {
const wql = "Select * From Msvm_VirtualSystemSettingData Where VirtualSystemType = 'Microsoft:Hyper-V:System:Realized' And ElementName='%s'"
vm := &VirtualMachine{}
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return vm, err
}
defer service.Close()
@ -86,22 +106,31 @@ func (*VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) {
}
defer enum.Close()
done, err := wmiext.NextObject(enum, vm)
settings, err := service.FindFirstInstance(fmt.Sprintf(wql, name))
if err != nil {
return vm, err
return vm, fmt.Errorf("could not find virtual machine %q: %w", name, err)
}
defer settings.Close()
return vmm.findVMFromSettings(service, settings)
}
func (vmm *VirtualMachineManager) findVMFromSettings(service *wmiext.Service, settings *wmiext.Instance) (*VirtualMachine, error) {
path, err := settings.Path()
if err != nil {
return nil, err
}
if done {
return vm, fmt.Errorf("could not find virtual machine %q", name)
}
vm := &VirtualMachine{vmm: vmm}
err = service.FindFirstRelatedObject(path, MsvmComputerSystem, vm)
return vm, nil
return vm, err
}
func (*VirtualMachineManager) CreateVhdxFile(path string, maxSize uint64) error {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return err
}
defer service.Close()
@ -152,7 +181,7 @@ func (vmm *VirtualMachineManager) GetSummaryInformation(requestedFields SummaryR
func (vmm *VirtualMachineManager) getSummaryInformation(settingsPath string, requestedFields SummaryRequestSet) ([]SummaryInformation, error) {
var service *wmiext.Service
var err error
if service, err = wmiext.NewLocalService(HyperVNamespace); err != nil {
if service, err = NewLocalHyperVService(); err != nil {
return nil, err
}
defer service.Close()

View File

@ -113,7 +113,7 @@ func safeArrayDestroy(safearray *ole.SafeArray) (err error) {
ret, _, _ := procSafeArrayDestroy.Call(uintptr(unsafe.Pointer(safearray)))
if ret != 0 {
return ole.NewError(ret)
return NewWmiError(ret)
}
return nil
@ -127,7 +127,7 @@ func safeArrayPutElement(safearray *ole.SafeArray, index int64, element uintptr)
element)
if ret != 0 {
return ole.NewError(ret)
return NewWmiError(ret)
}
return nil
@ -141,7 +141,7 @@ func safeArrayGetElement(safearray *ole.SafeArray, index int64, element unsafe.P
uintptr(element))
if ret != 0 {
return ole.NewError(ret)
return NewWmiError(ret)
}
return nil

View File

@ -77,7 +77,7 @@ func (e *Enum) Next() (instance *Instance, err error) {
uintptr(unsafe.Pointer(&apObjects)), // [out] IWbemClassObject **apObjects,
uintptr(unsafe.Pointer(&uReturned))) // [out] ULONG *puReturned)
if int(res) < 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
if uReturned < 1 {

View File

@ -0,0 +1,196 @@
package wmiext
import (
"fmt"
"os"
"strings"
"syscall"
"unicode/utf16"
"golang.org/x/sys/windows"
)
const (
WBEM_NO_ERROR = 0
WBEM_S_NO_ERROR = 0
WBEM_S_SAME = 0
WBEM_S_FALSE = 1
WBEM_S_ALREADY_EXISTS = 0x40001
WBEM_S_RESET_TO_DEFAULT = 0x40002
WBEM_S_DIFFERENT = 0x40003
WBEM_S_TIMEDOUT = 0x40004
WBEM_S_NO_MORE_DATA = 0x40005
WBEM_S_OPERATION_CANCELLED = 0x40006
WBEM_S_PENDING = 0x40007
WBEM_S_DUPLICATE_OBJECTS = 0x40008
WBEM_S_ACCESS_DENIED = 0x40009
WBEM_S_PARTIAL_RESULTS = 0x40010
WBEM_S_SOURCE_NOT_AVAILABLE = 0x40017
WBEM_E_FAILED = 0x80041001
WBEM_E_NOT_FOUND = 0x80041002
WBEM_E_ACCESS_DENIED = 0x80041003
WBEM_E_PROVIDER_FAILURE = 0x80041004
WBEM_E_TYPE_MISMATCH = 0x80041005
WBEM_E_OUT_OF_MEMORY = 0x80041006
WBEM_E_INVALID_CONTEXT = 0x80041007
WBEM_E_INVALID_PARAMETER = 0x80041008
WBEM_E_NOT_AVAILABLE = 0x80041009
WBEM_E_CRITICAL_ERROR = 0x8004100a
WBEM_E_INVALID_STREAM = 0x8004100b
WBEM_E_NOT_SUPPORTED = 0x8004100c
WBEM_E_INVALID_SUPERCLASS = 0x8004100d
WBEM_E_INVALID_NAMESPACE = 0x8004100e
WBEM_E_INVALID_OBJECT = 0x8004100f
WBEM_E_INVALID_CLASS = 0x80041010
WBEM_E_PROVIDER_NOT_FOUND = 0x80041011
WBEM_E_INVALID_PROVIDER_REGISTRATION = 0x80041012
WBEM_E_PROVIDER_LOAD_FAILURE = 0x80041013
WBEM_E_INITIALIZATION_FAILURE = 0x80041014
WBEM_E_TRANSPORT_FAILURE = 0x80041015
WBEM_E_INVALID_OPERATION = 0x80041016
WBEM_E_INVALID_QUERY = 0x80041017
WBEM_E_INVALID_QUERY_TYPE = 0x80041018
WBEM_E_ALREADY_EXISTS = 0x80041019
WBEM_E_OVERRIDE_NOT_ALLOWED = 0x8004101a
WBEM_E_PROPAGATED_QUALIFIER = 0x8004101b
WBEM_E_PROPAGATED_PROPERTY = 0x8004101c
WBEM_E_UNEXPECTED = 0x8004101d
WBEM_E_ILLEGAL_OPERATION = 0x8004101e
WBEM_E_CANNOT_BE_KEY = 0x8004101f
WBEM_E_INCOMPLETE_CLASS = 0x80041020
WBEM_E_INVALID_SYNTAX = 0x80041021
WBEM_E_NONDECORATED_OBJECT = 0x80041022
WBEM_E_READ_ONLY = 0x80041023
WBEM_E_PROVIDER_NOT_CAPABLE = 0x80041024
WBEM_E_CLASS_HAS_CHILDREN = 0x80041025
WBEM_E_CLASS_HAS_INSTANCES = 0x80041026
WBEM_E_QUERY_NOT_IMPLEMENTED = 0x80041027
WBEM_E_ILLEGAL_NULL = 0x80041028
WBEM_E_INVALID_QUALIFIER_TYPE = 0x80041029
WBEM_E_INVALID_PROPERTY_TYPE = 0x8004102a
WBEM_E_VALUE_OUT_OF_RANGE = 0x8004102b
WBEM_E_CANNOT_BE_SINGLETON = 0x8004102c
WBEM_E_INVALID_CIM_TYPE = 0x8004102d
WBEM_E_INVALID_METHOD = 0x8004102e
WBEM_E_INVALID_METHOD_PARAMETERS = 0x8004102f
WBEM_E_SYSTEM_PROPERTY = 0x80041030
WBEM_E_INVALID_PROPERTY = 0x80041031
WBEM_E_CALL_CANCELLED = 0x80041032
WBEM_E_SHUTTING_DOWN = 0x80041033
WBEM_E_PROPAGATED_METHOD = 0x80041034
WBEM_E_UNSUPPORTED_PARAMETER = 0x80041035
WBEM_E_MISSING_PARAMETER_ID = 0x80041036
WBEM_E_INVALID_PARAMETER_ID = 0x80041037
WBEM_E_NONCONSECUTIVE_PARAMETER_IDS = 0x80041038
WBEM_E_PARAMETER_ID_ON_RETVAL = 0x80041039
WBEM_E_INVALID_OBJECT_PATH = 0x8004103a
WBEM_E_OUT_OF_DISK_SPACE = 0x8004103b
WBEM_E_BUFFER_TOO_SMALL = 0x8004103c
WBEM_E_UNSUPPORTED_PUT_EXTENSION = 0x8004103d
WBEM_E_UNKNOWN_OBJECT_TYPE = 0x8004103e
WBEM_E_UNKNOWN_PACKET_TYPE = 0x8004103f
WBEM_E_MARSHAL_VERSION_MISMATCH = 0x80041040
WBEM_E_MARSHAL_INVALID_SIGNATURE = 0x80041041
WBEM_E_INVALID_QUALIFIER = 0x80041042
WBEM_E_INVALID_DUPLICATE_PARAMETER = 0x80041043
WBEM_E_TOO_MUCH_DATA = 0x80041044
WBEM_E_SERVER_TOO_BUSY = 0x80041045
WBEM_E_INVALID_FLAVOR = 0x80041046
WBEM_E_CIRCULAR_REFERENCE = 0x80041047
WBEM_E_UNSUPPORTED_CLASS_UPDATE = 0x80041048
WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE = 0x80041049
WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE = 0x80041050
WBEM_E_TOO_MANY_PROPERTIES = 0x80041051
WBEM_E_UPDATE_TYPE_MISMATCH = 0x80041052
WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED = 0x80041053
WBEM_E_UPDATE_PROPAGATED_METHOD = 0x80041054
WBEM_E_METHOD_NOT_IMPLEMENTED = 0x80041055
WBEM_E_METHOD_DISABLED = 0x80041056
WBEM_E_REFRESHER_BUSY = 0x80041057
WBEM_E_UNPARSABLE_QUERY = 0x80041058
WBEM_E_NOT_EVENT_CLASS = 0x80041059
WBEM_E_MISSING_GROUP_WITHIN = 0x8004105a
WBEM_E_MISSING_AGGREGATION_LIST = 0x8004105b
WBEM_E_PROPERTY_NOT_AN_OBJECT = 0x8004105c
WBEM_E_AGGREGATING_BY_OBJECT = 0x8004105d
WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY = 0x8004105f
WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING = 0x80041060
WBEM_E_QUEUE_OVERFLOW = 0x80041061
WBEM_E_PRIVILEGE_NOT_HELD = 0x80041062
WBEM_E_INVALID_OPERATOR = 0x80041063
WBEM_E_LOCAL_CREDENTIALS = 0x80041064
WBEM_E_CANNOT_BE_ABSTRACT = 0x80041065
WBEM_E_AMENDED_OBJECT = 0x80041066
WBEM_E_CLIENT_TOO_SLOW = 0x80041067
WBEM_E_NULL_SECURITY_DESCRIPTOR = 0x80041068
WBEM_E_TIMED_OUT = 0x80041069
WBEM_E_INVALID_ASSOCIATION = 0x8004106a
WBEM_E_AMBIGUOUS_OPERATION = 0x8004106b
WBEM_E_QUOTA_VIOLATION = 0x8004106c
WBEM_E_RESERVED_001 = 0x8004106d
WBEM_E_RESERVED_002 = 0x8004106e
WBEM_E_UNSUPPORTED_LOCALE = 0x8004106f
WBEM_E_HANDLE_OUT_OF_DATE = 0x80041070
WBEM_E_CONNECTION_FAILED = 0x80041071
WBEM_E_INVALID_HANDLE_REQUEST = 0x80041072
WBEM_E_PROPERTY_NAME_TOO_WIDE = 0x80041073
WBEM_E_CLASS_NAME_TOO_WIDE = 0x80041074
WBEM_E_METHOD_NAME_TOO_WIDE = 0x80041075
WBEM_E_QUALIFIER_NAME_TOO_WIDE = 0x80041076
WBEM_E_RERUN_COMMAND = 0x80041077
WBEM_E_DATABASE_VER_MISMATCH = 0x80041078
WBEM_E_VETO_DELETE = 0x80041079
WBEM_E_VETO_PUT = 0x8004107a
WBEM_E_INVALID_LOCALE = 0x80041080
WBEM_E_PROVIDER_SUSPENDED = 0x80041081
WBEM_E_SYNCHRONIZATION_REQUIRED = 0x80041082
WBEM_E_NO_SCHEMA = 0x80041083
WBEM_E_PROVIDER_ALREADY_REGISTERED = 0x80041084
WBEM_E_PROVIDER_NOT_REGISTERED = 0x80041085
WBEM_E_FATAL_TRANSPORT_ERROR = 0x80041086
WBEM_E_ENCRYPTED_CONNECTION_REQUIRED = 0x80041087
WBEM_E_PROVIDER_TIMED_OUT = 0x80041088
WBEM_E_NO_KEY = 0x80041089
WBEM_E_PROVIDER_DISABLED = 0x8004108a
)
var (
wmiModule syscall.Handle
)
func init() {
file := os.ExpandEnv("${windir}\\system32\\wbem\\wmiutils.dll")
wmiModule, _ = syscall.LoadLibrary(file)
}
type WmiError struct {
hres uintptr
}
func NewWmiError(hres uintptr) *WmiError {
return &WmiError{hres}
}
func (w *WmiError) String() string {
return w.Error()
}
func (w *WmiError) Code() uintptr {
return w.hres
}
func (w *WmiError) Error() string {
// ask windows for the remaining errors
var flags uint32 = syscall.FORMAT_MESSAGE_FROM_SYSTEM |
syscall.FORMAT_MESSAGE_FROM_HMODULE |
syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY |
syscall.FORMAT_MESSAGE_IGNORE_INSERTS
buf := make([]uint16, 300)
n, err := windows.FormatMessage(flags, uintptr(wmiModule), uint32(w.hres), 0, buf, nil)
if err != nil {
return fmt.Sprintf("WMI error [%d]: FormatMessage failed with: %v", w.hres, err)
}
return fmt.Sprintf("WMI error [%d]: %s", w.hres, strings.TrimRight(string(utf16.Decode(buf[:n])), "\r\n"))
}

View File

@ -31,11 +31,6 @@ var (
)
const (
// WMI HRESULT values
WBEM_S_NO_ERROR = 0
WBEM_S_FALSE = 1
WBEM_S_NO_MORE_DATA = 0x40005
// WMI Generic flags
WBEM_FLAG_RETURN_WBEM_COMPLETE = 0x0
WBEM_FLAG_RETURN_IMMEDIATELY = 0x10
@ -108,6 +103,6 @@ func initSecurity() {
uintptr(EOAC_NONE), // [in] DWORD dwCapabilities,
uintptr(0)) // [in, optional] void *pReserved3
if int(res) < 0 {
logrus.Errorf("Unable to initialize COM security: %s", ole.NewError(res).Error())
logrus.Errorf("Unable to initialize COM security: %s", NewWmiError(res).Error())
}
}

View File

@ -151,7 +151,7 @@ func (i *Instance) SpawnInstance() (instance *Instance, err error) {
uintptr(0), // [in] long lFlags,
uintptr(unsafe.Pointer(&newUnknown))) // [out] IWbemClassObject **ppNewInstance)
if res != 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
return newInstance(newUnknown, i.service), nil
@ -168,7 +168,7 @@ func (i *Instance) CloneInstance() (*Instance, error) {
uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr
uintptr(unsafe.Pointer(&cloned))) // [out] IWbemClassObject **ppCopy)
if ret != 0 {
return nil, ole.NewError(ret)
return nil, NewWmiError(ret)
}
return newInstance(cloned, i.service), nil
@ -260,7 +260,7 @@ func (i *Instance) Put(name string, value interface{}) (err error) {
uintptr(unsafe.Pointer(&variant)), // [in] VARIANT *pVal,
uintptr(0)) // [in] CIMTYPE Type)
if res != 0 {
return ole.NewError(res)
return NewWmiError(res)
}
_ = variant.Clear()
@ -444,7 +444,7 @@ func (i *Instance) GetAsVariant(name string) (*ole.VARIANT, CIMTYPE_ENUMERATION,
uintptr(unsafe.Pointer(&cimType)), // [out, optional] CIMTYPE *pType,
uintptr(unsafe.Pointer(&flavor))) // [out, optional] long *plFlavor)
if res != 0 {
return nil, 0, 0, ole.NewError(res)
return nil, 0, 0, NewWmiError(res)
}
return &variant, cimType, flavor, nil
@ -490,7 +490,7 @@ func (i *Instance) NextAsVariant() (bool, string, *ole.VARIANT, CIMTYPE_ENUMERAT
uintptr(unsafe.Pointer(&cimType)), // [out, optional] CIMTYPE *pType,
uintptr(unsafe.Pointer(&flavor))) // [out, optional] long *plFlavor
if int(res) < 0 {
return false, "", nil, cimType, flavor, ole.NewError(res)
return false, "", nil, cimType, flavor, NewWmiError(res)
}
if res == WBEM_S_NO_MORE_DATA {
@ -556,7 +556,7 @@ func (i *Instance) GetMethodParameters(method string) (*Instance, error) {
uintptr(unsafe.Pointer(&inSignature)), // [out] IWbemClassObject **ppInSignature,
uintptr(0)) // [out] IWbemClassObject **ppOutSignature)
if res != 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
return newInstance(inSignature, i.service), nil
@ -612,7 +612,7 @@ func (i *Instance) BeginEnumeration() error {
uintptr(unsafe.Pointer(classObj)), // IWbemClassObject ptr,
uintptr(0)) // [in] long lEnumFlags) // 0 = defaults
if result != 0 {
return ole.NewError(result)
return NewWmiError(result)
}
return nil
@ -626,7 +626,7 @@ func (i *Instance) EndEnumeration() error {
i.vTable.EndEnumeration, // IWbemClassObject::EndEnumeration(
uintptr(unsafe.Pointer(i.object))) // IWbemClassObject ptr)
if res != 0 {
return ole.NewError(res)
return NewWmiError(res)
}
return nil

View File

@ -90,7 +90,7 @@ func connectService(namespace string) (*Service, error) {
uintptr(unsafe.Pointer(&service))) // [out] IWbemServices **ppNamespace)
if res != 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
if err = CoSetProxyBlanket(service); err != nil {
@ -123,7 +123,7 @@ func CoSetProxyBlanket(service *ole.IUnknown) (err error) {
uintptr(EOAC_NONE)) // [in] DWORD dwCapabilities)
if res != 0 {
return ole.NewError(res)
return NewWmiError(res)
}
return nil
@ -169,7 +169,7 @@ func (s *Service) ExecQuery(wqlQuery string) (*Enum, error) {
uintptr(0), // [in] IWbemContext *pCtx,
uintptr(unsafe.Pointer(&pEnum))) // [out] IEnumWbemClassObject **ppEnum)
if hres != 0 {
return nil, ole.NewError(hres)
return nil, NewWmiError(hres)
}
if err = CoSetProxyBlanket(pEnum); err != nil {
@ -201,7 +201,7 @@ func (s *Service) GetObject(objectPath string) (instance *Instance, err error) {
uintptr(0)) // [out] IWbemCallResult **ppCallResult)
if int(res) < 0 {
// returns WBEM_E_PROVIDER_NOT_FOUND when no entry found
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
return newInstance(pObject, s), nil
@ -240,7 +240,7 @@ func (s *Service) CreateInstanceEnum(className string) (*Enum, error) {
uintptr(0), // [in] IWbemContext *pCtx,
uintptr(unsafe.Pointer(&pEnum))) // [out] IEnumWbemClassObject **ppEnum)
if int(res) < 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
if err = CoSetProxyBlanket(pEnum); err != nil {
@ -278,7 +278,7 @@ func (s *Service) ExecMethod(className string, methodName string, inParams *Inst
uintptr(unsafe.Pointer(&outParams)), // [out] IWbemClassObject **ppOutParams,
uintptr(0)) // [out] IWbemCallResult **ppCallResult)
if int(res) < 0 {
return nil, ole.NewError(res)
return nil, NewWmiError(res)
}
return newInstance(outParams, s), nil

2
vendor/modules.txt vendored
View File

@ -302,7 +302,7 @@ github.com/containers/image/v5/transports
github.com/containers/image/v5/transports/alltransports
github.com/containers/image/v5/types
github.com/containers/image/v5/version
# github.com/containers/libhvee v0.4.1-0.20231106202301-9651e31ae734
# github.com/containers/libhvee v0.5.0
## explicit; go 1.18
github.com/containers/libhvee/pkg/hypervctl
github.com/containers/libhvee/pkg/kvp/ginsu