github.com/vmware/govmomi@v0.51.0/toolbox/vix/property.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package vix 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "errors" 11 ) 12 13 // Property type enum as defined in open-vm-tools/lib/include/vix.h 14 const ( 15 _ = iota // ANY type not supported 16 vixPropertyTypeInt32 17 vixPropertyTypeString 18 vixPropertyTypeBool 19 _ // HANDLE type not supported 20 vixPropertyTypeInt64 21 vixPropertyTypeBlob 22 ) 23 24 // Property ID enum as defined in open-vm-tools/lib/include/vixOpenSource.h 25 const ( 26 PropertyGuestToolsAPIOptions = 4501 27 PropertyGuestOsFamily = 4502 28 PropertyGuestOsVersion = 4503 29 PropertyGuestToolsProductNam = 4511 30 PropertyGuestToolsVersion = 4500 31 PropertyGuestName = 4505 32 PropertyGuestOsVersionShort = 4520 33 34 PropertyGuestStartProgramEnabled = 4540 35 PropertyGuestListProcessesEnabled = 4541 36 PropertyGuestTerminateProcessEnabled = 4542 37 PropertyGuestReadEnvironmentVariableEnabled = 4543 38 39 PropertyGuestMakeDirectoryEnabled = 4547 40 PropertyGuestDeleteFileEnabled = 4548 41 PropertyGuestDeleteDirectoryEnabled = 4549 42 PropertyGuestMoveDirectoryEnabled = 4550 43 PropertyGuestMoveFileEnabled = 4551 44 PropertyGuestCreateTempFileEnabled = 4552 45 PropertyGuestCreateTempDirectoryEnabled = 4553 46 PropertyGuestListFilesEnabled = 4554 47 PropertyGuestChangeFileAttributesEnabled = 4555 48 PropertyGuestInitiateFileTransferFromGuestEnabled = 4556 49 PropertyGuestInitiateFileTransferToGuestEnabled = 4557 50 ) 51 52 type Property struct { 53 header struct { 54 ID int32 55 Kind int32 56 Length int32 57 } 58 59 data struct { 60 Int32 int32 61 String string 62 Bool uint8 63 Int64 int64 64 Blob []byte 65 } 66 } 67 68 var int32Size int32 69 70 func init() { 71 var i int32 72 int32Size = int32(binary.Size(&i)) 73 } 74 75 type PropertyList []*Property 76 77 func NewInt32Property(id int32, val int32) *Property { 78 p := new(Property) 79 p.header.ID = id 80 p.header.Kind = vixPropertyTypeInt32 81 p.header.Length = int32Size 82 p.data.Int32 = val 83 return p 84 } 85 86 func NewStringProperty(id int32, val string) *Property { 87 p := new(Property) 88 p.header.ID = id 89 p.header.Kind = vixPropertyTypeString 90 p.header.Length = int32(len(val) + 1) 91 p.data.String = val 92 return p 93 } 94 95 func NewBoolProperty(id int32, val bool) *Property { 96 p := new(Property) 97 p.header.ID = id 98 p.header.Kind = vixPropertyTypeBool 99 p.header.Length = 1 100 if val { 101 p.data.Bool = 1 102 } 103 return p 104 } 105 106 func NewInt64Property(id int32, val int64) *Property { 107 p := new(Property) 108 p.header.ID = id 109 p.header.Kind = vixPropertyTypeInt64 110 p.header.Length = int32Size * 2 111 p.data.Int64 = val 112 return p 113 } 114 115 func NewBlobProperty(id int32, val []byte) *Property { 116 p := new(Property) 117 p.header.ID = id 118 p.header.Kind = vixPropertyTypeBlob 119 p.header.Length = int32(len(val)) 120 p.data.Blob = val 121 return p 122 } 123 124 // MarshalBinary implements the encoding.BinaryMarshaler interface 125 func (p *Property) MarshalBinary() ([]byte, error) { 126 buf := new(bytes.Buffer) 127 128 // #nosec: Errors unhandled 129 _ = binary.Write(buf, binary.LittleEndian, &p.header) 130 131 switch p.header.Kind { 132 case vixPropertyTypeBool: 133 // #nosec: Errors unhandled 134 _ = binary.Write(buf, binary.LittleEndian, p.data.Bool) 135 case vixPropertyTypeInt32: 136 // #nosec: Errors unhandled 137 _ = binary.Write(buf, binary.LittleEndian, p.data.Int32) 138 case vixPropertyTypeInt64: 139 // #nosec: Errors unhandled 140 _ = binary.Write(buf, binary.LittleEndian, p.data.Int64) 141 case vixPropertyTypeString: 142 // #nosec: Errors unhandled 143 _, _ = buf.WriteString(p.data.String) 144 // #nosec: Errors unhandled 145 _ = buf.WriteByte(0) 146 case vixPropertyTypeBlob: 147 // #nosec: Errors unhandled 148 _, _ = buf.Write(p.data.Blob) 149 } 150 151 return buf.Bytes(), nil 152 } 153 154 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface 155 func (p *Property) UnmarshalBinary(data []byte) error { 156 buf := bytes.NewBuffer(data) 157 158 err := binary.Read(buf, binary.LittleEndian, &p.header) 159 if err != nil { 160 return err 161 } 162 163 switch p.header.Kind { 164 case vixPropertyTypeBool: 165 return binary.Read(buf, binary.LittleEndian, &p.data.Bool) 166 case vixPropertyTypeInt32: 167 return binary.Read(buf, binary.LittleEndian, &p.data.Int32) 168 case vixPropertyTypeInt64: 169 return binary.Read(buf, binary.LittleEndian, &p.data.Int64) 170 case vixPropertyTypeString: 171 s := make([]byte, p.header.Length) 172 if _, err := buf.Read(s); err != nil { 173 return err 174 } 175 176 p.data.String = string(bytes.TrimRight(s, "\x00")) 177 case vixPropertyTypeBlob: 178 p.data.Blob = make([]byte, p.header.Length) 179 if _, err := buf.Read(p.data.Blob); err != nil { 180 return err 181 } 182 default: 183 return errors.New("VIX_E_UNRECOGNIZED_PROPERTY") 184 } 185 186 return nil 187 } 188 189 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface 190 func (l *PropertyList) UnmarshalBinary(data []byte) error { 191 headerSize := int32Size * 3 192 193 for { 194 p := new(Property) 195 196 err := p.UnmarshalBinary(data) 197 if err != nil { 198 return err 199 } 200 201 *l = append(*l, p) 202 203 offset := headerSize + p.header.Length 204 data = data[offset:] 205 206 if len(data) == 0 { 207 return nil 208 } 209 } 210 } 211 212 // MarshalBinary implements the encoding.BinaryMarshaler interface 213 func (l *PropertyList) MarshalBinary() ([]byte, error) { 214 var buf bytes.Buffer 215 216 for _, p := range *l { 217 // #nosec: Errors unhandled 218 b, _ := p.MarshalBinary() 219 // #nosec: Errors unhandled 220 _, _ = buf.Write(b) 221 } 222 223 return buf.Bytes(), nil 224 }