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  }