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