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 }