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