github.com/vmware/govmomi@v0.51.0/toolbox/hgfs/protocol.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 hgfs
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"log"
    12  	"os"
    13  	"strings"
    14  )
    15  
    16  // See: https://github.com/vmware/open-vm-tools/blob/master/open-vm-tools/lib/include/hgfsProto.h
    17  
    18  // Opcodes for server operations as defined in hgfsProto.h
    19  const (
    20  	OpOpen               = iota /* Open file */
    21  	OpRead                      /* Read from file */
    22  	OpWrite                     /* Write to file */
    23  	OpClose                     /* Close file */
    24  	OpSearchOpen                /* Start new search */
    25  	OpSearchRead                /* Get next search response */
    26  	OpSearchClose               /* End a search */
    27  	OpGetattr                   /* Get file attributes */
    28  	OpSetattr                   /* Set file attributes */
    29  	OpCreateDir                 /* Create new directory */
    30  	OpDeleteFile                /* Delete a file */
    31  	OpDeleteDir                 /* Delete a directory */
    32  	OpRename                    /* Rename a file or directory */
    33  	OpQueryVolumeInfo           /* Query volume information */
    34  	OpOpenV2                    /* Open file */
    35  	OpGetattrV2                 /* Get file attributes */
    36  	OpSetattrV2                 /* Set file attributes */
    37  	OpSearchReadV2              /* Get next search response */
    38  	OpCreateSymlink             /* Create a symlink */
    39  	OpServerLockChange          /* Change the oplock on a file */
    40  	OpCreateDirV2               /* Create a directory */
    41  	OpDeleteFileV2              /* Delete a file */
    42  	OpDeleteDirV2               /* Delete a directory */
    43  	OpRenameV2                  /* Rename a file or directory */
    44  	OpOpenV3                    /* Open file */
    45  	OpReadV3                    /* Read from file */
    46  	OpWriteV3                   /* Write to file */
    47  	OpCloseV3                   /* Close file */
    48  	OpSearchOpenV3              /* Start new search */
    49  	OpSearchReadV3              /* Read V3 directory entries */
    50  	OpSearchCloseV3             /* End a search */
    51  	OpGetattrV3                 /* Get file attributes */
    52  	OpSetattrV3                 /* Set file attributes */
    53  	OpCreateDirV3               /* Create new directory */
    54  	OpDeleteFileV3              /* Delete a file */
    55  	OpDeleteDirV3               /* Delete a directory */
    56  	OpRenameV3                  /* Rename a file or directory */
    57  	OpQueryVolumeInfoV3         /* Query volume information */
    58  	OpCreateSymlinkV3           /* Create a symlink */
    59  	OpServerLockChangeV3        /* Change the oplock on a file */
    60  	OpWriteWin32StreamV3        /* Write WIN32_STREAM_ID format data to file */
    61  	OpCreateSessionV4           /* Create a session and return host capabilities. */
    62  	OpDestroySessionV4          /* Destroy/close session. */
    63  	OpReadFastV4                /* Read */
    64  	OpWriteFastV4               /* Write */
    65  	OpSetWatchV4                /* Start monitoring directory changes. */
    66  	OpRemoveWatchV4             /* Stop monitoring directory changes. */
    67  	OpNotifyV4                  /* Notification for a directory change event. */
    68  	OpSearchReadV4              /* Read V4 directory entries. */
    69  	OpOpenV4                    /* Open file */
    70  	OpEnumerateStreamsV4        /* Enumerate alternative named streams for a file. */
    71  	OpGetattrV4                 /* Get file attributes */
    72  	OpSetattrV4                 /* Set file attributes */
    73  	OpDeleteV4                  /* Delete a file or a directory */
    74  	OpLinkmoveV4                /* Rename/move/create hard link. */
    75  	OpFsctlV4                   /* Sending FS control requests. */
    76  	OpAccessCheckV4             /* Access check. */
    77  	OpFsyncV4                   /* Flush all cached data to the disk. */
    78  	OpQueryVolumeInfoV4         /* Query volume information. */
    79  	OpOplockAcquireV4           /* Acquire OPLOCK. */
    80  	OpOplockBreakV4             /* Break or downgrade OPLOCK. */
    81  	OpLockByteRangeV4           /* Acquire byte range lock. */
    82  	OpUnlockByteRangeV4         /* Release byte range lock. */
    83  	OpQueryEasV4                /* Query extended attributes. */
    84  	OpSetEasV4                  /* Add or modify extended attributes. */
    85  	OpNewHeader          = 0xff /* Header op, must be unique, distinguishes packet headers. */
    86  )
    87  
    88  // Status codes
    89  const (
    90  	StatusSuccess = iota
    91  	StatusNoSuchFileOrDir
    92  	StatusInvalidHandle
    93  	StatusOperationNotPermitted
    94  	StatusFileExists
    95  	StatusNotDirectory
    96  	StatusDirNotEmpty
    97  	StatusProtocolError
    98  	StatusAccessDenied
    99  	StatusInvalidName
   100  	StatusGenericError
   101  	StatusSharingViolation
   102  	StatusNoSpace
   103  	StatusOperationNotSupported
   104  	StatusNameTooLong
   105  	StatusInvalidParameter
   106  	StatusNotSameDevice
   107  	StatusStaleSession
   108  	StatusTooManySessions
   109  	StatusTransportError
   110  )
   111  
   112  // Flags for attr mask
   113  const (
   114  	AttrValidType = 1 << iota
   115  	AttrValidSize
   116  	AttrValidCreateTime
   117  	AttrValidAccessTime
   118  	AttrValidWriteTime
   119  	AttrValidChangeTime
   120  	AttrValidSpecialPerms
   121  	AttrValidOwnerPerms
   122  	AttrValidGroupPerms
   123  	AttrValidOtherPerms
   124  	AttrValidFlags
   125  	AttrValidAllocationSize
   126  	AttrValidUserID
   127  	AttrValidGroupID
   128  	AttrValidFileID
   129  	AttrValidVolID
   130  	AttrValidNonStaticFileID
   131  	AttrValidEffectivePerms
   132  	AttrValidExtendAttrSize
   133  	AttrValidReparsePoint
   134  	AttrValidShortName
   135  )
   136  
   137  // HeaderVersion for HGFS protocol version 4
   138  const HeaderVersion = 0x1
   139  
   140  // LargePacketMax is maximum size of an hgfs packet
   141  const LargePacketMax = 0xf800 // HGFS_LARGE_PACKET_MAX
   142  
   143  // Packet flags
   144  const (
   145  	PacketFlagRequest = 1 << iota
   146  	PacketFlagReply
   147  	PacketFlagInfoExterror
   148  	PacketFlagValidFlags = 0x7
   149  )
   150  
   151  // Status is an error type that encapsulates an error status code and the cause
   152  type Status struct {
   153  	Err  error
   154  	Code uint32
   155  }
   156  
   157  func (s *Status) Error() string {
   158  	if s.Err != nil {
   159  		return s.Err.Error()
   160  	}
   161  
   162  	return fmt.Sprintf("hgfs.Status=%d", s.Code)
   163  }
   164  
   165  // errorStatus maps the given error type to a status code
   166  func errorStatus(err error) uint32 {
   167  	if x, ok := err.(*Status); ok {
   168  		return x.Code
   169  	}
   170  
   171  	switch {
   172  	case os.IsNotExist(err):
   173  		return StatusNoSuchFileOrDir
   174  	case os.IsExist(err):
   175  		return StatusFileExists
   176  	case os.IsPermission(err):
   177  		return StatusOperationNotPermitted
   178  	}
   179  
   180  	return StatusGenericError
   181  }
   182  
   183  // ProtocolError wraps the given error as a Status type
   184  func ProtocolError(err error) error {
   185  	return &Status{
   186  		Err:  err,
   187  		Code: StatusProtocolError,
   188  	}
   189  }
   190  
   191  // Request as defined in hgfsProto.h:HgfsRequest
   192  type Request struct {
   193  	Handle uint32
   194  	Op     int32
   195  }
   196  
   197  // Reply as defined in hgfsProto.h:HgfsReply
   198  type Reply struct {
   199  	Handle uint32
   200  	Status uint32
   201  }
   202  
   203  // Header as defined in hgfsProto.h:HgfsHeader
   204  type Header struct {
   205  	Version     uint8
   206  	Reserved1   [3]uint8
   207  	Dummy       int32
   208  	PacketSize  uint32
   209  	HeaderSize  uint32
   210  	RequestID   uint32
   211  	Op          int32
   212  	Status      uint32
   213  	Flags       uint32
   214  	Information uint32
   215  	SessionID   uint64
   216  	Reserved    uint64
   217  }
   218  
   219  var (
   220  	headerSize = uint32(binary.Size(new(Header)))
   221  
   222  	packetSize = func(r *Packet) uint32 {
   223  		return headerSize + uint32(len(r.Payload))
   224  	}
   225  )
   226  
   227  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   228  func (h *Header) UnmarshalBinary(data []byte) error {
   229  	buf := bytes.NewBuffer(data)
   230  
   231  	err := binary.Read(buf, binary.LittleEndian, h)
   232  	if err != nil {
   233  		return fmt.Errorf("reading hgfs header: %s", err)
   234  	}
   235  
   236  	if h.Dummy != OpNewHeader {
   237  		return fmt.Errorf("expected hgfs header with OpNewHeader (%#x), got: %#x", OpNewHeader, h.Dummy)
   238  	}
   239  
   240  	return nil
   241  }
   242  
   243  // Packet encapsulates an hgfs Header and Payload
   244  type Packet struct {
   245  	Header
   246  
   247  	Payload []byte
   248  }
   249  
   250  // Reply composes a new Packet with the given payload or error
   251  func (r *Packet) Reply(payload any, err error) ([]byte, error) {
   252  	p := new(Packet)
   253  
   254  	status := uint32(StatusSuccess)
   255  
   256  	if err != nil {
   257  		status = errorStatus(err)
   258  	} else {
   259  		p.Payload, err = MarshalBinary(payload)
   260  		if err != nil {
   261  			return nil, err
   262  		}
   263  	}
   264  
   265  	p.Header = Header{
   266  		Version:     HeaderVersion,
   267  		Dummy:       OpNewHeader,
   268  		PacketSize:  headerSize + uint32(len(p.Payload)),
   269  		HeaderSize:  headerSize,
   270  		RequestID:   r.RequestID,
   271  		Op:          r.Op,
   272  		Status:      status,
   273  		Flags:       PacketFlagReply,
   274  		Information: 0,
   275  		SessionID:   r.SessionID,
   276  	}
   277  
   278  	if Trace {
   279  		rc := "OK"
   280  		if err != nil {
   281  			rc = err.Error()
   282  		}
   283  		fmt.Fprintf(os.Stderr, "[hgfs] response %#v [%s]\n", p.Header, rc)
   284  	} else if err != nil {
   285  		log.Printf("[hgfs] op=%d error: %s", r.Op, err)
   286  	}
   287  
   288  	return p.MarshalBinary()
   289  }
   290  
   291  // MarshalBinary implements the encoding.BinaryMarshaler interface
   292  func (r *Packet) MarshalBinary() ([]byte, error) {
   293  	r.Header.PacketSize = packetSize(r)
   294  
   295  	buf, _ := MarshalBinary(r.Header)
   296  
   297  	return append(buf, r.Payload...), nil
   298  }
   299  
   300  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   301  func (r *Packet) UnmarshalBinary(data []byte) error {
   302  	err := r.Header.UnmarshalBinary(data)
   303  	if err != nil {
   304  		return err
   305  	}
   306  
   307  	r.Payload = data[r.HeaderSize:r.PacketSize]
   308  
   309  	return nil
   310  }
   311  
   312  // Capability as defined in hgfsProto.h:HgfsCapability
   313  type Capability struct {
   314  	Op    int32
   315  	Flags uint32
   316  }
   317  
   318  // RequestCreateSessionV4 as defined in hgfsProto.h:HgfsRequestCreateSessionV4
   319  type RequestCreateSessionV4 struct {
   320  	NumCapabilities uint32
   321  	MaxPacketSize   uint32
   322  	Flags           uint32
   323  	Reserved        uint32
   324  	Capabilities    []Capability
   325  }
   326  
   327  // MarshalBinary implements the encoding.BinaryMarshaler interface
   328  func (r *RequestCreateSessionV4) MarshalBinary() ([]byte, error) {
   329  	buf := new(bytes.Buffer)
   330  
   331  	r.NumCapabilities = uint32(len(r.Capabilities))
   332  
   333  	fields := []*uint32{
   334  		&r.NumCapabilities,
   335  		&r.MaxPacketSize,
   336  		&r.Flags,
   337  		&r.Reserved,
   338  	}
   339  
   340  	for _, p := range fields {
   341  		err := binary.Write(buf, binary.LittleEndian, p)
   342  		if err != nil {
   343  			return nil, err
   344  		}
   345  	}
   346  
   347  	for i := uint32(0); i < r.NumCapabilities; i++ {
   348  		err := binary.Write(buf, binary.LittleEndian, &r.Capabilities[i])
   349  		if err != nil {
   350  			return nil, err
   351  		}
   352  	}
   353  
   354  	return buf.Bytes(), nil
   355  }
   356  
   357  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   358  func (r *RequestCreateSessionV4) UnmarshalBinary(data []byte) error {
   359  	buf := bytes.NewBuffer(data)
   360  
   361  	fields := []*uint32{
   362  		&r.NumCapabilities,
   363  		&r.MaxPacketSize,
   364  		&r.Flags,
   365  		&r.Reserved,
   366  	}
   367  
   368  	for _, p := range fields {
   369  		err := binary.Read(buf, binary.LittleEndian, p)
   370  		if err != nil {
   371  			return err
   372  		}
   373  	}
   374  
   375  	for i := uint32(0); i < r.NumCapabilities; i++ {
   376  		var cap Capability
   377  		err := binary.Read(buf, binary.LittleEndian, &cap)
   378  		if err != nil {
   379  			return err
   380  		}
   381  
   382  		r.Capabilities = append(r.Capabilities, cap)
   383  	}
   384  
   385  	return nil
   386  }
   387  
   388  // ReplyCreateSessionV4 as defined in hgfsProto.h:HgfsReplyCreateSessionV4
   389  type ReplyCreateSessionV4 struct {
   390  	SessionID       uint64
   391  	NumCapabilities uint32
   392  	MaxPacketSize   uint32
   393  	IdentityOffset  uint32
   394  	Flags           uint32
   395  	Reserved        uint32
   396  	Capabilities    []Capability
   397  }
   398  
   399  // MarshalBinary implements the encoding.BinaryMarshaler interface
   400  func (r *ReplyCreateSessionV4) MarshalBinary() ([]byte, error) {
   401  	buf := new(bytes.Buffer)
   402  
   403  	fields := []any{
   404  		&r.SessionID,
   405  		&r.NumCapabilities,
   406  		&r.MaxPacketSize,
   407  		&r.IdentityOffset,
   408  		&r.Flags,
   409  		&r.Reserved,
   410  	}
   411  
   412  	for _, p := range fields {
   413  		err := binary.Write(buf, binary.LittleEndian, p)
   414  		if err != nil {
   415  			return nil, err
   416  		}
   417  	}
   418  
   419  	for i := uint32(0); i < r.NumCapabilities; i++ {
   420  		err := binary.Write(buf, binary.LittleEndian, &r.Capabilities[i])
   421  		if err != nil {
   422  			return nil, err
   423  		}
   424  	}
   425  
   426  	return buf.Bytes(), nil
   427  }
   428  
   429  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   430  func (r *ReplyCreateSessionV4) UnmarshalBinary(data []byte) error {
   431  	buf := bytes.NewBuffer(data)
   432  
   433  	fields := []any{
   434  		&r.SessionID,
   435  		&r.NumCapabilities,
   436  		&r.MaxPacketSize,
   437  		&r.IdentityOffset,
   438  		&r.Flags,
   439  		&r.Reserved,
   440  	}
   441  
   442  	for _, p := range fields {
   443  		err := binary.Read(buf, binary.LittleEndian, p)
   444  		if err != nil {
   445  			return err
   446  		}
   447  	}
   448  
   449  	for i := uint32(0); i < r.NumCapabilities; i++ {
   450  		var cap Capability
   451  		err := binary.Read(buf, binary.LittleEndian, &cap)
   452  		if err != nil {
   453  			return err
   454  		}
   455  
   456  		r.Capabilities = append(r.Capabilities, cap)
   457  	}
   458  
   459  	return nil
   460  }
   461  
   462  // RequestDestroySessionV4 as defined in hgfsProto.h:HgfsRequestDestroySessionV4
   463  type RequestDestroySessionV4 struct {
   464  	Reserved uint64
   465  }
   466  
   467  // ReplyDestroySessionV4 as defined in hgfsProto.h:HgfsReplyDestroySessionV4
   468  type ReplyDestroySessionV4 struct {
   469  	Reserved uint64
   470  }
   471  
   472  // FileName as defined in hgfsProto.h:HgfsFileName
   473  type FileName struct {
   474  	Length uint32
   475  	Name   string
   476  }
   477  
   478  // MarshalBinary implements the encoding.BinaryMarshaler interface
   479  func (f *FileName) MarshalBinary() ([]byte, error) {
   480  	name := f.Name
   481  	f.Length = uint32(len(f.Name))
   482  	if f.Length == 0 {
   483  		// field is defined as 'char name[1];', this byte is required for min sizeof() validation
   484  		name = "\x00"
   485  	}
   486  	return MarshalBinary(&f.Length, name)
   487  }
   488  
   489  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   490  func (f *FileName) UnmarshalBinary(data []byte) error {
   491  	buf := bytes.NewBuffer(data)
   492  
   493  	_ = binary.Read(buf, binary.LittleEndian, &f.Length)
   494  
   495  	f.Name = string(buf.Next(int(f.Length)))
   496  
   497  	return nil
   498  }
   499  
   500  const serverPolicyRootShareName = "root"
   501  
   502  // FromString converts name to a FileName
   503  func (f *FileName) FromString(name string) {
   504  	name = strings.TrimPrefix(name, "/")
   505  
   506  	cp := strings.Split(name, "/")
   507  
   508  	cp = append([]string{serverPolicyRootShareName}, cp...)
   509  
   510  	f.Name = strings.Join(cp, "\x00")
   511  	f.Length = uint32(len(f.Name))
   512  }
   513  
   514  // Path converts FileName to a string
   515  func (f *FileName) Path() string {
   516  	cp := strings.Split(f.Name, "\x00")
   517  
   518  	if len(cp) == 0 || cp[0] != serverPolicyRootShareName {
   519  		return "" // TODO: not happening until if/when we handle Windows shares
   520  	}
   521  
   522  	cp[0] = ""
   523  
   524  	return strings.Join(cp, "/")
   525  }
   526  
   527  // FileNameV3 as defined in hgfsProto.h:HgfsFileNameV3
   528  type FileNameV3 struct {
   529  	Length   uint32
   530  	Flags    uint32
   531  	CaseType int32
   532  	ID       uint32
   533  	Name     string
   534  }
   535  
   536  // MarshalBinary implements the encoding.BinaryMarshaler interface
   537  func (f *FileNameV3) MarshalBinary() ([]byte, error) {
   538  	name := f.Name
   539  	f.Length = uint32(len(f.Name))
   540  	if f.Length == 0 {
   541  		// field is defined as 'char name[1];', this byte is required for min sizeof() validation
   542  		name = "\x00"
   543  	}
   544  	return MarshalBinary(&f.Length, &f.Flags, &f.CaseType, &f.ID, name)
   545  }
   546  
   547  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   548  func (f *FileNameV3) UnmarshalBinary(data []byte) error {
   549  	buf := bytes.NewBuffer(data)
   550  
   551  	fields := []any{
   552  		&f.Length, &f.Flags, &f.CaseType, &f.ID,
   553  	}
   554  
   555  	for _, p := range fields {
   556  		if err := binary.Read(buf, binary.LittleEndian, p); err != nil {
   557  			return err
   558  		}
   559  	}
   560  
   561  	f.Name = string(buf.Next(int(f.Length)))
   562  
   563  	return nil
   564  }
   565  
   566  // FromString converts name to a FileNameV3
   567  func (f *FileNameV3) FromString(name string) {
   568  	p := new(FileName)
   569  	p.FromString(name)
   570  	f.Name = p.Name
   571  	f.Length = p.Length
   572  }
   573  
   574  // Path converts FileNameV3 to a string
   575  func (f *FileNameV3) Path() string {
   576  	return (&FileName{Name: f.Name, Length: f.Length}).Path()
   577  }
   578  
   579  // FileType
   580  const (
   581  	FileTypeRegular = iota
   582  	FileTypeDirectory
   583  	FileTypeSymlink
   584  )
   585  
   586  // AttrV2 as defined in hgfsProto.h:HgfsAttrV2
   587  type AttrV2 struct {
   588  	Mask           uint64
   589  	Type           int32
   590  	Size           uint64
   591  	CreationTime   uint64
   592  	AccessTime     uint64
   593  	WriteTime      uint64
   594  	AttrChangeTime uint64
   595  	SpecialPerms   uint8
   596  	OwnerPerms     uint8
   597  	GroupPerms     uint8
   598  	OtherPerms     uint8
   599  	AttrFlags      uint64
   600  	AllocationSize uint64
   601  	UserID         uint32
   602  	GroupID        uint32
   603  	HostFileID     uint64
   604  	VolumeID       uint32
   605  	EffectivePerms uint32
   606  	Reserved2      uint64
   607  }
   608  
   609  // RequestGetattrV2 as defined in hgfsProto.h:HgfsRequestGetattrV2
   610  type RequestGetattrV2 struct {
   611  	Request
   612  	AttrHint uint64
   613  	Handle   uint32
   614  	FileName FileName
   615  }
   616  
   617  // MarshalBinary implements the encoding.BinaryMarshaler interface
   618  func (r *RequestGetattrV2) MarshalBinary() ([]byte, error) {
   619  	return MarshalBinary(&r.Request, &r.AttrHint, &r.Handle, &r.FileName)
   620  }
   621  
   622  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   623  func (r *RequestGetattrV2) UnmarshalBinary(data []byte) error {
   624  	return UnmarshalBinary(data, &r.Request, &r.AttrHint, &r.Handle, &r.FileName)
   625  }
   626  
   627  // ReplyGetattrV2 as defined in hgfsProto.h:HgfsReplyGetattrV2
   628  type ReplyGetattrV2 struct {
   629  	Reply
   630  	Attr          AttrV2
   631  	SymlinkTarget FileName
   632  }
   633  
   634  // MarshalBinary implements the encoding.BinaryMarshaler interface
   635  func (r *ReplyGetattrV2) MarshalBinary() ([]byte, error) {
   636  	return MarshalBinary(&r.Reply, &r.Attr, &r.SymlinkTarget)
   637  }
   638  
   639  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   640  func (r *ReplyGetattrV2) UnmarshalBinary(data []byte) error {
   641  	return UnmarshalBinary(data, &r.Reply, &r.Attr, &r.SymlinkTarget)
   642  }
   643  
   644  // RequestSetattrV2 as defined in hgfsProto.h:HgfsRequestSetattrV2
   645  type RequestSetattrV2 struct {
   646  	Request
   647  	Hints    uint64
   648  	Attr     AttrV2
   649  	Handle   uint32
   650  	FileName FileName
   651  }
   652  
   653  // MarshalBinary implements the encoding.BinaryMarshaler interface
   654  func (r *RequestSetattrV2) MarshalBinary() ([]byte, error) {
   655  	return MarshalBinary(&r.Request, &r.Hints, &r.Attr, &r.Handle, &r.FileName)
   656  }
   657  
   658  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   659  func (r *RequestSetattrV2) UnmarshalBinary(data []byte) error {
   660  	return UnmarshalBinary(data, &r.Request, &r.Hints, &r.Attr, &r.Handle, &r.FileName)
   661  }
   662  
   663  // ReplySetattrV2 as defined in hgfsProto.h:HgfsReplySetattrV2
   664  type ReplySetattrV2 struct {
   665  	Header Reply
   666  }
   667  
   668  // OpenMode
   669  const (
   670  	OpenModeReadOnly = iota
   671  	OpenModeWriteOnly
   672  	OpenModeReadWrite
   673  	OpenModeAccmodes
   674  )
   675  
   676  // OpenFlags
   677  const (
   678  	Open = iota
   679  	OpenEmpty
   680  	OpenCreate
   681  	OpenCreateSafe
   682  	OpenCreateEmpty
   683  )
   684  
   685  // Permissions
   686  const (
   687  	PermRead  = 4
   688  	PermWrite = 2
   689  	PermExec  = 1
   690  )
   691  
   692  // RequestOpen as defined in hgfsProto.h:HgfsRequestOpen
   693  type RequestOpen struct {
   694  	Request
   695  	OpenMode    int32
   696  	OpenFlags   int32
   697  	Permissions uint8
   698  	FileName    FileName
   699  }
   700  
   701  // MarshalBinary implements the encoding.BinaryMarshaler interface
   702  func (r *RequestOpen) MarshalBinary() ([]byte, error) {
   703  	return MarshalBinary(&r.Request, &r.OpenMode, &r.OpenFlags, r.Permissions, &r.FileName)
   704  }
   705  
   706  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   707  func (r *RequestOpen) UnmarshalBinary(data []byte) error {
   708  	return UnmarshalBinary(data, &r.Request, &r.OpenMode, &r.OpenFlags, &r.Permissions, &r.FileName)
   709  }
   710  
   711  // ReplyOpen as defined in hgfsProto.h:HgfsReplyOpen
   712  type ReplyOpen struct {
   713  	Reply
   714  	Handle uint32
   715  }
   716  
   717  // RequestClose as defined in hgfsProto.h:HgfsRequestClose
   718  type RequestClose struct {
   719  	Request
   720  	Handle uint32
   721  }
   722  
   723  // ReplyClose as defined in hgfsProto.h:HgfsReplyClose
   724  type ReplyClose struct {
   725  	Reply
   726  }
   727  
   728  // Lock type
   729  const (
   730  	LockNone = iota
   731  	LockOpportunistic
   732  	LockExclusive
   733  	LockShared
   734  	LockBatch
   735  	LockLease
   736  )
   737  
   738  // RequestOpenV3 as defined in hgfsProto.h:HgfsRequestOpenV3
   739  type RequestOpenV3 struct {
   740  	Mask           uint64
   741  	OpenMode       int32
   742  	OpenFlags      int32
   743  	SpecialPerms   uint8
   744  	OwnerPerms     uint8
   745  	GroupPerms     uint8
   746  	OtherPerms     uint8
   747  	AttrFlags      uint64
   748  	AllocationSize uint64
   749  	DesiredAccess  uint32
   750  	ShareAccess    uint32
   751  	DesiredLock    int32
   752  	Reserved1      uint64
   753  	Reserved2      uint64
   754  	FileName       FileNameV3
   755  }
   756  
   757  // MarshalBinary implements the encoding.BinaryMarshaler interface
   758  func (r *RequestOpenV3) MarshalBinary() ([]byte, error) {
   759  	return MarshalBinary(&r.Mask, &r.OpenMode, &r.OpenFlags,
   760  		&r.SpecialPerms, &r.OwnerPerms, &r.GroupPerms, &r.OtherPerms,
   761  		&r.AttrFlags, &r.AllocationSize, &r.DesiredAccess, &r.ShareAccess,
   762  		&r.DesiredLock, &r.Reserved1, &r.Reserved2, &r.FileName)
   763  }
   764  
   765  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   766  func (r *RequestOpenV3) UnmarshalBinary(data []byte) error {
   767  	return UnmarshalBinary(data, &r.Mask, &r.OpenMode, &r.OpenFlags,
   768  		&r.SpecialPerms, &r.OwnerPerms, &r.GroupPerms, &r.OtherPerms,
   769  		&r.AttrFlags, &r.AllocationSize, &r.DesiredAccess, &r.ShareAccess,
   770  		&r.DesiredLock, &r.Reserved1, &r.Reserved2, &r.FileName)
   771  }
   772  
   773  // ReplyOpenV3 as defined in hgfsProto.h:HgfsReplyOpenV3
   774  type ReplyOpenV3 struct {
   775  	Handle       uint32
   776  	AcquiredLock int32
   777  	Flags        int32
   778  	Reserved     uint32
   779  }
   780  
   781  // RequestReadV3 as defined in hgfsProto.h:HgfsRequestReadV3
   782  type RequestReadV3 struct {
   783  	Handle       uint32
   784  	Offset       uint64
   785  	RequiredSize uint32
   786  	Reserved     uint64
   787  }
   788  
   789  // ReplyReadV3 as defined in hgfsProto.h:HgfsReplyReadV3
   790  type ReplyReadV3 struct {
   791  	ActualSize uint32
   792  	Reserved   uint64
   793  	Payload    []byte
   794  }
   795  
   796  // MarshalBinary implements the encoding.BinaryMarshaler interface
   797  func (r *ReplyReadV3) MarshalBinary() ([]byte, error) {
   798  	return MarshalBinary(&r.ActualSize, &r.Reserved, r.Payload)
   799  }
   800  
   801  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   802  func (r *ReplyReadV3) UnmarshalBinary(data []byte) error {
   803  	return UnmarshalBinary(data, &r.ActualSize, &r.Reserved, &r.Payload)
   804  }
   805  
   806  // Write flags
   807  const (
   808  	WriteAppend = 1
   809  )
   810  
   811  // RequestWriteV3 as defined in hgfsProto.h:HgfsRequestWriteV3
   812  type RequestWriteV3 struct {
   813  	Handle       uint32
   814  	WriteFlags   uint8
   815  	Offset       uint64
   816  	RequiredSize uint32
   817  	Reserved     uint64
   818  	Payload      []byte
   819  }
   820  
   821  // MarshalBinary implements the encoding.BinaryMarshaler interface
   822  func (r *RequestWriteV3) MarshalBinary() ([]byte, error) {
   823  	return MarshalBinary(&r.Handle, &r.WriteFlags, &r.Offset, &r.RequiredSize, &r.Reserved, r.Payload)
   824  }
   825  
   826  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
   827  func (r *RequestWriteV3) UnmarshalBinary(data []byte) error {
   828  	return UnmarshalBinary(data, &r.Handle, &r.WriteFlags, &r.Offset, &r.RequiredSize, &r.Reserved, &r.Payload)
   829  }
   830  
   831  // ReplyWriteV3 as defined in hgfsProto.h:HgfsReplyWriteV3
   832  type ReplyWriteV3 struct {
   833  	ActualSize uint32
   834  	Reserved   uint64
   835  }