github.com/vmware/govmomi@v0.43.0/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 }