1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
package smb2
import (
"context"
"fmt"
. "github.com/cloudsoda/go-smb2/internal/smb2"
"github.com/cloudsoda/go-smb2/internal/utf16le"
)
type treeConn struct {
*session
treeId uint32
shareFlags uint32
// path string
// shareType uint8
// capabilities uint32
// maximalAccess uint32
}
func treeConnect(s *session, path string, flags uint16, mc utf16le.MapChars, ctx context.Context) (*treeConn, error) {
req := &TreeConnectRequest{
Flags: flags,
Path: path,
Mapping: mc,
}
req.CreditCharge = 1
rr, err := s.send(req, ctx)
if err != nil {
return nil, err
}
pkt, err := s.recv(rr)
if err != nil {
return nil, err
}
res, err := accept(SMB2_TREE_CONNECT, pkt)
if err != nil {
return nil, err
}
r := TreeConnectResponseDecoder(res)
if r.IsInvalid() {
return nil, &InvalidResponseError{"broken tree connect response format"}
}
tc := &treeConn{
session: s,
treeId: PacketCodec(pkt).TreeId(),
shareFlags: r.ShareFlags(),
// path: path,
// shareType: r.ShareType(),
// capabilities: r.Capabilities(),
// maximalAccess: r.MaximalAccess(),
}
return tc, nil
}
func (tc *treeConn) disconnect(ctx context.Context) error {
req := new(TreeDisconnectRequest)
req.CreditCharge = 1
res, err := tc.sendRecv(SMB2_TREE_DISCONNECT, req, ctx)
if err != nil {
return err
}
r := TreeDisconnectResponseDecoder(res)
if r.IsInvalid() {
return &InvalidResponseError{"broken tree disconnect response format"}
}
return nil
}
func (tc *treeConn) sendRecv(cmd uint16, req Packet, ctx context.Context) (res []byte, err error) {
rr, err := tc.send(req, ctx)
if err != nil {
return nil, err
}
pkt, err := tc.recv(rr)
if err != nil {
return nil, err
}
return accept(cmd, pkt)
}
func (tc *treeConn) send(req Packet, ctx context.Context) (rr *requestResponse, err error) {
return tc.sendWith(req, tc, ctx)
}
func (tc *treeConn) recv(rr *requestResponse) (pkt []byte, err error) {
pkt, err = tc.session.recv(rr)
if err != nil {
return nil, err
}
if rr.asyncId != 0 {
if asyncId := PacketCodec(pkt).AsyncId(); asyncId != rr.asyncId {
return nil, &InvalidResponseError{fmt.Sprintf("expected async id: %v, got %v", rr.asyncId, asyncId)}
}
} else {
if treeId := PacketCodec(pkt).TreeId(); treeId != tc.treeId {
return nil, &InvalidResponseError{fmt.Sprintf("expected tree id: %v, got %v", tc.treeId, treeId)}
}
}
return pkt, err
}
|