mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 05:57:25 +00:00
Bumping version to include changes that better handle TLS errors. Bump nescessary to prepare for when the version of Go is bumped to 1.20 Signed-off-by: Madhav Jivrajani <madhav.jiv@gmail.com>
848 lines
21 KiB
Go
848 lines
21 KiB
Go
/*
|
|
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package hgfs
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// See: https://github.com/vmware/open-vm-tools/blob/master/open-vm-tools/lib/include/hgfsProto.h
|
|
|
|
// Opcodes for server operations as defined in hgfsProto.h
|
|
const (
|
|
OpOpen = iota /* Open file */
|
|
OpRead /* Read from file */
|
|
OpWrite /* Write to file */
|
|
OpClose /* Close file */
|
|
OpSearchOpen /* Start new search */
|
|
OpSearchRead /* Get next search response */
|
|
OpSearchClose /* End a search */
|
|
OpGetattr /* Get file attributes */
|
|
OpSetattr /* Set file attributes */
|
|
OpCreateDir /* Create new directory */
|
|
OpDeleteFile /* Delete a file */
|
|
OpDeleteDir /* Delete a directory */
|
|
OpRename /* Rename a file or directory */
|
|
OpQueryVolumeInfo /* Query volume information */
|
|
OpOpenV2 /* Open file */
|
|
OpGetattrV2 /* Get file attributes */
|
|
OpSetattrV2 /* Set file attributes */
|
|
OpSearchReadV2 /* Get next search response */
|
|
OpCreateSymlink /* Create a symlink */
|
|
OpServerLockChange /* Change the oplock on a file */
|
|
OpCreateDirV2 /* Create a directory */
|
|
OpDeleteFileV2 /* Delete a file */
|
|
OpDeleteDirV2 /* Delete a directory */
|
|
OpRenameV2 /* Rename a file or directory */
|
|
OpOpenV3 /* Open file */
|
|
OpReadV3 /* Read from file */
|
|
OpWriteV3 /* Write to file */
|
|
OpCloseV3 /* Close file */
|
|
OpSearchOpenV3 /* Start new search */
|
|
OpSearchReadV3 /* Read V3 directory entries */
|
|
OpSearchCloseV3 /* End a search */
|
|
OpGetattrV3 /* Get file attributes */
|
|
OpSetattrV3 /* Set file attributes */
|
|
OpCreateDirV3 /* Create new directory */
|
|
OpDeleteFileV3 /* Delete a file */
|
|
OpDeleteDirV3 /* Delete a directory */
|
|
OpRenameV3 /* Rename a file or directory */
|
|
OpQueryVolumeInfoV3 /* Query volume information */
|
|
OpCreateSymlinkV3 /* Create a symlink */
|
|
OpServerLockChangeV3 /* Change the oplock on a file */
|
|
OpWriteWin32StreamV3 /* Write WIN32_STREAM_ID format data to file */
|
|
OpCreateSessionV4 /* Create a session and return host capabilities. */
|
|
OpDestroySessionV4 /* Destroy/close session. */
|
|
OpReadFastV4 /* Read */
|
|
OpWriteFastV4 /* Write */
|
|
OpSetWatchV4 /* Start monitoring directory changes. */
|
|
OpRemoveWatchV4 /* Stop monitoring directory changes. */
|
|
OpNotifyV4 /* Notification for a directory change event. */
|
|
OpSearchReadV4 /* Read V4 directory entries. */
|
|
OpOpenV4 /* Open file */
|
|
OpEnumerateStreamsV4 /* Enumerate alternative named streams for a file. */
|
|
OpGetattrV4 /* Get file attributes */
|
|
OpSetattrV4 /* Set file attributes */
|
|
OpDeleteV4 /* Delete a file or a directory */
|
|
OpLinkmoveV4 /* Rename/move/create hard link. */
|
|
OpFsctlV4 /* Sending FS control requests. */
|
|
OpAccessCheckV4 /* Access check. */
|
|
OpFsyncV4 /* Flush all cached data to the disk. */
|
|
OpQueryVolumeInfoV4 /* Query volume information. */
|
|
OpOplockAcquireV4 /* Acquire OPLOCK. */
|
|
OpOplockBreakV4 /* Break or downgrade OPLOCK. */
|
|
OpLockByteRangeV4 /* Acquire byte range lock. */
|
|
OpUnlockByteRangeV4 /* Release byte range lock. */
|
|
OpQueryEasV4 /* Query extended attributes. */
|
|
OpSetEasV4 /* Add or modify extended attributes. */
|
|
OpNewHeader = 0xff /* Header op, must be unique, distinguishes packet headers. */
|
|
)
|
|
|
|
// Status codes
|
|
const (
|
|
StatusSuccess = iota
|
|
StatusNoSuchFileOrDir
|
|
StatusInvalidHandle
|
|
StatusOperationNotPermitted
|
|
StatusFileExists
|
|
StatusNotDirectory
|
|
StatusDirNotEmpty
|
|
StatusProtocolError
|
|
StatusAccessDenied
|
|
StatusInvalidName
|
|
StatusGenericError
|
|
StatusSharingViolation
|
|
StatusNoSpace
|
|
StatusOperationNotSupported
|
|
StatusNameTooLong
|
|
StatusInvalidParameter
|
|
StatusNotSameDevice
|
|
StatusStaleSession
|
|
StatusTooManySessions
|
|
StatusTransportError
|
|
)
|
|
|
|
// Flags for attr mask
|
|
const (
|
|
AttrValidType = 1 << iota
|
|
AttrValidSize
|
|
AttrValidCreateTime
|
|
AttrValidAccessTime
|
|
AttrValidWriteTime
|
|
AttrValidChangeTime
|
|
AttrValidSpecialPerms
|
|
AttrValidOwnerPerms
|
|
AttrValidGroupPerms
|
|
AttrValidOtherPerms
|
|
AttrValidFlags
|
|
AttrValidAllocationSize
|
|
AttrValidUserID
|
|
AttrValidGroupID
|
|
AttrValidFileID
|
|
AttrValidVolID
|
|
AttrValidNonStaticFileID
|
|
AttrValidEffectivePerms
|
|
AttrValidExtendAttrSize
|
|
AttrValidReparsePoint
|
|
AttrValidShortName
|
|
)
|
|
|
|
// HeaderVersion for HGFS protocol version 4
|
|
const HeaderVersion = 0x1
|
|
|
|
// LargePacketMax is maximum size of an hgfs packet
|
|
const LargePacketMax = 0xf800 // HGFS_LARGE_PACKET_MAX
|
|
|
|
// Packet flags
|
|
const (
|
|
PacketFlagRequest = 1 << iota
|
|
PacketFlagReply
|
|
PacketFlagInfoExterror
|
|
PacketFlagValidFlags = 0x7
|
|
)
|
|
|
|
// Status is an error type that encapsulates an error status code and the cause
|
|
type Status struct {
|
|
Err error
|
|
Code uint32
|
|
}
|
|
|
|
func (s *Status) Error() string {
|
|
if s.Err != nil {
|
|
return s.Err.Error()
|
|
}
|
|
|
|
return fmt.Sprintf("hgfs.Status=%d", s.Code)
|
|
}
|
|
|
|
// errorStatus maps the given error type to a status code
|
|
func errorStatus(err error) uint32 {
|
|
if x, ok := err.(*Status); ok {
|
|
return x.Code
|
|
}
|
|
|
|
switch {
|
|
case os.IsNotExist(err):
|
|
return StatusNoSuchFileOrDir
|
|
case os.IsExist(err):
|
|
return StatusFileExists
|
|
case os.IsPermission(err):
|
|
return StatusOperationNotPermitted
|
|
}
|
|
|
|
return StatusGenericError
|
|
}
|
|
|
|
// ProtocolError wraps the given error as a Status type
|
|
func ProtocolError(err error) error {
|
|
return &Status{
|
|
Err: err,
|
|
Code: StatusProtocolError,
|
|
}
|
|
}
|
|
|
|
// Request as defined in hgfsProto.h:HgfsRequest
|
|
type Request struct {
|
|
Handle uint32
|
|
Op int32
|
|
}
|
|
|
|
// Reply as defined in hgfsProto.h:HgfsReply
|
|
type Reply struct {
|
|
Handle uint32
|
|
Status uint32
|
|
}
|
|
|
|
// Header as defined in hgfsProto.h:HgfsHeader
|
|
type Header struct {
|
|
Version uint8
|
|
Reserved1 [3]uint8
|
|
Dummy int32
|
|
PacketSize uint32
|
|
HeaderSize uint32
|
|
RequestID uint32
|
|
Op int32
|
|
Status uint32
|
|
Flags uint32
|
|
Information uint32
|
|
SessionID uint64
|
|
Reserved uint64
|
|
}
|
|
|
|
var (
|
|
headerSize = uint32(binary.Size(new(Header)))
|
|
|
|
packetSize = func(r *Packet) uint32 {
|
|
return headerSize + uint32(len(r.Payload))
|
|
}
|
|
)
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (h *Header) UnmarshalBinary(data []byte) error {
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
err := binary.Read(buf, binary.LittleEndian, h)
|
|
if err != nil {
|
|
return fmt.Errorf("reading hgfs header: %s", err)
|
|
}
|
|
|
|
if h.Dummy != OpNewHeader {
|
|
return fmt.Errorf("expected hgfs header with OpNewHeader (%#x), got: %#x", OpNewHeader, h.Dummy)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Packet encapsulates an hgfs Header and Payload
|
|
type Packet struct {
|
|
Header
|
|
|
|
Payload []byte
|
|
}
|
|
|
|
// Reply composes a new Packet with the given payload or error
|
|
func (r *Packet) Reply(payload interface{}, err error) ([]byte, error) {
|
|
p := new(Packet)
|
|
|
|
status := uint32(StatusSuccess)
|
|
|
|
if err != nil {
|
|
status = errorStatus(err)
|
|
} else {
|
|
p.Payload, err = MarshalBinary(payload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
p.Header = Header{
|
|
Version: HeaderVersion,
|
|
Dummy: OpNewHeader,
|
|
PacketSize: headerSize + uint32(len(p.Payload)),
|
|
HeaderSize: headerSize,
|
|
RequestID: r.RequestID,
|
|
Op: r.Op,
|
|
Status: status,
|
|
Flags: PacketFlagReply,
|
|
Information: 0,
|
|
SessionID: r.SessionID,
|
|
}
|
|
|
|
if Trace {
|
|
rc := "OK"
|
|
if err != nil {
|
|
rc = err.Error()
|
|
}
|
|
fmt.Fprintf(os.Stderr, "[hgfs] response %#v [%s]\n", p.Header, rc)
|
|
} else if err != nil {
|
|
log.Printf("[hgfs] op=%d error: %s", r.Op, err)
|
|
}
|
|
|
|
return p.MarshalBinary()
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *Packet) MarshalBinary() ([]byte, error) {
|
|
r.Header.PacketSize = packetSize(r)
|
|
|
|
buf, _ := MarshalBinary(r.Header)
|
|
|
|
return append(buf, r.Payload...), nil
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *Packet) UnmarshalBinary(data []byte) error {
|
|
err := r.Header.UnmarshalBinary(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
r.Payload = data[r.HeaderSize:r.PacketSize]
|
|
|
|
return nil
|
|
}
|
|
|
|
// Capability as defined in hgfsProto.h:HgfsCapability
|
|
type Capability struct {
|
|
Op int32
|
|
Flags uint32
|
|
}
|
|
|
|
// RequestCreateSessionV4 as defined in hgfsProto.h:HgfsRequestCreateSessionV4
|
|
type RequestCreateSessionV4 struct {
|
|
NumCapabilities uint32
|
|
MaxPacketSize uint32
|
|
Flags uint32
|
|
Reserved uint32
|
|
Capabilities []Capability
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestCreateSessionV4) MarshalBinary() ([]byte, error) {
|
|
buf := new(bytes.Buffer)
|
|
|
|
r.NumCapabilities = uint32(len(r.Capabilities))
|
|
|
|
fields := []*uint32{
|
|
&r.NumCapabilities,
|
|
&r.MaxPacketSize,
|
|
&r.Flags,
|
|
&r.Reserved,
|
|
}
|
|
|
|
for _, p := range fields {
|
|
err := binary.Write(buf, binary.LittleEndian, p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
for i := uint32(0); i < r.NumCapabilities; i++ {
|
|
err := binary.Write(buf, binary.LittleEndian, &r.Capabilities[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestCreateSessionV4) UnmarshalBinary(data []byte) error {
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
fields := []*uint32{
|
|
&r.NumCapabilities,
|
|
&r.MaxPacketSize,
|
|
&r.Flags,
|
|
&r.Reserved,
|
|
}
|
|
|
|
for _, p := range fields {
|
|
err := binary.Read(buf, binary.LittleEndian, p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for i := uint32(0); i < r.NumCapabilities; i++ {
|
|
var cap Capability
|
|
err := binary.Read(buf, binary.LittleEndian, &cap)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
r.Capabilities = append(r.Capabilities, cap)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ReplyCreateSessionV4 as defined in hgfsProto.h:HgfsReplyCreateSessionV4
|
|
type ReplyCreateSessionV4 struct {
|
|
SessionID uint64
|
|
NumCapabilities uint32
|
|
MaxPacketSize uint32
|
|
IdentityOffset uint32
|
|
Flags uint32
|
|
Reserved uint32
|
|
Capabilities []Capability
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *ReplyCreateSessionV4) MarshalBinary() ([]byte, error) {
|
|
buf := new(bytes.Buffer)
|
|
|
|
fields := []interface{}{
|
|
&r.SessionID,
|
|
&r.NumCapabilities,
|
|
&r.MaxPacketSize,
|
|
&r.IdentityOffset,
|
|
&r.Flags,
|
|
&r.Reserved,
|
|
}
|
|
|
|
for _, p := range fields {
|
|
err := binary.Write(buf, binary.LittleEndian, p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
for i := uint32(0); i < r.NumCapabilities; i++ {
|
|
err := binary.Write(buf, binary.LittleEndian, &r.Capabilities[i])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *ReplyCreateSessionV4) UnmarshalBinary(data []byte) error {
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
fields := []interface{}{
|
|
&r.SessionID,
|
|
&r.NumCapabilities,
|
|
&r.MaxPacketSize,
|
|
&r.IdentityOffset,
|
|
&r.Flags,
|
|
&r.Reserved,
|
|
}
|
|
|
|
for _, p := range fields {
|
|
err := binary.Read(buf, binary.LittleEndian, p)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for i := uint32(0); i < r.NumCapabilities; i++ {
|
|
var cap Capability
|
|
err := binary.Read(buf, binary.LittleEndian, &cap)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
r.Capabilities = append(r.Capabilities, cap)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RequestDestroySessionV4 as defined in hgfsProto.h:HgfsRequestDestroySessionV4
|
|
type RequestDestroySessionV4 struct {
|
|
Reserved uint64
|
|
}
|
|
|
|
// ReplyDestroySessionV4 as defined in hgfsProto.h:HgfsReplyDestroySessionV4
|
|
type ReplyDestroySessionV4 struct {
|
|
Reserved uint64
|
|
}
|
|
|
|
// FileName as defined in hgfsProto.h:HgfsFileName
|
|
type FileName struct {
|
|
Length uint32
|
|
Name string
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (f *FileName) MarshalBinary() ([]byte, error) {
|
|
name := f.Name
|
|
f.Length = uint32(len(f.Name))
|
|
if f.Length == 0 {
|
|
// field is defined as 'char name[1];', this byte is required for min sizeof() validation
|
|
name = "\x00"
|
|
}
|
|
return MarshalBinary(&f.Length, name)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (f *FileName) UnmarshalBinary(data []byte) error {
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
_ = binary.Read(buf, binary.LittleEndian, &f.Length)
|
|
|
|
f.Name = string(buf.Next(int(f.Length)))
|
|
|
|
return nil
|
|
}
|
|
|
|
const serverPolicyRootShareName = "root"
|
|
|
|
// FromString converts name to a FileName
|
|
func (f *FileName) FromString(name string) {
|
|
name = strings.TrimPrefix(name, "/")
|
|
|
|
cp := strings.Split(name, "/")
|
|
|
|
cp = append([]string{serverPolicyRootShareName}, cp...)
|
|
|
|
f.Name = strings.Join(cp, "\x00")
|
|
f.Length = uint32(len(f.Name))
|
|
}
|
|
|
|
// Path converts FileName to a string
|
|
func (f *FileName) Path() string {
|
|
cp := strings.Split(f.Name, "\x00")
|
|
|
|
if len(cp) == 0 || cp[0] != serverPolicyRootShareName {
|
|
return "" // TODO: not happening until if/when we handle Windows shares
|
|
}
|
|
|
|
cp[0] = ""
|
|
|
|
return strings.Join(cp, "/")
|
|
}
|
|
|
|
// FileNameV3 as defined in hgfsProto.h:HgfsFileNameV3
|
|
type FileNameV3 struct {
|
|
Length uint32
|
|
Flags uint32
|
|
CaseType int32
|
|
ID uint32
|
|
Name string
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (f *FileNameV3) MarshalBinary() ([]byte, error) {
|
|
name := f.Name
|
|
f.Length = uint32(len(f.Name))
|
|
if f.Length == 0 {
|
|
// field is defined as 'char name[1];', this byte is required for min sizeof() validation
|
|
name = "\x00"
|
|
}
|
|
return MarshalBinary(&f.Length, &f.Flags, &f.CaseType, &f.ID, name)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (f *FileNameV3) UnmarshalBinary(data []byte) error {
|
|
buf := bytes.NewBuffer(data)
|
|
|
|
fields := []interface{}{
|
|
&f.Length, &f.Flags, &f.CaseType, &f.ID,
|
|
}
|
|
|
|
for _, p := range fields {
|
|
if err := binary.Read(buf, binary.LittleEndian, p); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
f.Name = string(buf.Next(int(f.Length)))
|
|
|
|
return nil
|
|
}
|
|
|
|
// FromString converts name to a FileNameV3
|
|
func (f *FileNameV3) FromString(name string) {
|
|
p := new(FileName)
|
|
p.FromString(name)
|
|
f.Name = p.Name
|
|
f.Length = p.Length
|
|
}
|
|
|
|
// Path converts FileNameV3 to a string
|
|
func (f *FileNameV3) Path() string {
|
|
return (&FileName{Name: f.Name, Length: f.Length}).Path()
|
|
}
|
|
|
|
// FileType
|
|
const (
|
|
FileTypeRegular = iota
|
|
FileTypeDirectory
|
|
FileTypeSymlink
|
|
)
|
|
|
|
// AttrV2 as defined in hgfsProto.h:HgfsAttrV2
|
|
type AttrV2 struct {
|
|
Mask uint64
|
|
Type int32
|
|
Size uint64
|
|
CreationTime uint64
|
|
AccessTime uint64
|
|
WriteTime uint64
|
|
AttrChangeTime uint64
|
|
SpecialPerms uint8
|
|
OwnerPerms uint8
|
|
GroupPerms uint8
|
|
OtherPerms uint8
|
|
AttrFlags uint64
|
|
AllocationSize uint64
|
|
UserID uint32
|
|
GroupID uint32
|
|
HostFileID uint64
|
|
VolumeID uint32
|
|
EffectivePerms uint32
|
|
Reserved2 uint64
|
|
}
|
|
|
|
// RequestGetattrV2 as defined in hgfsProto.h:HgfsRequestGetattrV2
|
|
type RequestGetattrV2 struct {
|
|
Request
|
|
AttrHint uint64
|
|
Handle uint32
|
|
FileName FileName
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestGetattrV2) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Request, &r.AttrHint, &r.Handle, &r.FileName)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestGetattrV2) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Request, &r.AttrHint, &r.Handle, &r.FileName)
|
|
}
|
|
|
|
// ReplyGetattrV2 as defined in hgfsProto.h:HgfsReplyGetattrV2
|
|
type ReplyGetattrV2 struct {
|
|
Reply
|
|
Attr AttrV2
|
|
SymlinkTarget FileName
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *ReplyGetattrV2) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Reply, &r.Attr, &r.SymlinkTarget)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *ReplyGetattrV2) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Reply, &r.Attr, &r.SymlinkTarget)
|
|
}
|
|
|
|
// RequestSetattrV2 as defined in hgfsProto.h:HgfsRequestSetattrV2
|
|
type RequestSetattrV2 struct {
|
|
Request
|
|
Hints uint64
|
|
Attr AttrV2
|
|
Handle uint32
|
|
FileName FileName
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestSetattrV2) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Request, &r.Hints, &r.Attr, &r.Handle, &r.FileName)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestSetattrV2) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Request, &r.Hints, &r.Attr, &r.Handle, &r.FileName)
|
|
}
|
|
|
|
// ReplySetattrV2 as defined in hgfsProto.h:HgfsReplySetattrV2
|
|
type ReplySetattrV2 struct {
|
|
Header Reply
|
|
}
|
|
|
|
// OpenMode
|
|
const (
|
|
OpenModeReadOnly = iota
|
|
OpenModeWriteOnly
|
|
OpenModeReadWrite
|
|
OpenModeAccmodes
|
|
)
|
|
|
|
// OpenFlags
|
|
const (
|
|
Open = iota
|
|
OpenEmpty
|
|
OpenCreate
|
|
OpenCreateSafe
|
|
OpenCreateEmpty
|
|
)
|
|
|
|
// Permissions
|
|
const (
|
|
PermRead = 4
|
|
PermWrite = 2
|
|
PermExec = 1
|
|
)
|
|
|
|
// RequestOpen as defined in hgfsProto.h:HgfsRequestOpen
|
|
type RequestOpen struct {
|
|
Request
|
|
OpenMode int32
|
|
OpenFlags int32
|
|
Permissions uint8
|
|
FileName FileName
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestOpen) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Request, &r.OpenMode, &r.OpenFlags, r.Permissions, &r.FileName)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestOpen) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Request, &r.OpenMode, &r.OpenFlags, &r.Permissions, &r.FileName)
|
|
}
|
|
|
|
// ReplyOpen as defined in hgfsProto.h:HgfsReplyOpen
|
|
type ReplyOpen struct {
|
|
Reply
|
|
Handle uint32
|
|
}
|
|
|
|
// RequestClose as defined in hgfsProto.h:HgfsRequestClose
|
|
type RequestClose struct {
|
|
Request
|
|
Handle uint32
|
|
}
|
|
|
|
// ReplyClose as defined in hgfsProto.h:HgfsReplyClose
|
|
type ReplyClose struct {
|
|
Reply
|
|
}
|
|
|
|
// Lock type
|
|
const (
|
|
LockNone = iota
|
|
LockOpportunistic
|
|
LockExclusive
|
|
LockShared
|
|
LockBatch
|
|
LockLease
|
|
)
|
|
|
|
// RequestOpenV3 as defined in hgfsProto.h:HgfsRequestOpenV3
|
|
type RequestOpenV3 struct {
|
|
Mask uint64
|
|
OpenMode int32
|
|
OpenFlags int32
|
|
SpecialPerms uint8
|
|
OwnerPerms uint8
|
|
GroupPerms uint8
|
|
OtherPerms uint8
|
|
AttrFlags uint64
|
|
AllocationSize uint64
|
|
DesiredAccess uint32
|
|
ShareAccess uint32
|
|
DesiredLock int32
|
|
Reserved1 uint64
|
|
Reserved2 uint64
|
|
FileName FileNameV3
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestOpenV3) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Mask, &r.OpenMode, &r.OpenFlags,
|
|
&r.SpecialPerms, &r.OwnerPerms, &r.GroupPerms, &r.OtherPerms,
|
|
&r.AttrFlags, &r.AllocationSize, &r.DesiredAccess, &r.ShareAccess,
|
|
&r.DesiredLock, &r.Reserved1, &r.Reserved2, &r.FileName)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestOpenV3) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Mask, &r.OpenMode, &r.OpenFlags,
|
|
&r.SpecialPerms, &r.OwnerPerms, &r.GroupPerms, &r.OtherPerms,
|
|
&r.AttrFlags, &r.AllocationSize, &r.DesiredAccess, &r.ShareAccess,
|
|
&r.DesiredLock, &r.Reserved1, &r.Reserved2, &r.FileName)
|
|
}
|
|
|
|
// ReplyOpenV3 as defined in hgfsProto.h:HgfsReplyOpenV3
|
|
type ReplyOpenV3 struct {
|
|
Handle uint32
|
|
AcquiredLock int32
|
|
Flags int32
|
|
Reserved uint32
|
|
}
|
|
|
|
// RequestReadV3 as defined in hgfsProto.h:HgfsRequestReadV3
|
|
type RequestReadV3 struct {
|
|
Handle uint32
|
|
Offset uint64
|
|
RequiredSize uint32
|
|
Reserved uint64
|
|
}
|
|
|
|
// ReplyReadV3 as defined in hgfsProto.h:HgfsReplyReadV3
|
|
type ReplyReadV3 struct {
|
|
ActualSize uint32
|
|
Reserved uint64
|
|
Payload []byte
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *ReplyReadV3) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.ActualSize, &r.Reserved, r.Payload)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *ReplyReadV3) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.ActualSize, &r.Reserved, &r.Payload)
|
|
}
|
|
|
|
// Write flags
|
|
const (
|
|
WriteAppend = 1
|
|
)
|
|
|
|
// RequestWriteV3 as defined in hgfsProto.h:HgfsRequestWriteV3
|
|
type RequestWriteV3 struct {
|
|
Handle uint32
|
|
WriteFlags uint8
|
|
Offset uint64
|
|
RequiredSize uint32
|
|
Reserved uint64
|
|
Payload []byte
|
|
}
|
|
|
|
// MarshalBinary implements the encoding.BinaryMarshaler interface
|
|
func (r *RequestWriteV3) MarshalBinary() ([]byte, error) {
|
|
return MarshalBinary(&r.Handle, &r.WriteFlags, &r.Offset, &r.RequiredSize, &r.Reserved, r.Payload)
|
|
}
|
|
|
|
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface
|
|
func (r *RequestWriteV3) UnmarshalBinary(data []byte) error {
|
|
return UnmarshalBinary(data, &r.Handle, &r.WriteFlags, &r.Offset, &r.RequiredSize, &r.Reserved, &r.Payload)
|
|
}
|
|
|
|
// ReplyWriteV3 as defined in hgfsProto.h:HgfsReplyWriteV3
|
|
type ReplyWriteV3 struct {
|
|
ActualSize uint32
|
|
Reserved uint64
|
|
}
|