2 |
- |
1 |
#include "headers.h"
|
|
|
2 |
|
|
|
3 |
SmbProcessResult
|
|
|
4 |
smbcomreadandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
|
|
|
5 |
{
|
|
|
6 |
uchar andxcommand;
|
|
|
7 |
ushort andxoffset;
|
|
|
8 |
ulong andxoffsetfixup;
|
|
|
9 |
ulong datafixup;
|
|
|
10 |
ulong bytecountfixup;
|
|
|
11 |
ushort fid;
|
|
|
12 |
SmbTree *t;
|
|
|
13 |
SmbFile *f;
|
|
|
14 |
vlong offset;
|
|
|
15 |
ushort maxcount;
|
|
|
16 |
long toread;
|
|
|
17 |
long nb;
|
|
|
18 |
|
|
|
19 |
if (h->wordcount != 10 && h->wordcount != 12)
|
|
|
20 |
return SmbProcessResultFormat;
|
|
|
21 |
|
|
|
22 |
andxcommand = *pdata++;
|
|
|
23 |
pdata++;
|
|
|
24 |
andxoffset = smbnhgets(pdata); pdata += 2;
|
|
|
25 |
fid = smbnhgets(pdata); pdata += 2;
|
|
|
26 |
offset = smbnhgetl(pdata); pdata += 4;
|
|
|
27 |
maxcount = smbnhgets(pdata); pdata += 2;
|
|
|
28 |
pdata += 2; // mincount
|
|
|
29 |
pdata += 4; // timeout ?
|
|
|
30 |
pdata += 2; // remaining
|
|
|
31 |
if (h->wordcount == 12)
|
|
|
32 |
offset |= (vlong)smbnhgetl(pdata) << 32;
|
|
|
33 |
|
|
|
34 |
t = smbidmapfind(s->tidmap, h->tid);
|
|
|
35 |
if (t == nil) {
|
|
|
36 |
smbseterror(s, ERRSRV, ERRinvtid);
|
|
|
37 |
return SmbProcessResultError;
|
|
|
38 |
}
|
|
|
39 |
f = smbidmapfind(s->fidmap, fid);
|
|
|
40 |
if (f == nil) {
|
|
|
41 |
smbseterror(s, ERRDOS, ERRbadfid);
|
|
|
42 |
return SmbProcessResultError;
|
|
|
43 |
}
|
|
|
44 |
|
|
|
45 |
if (!f->ioallowed) {
|
|
|
46 |
smbseterror(s, ERRDOS, ERRbadaccess);
|
|
|
47 |
return SmbProcessResultError;
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
h->wordcount = 12;
|
|
|
51 |
if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup))
|
|
|
52 |
return SmbProcessResultMisc;
|
|
|
53 |
if (!smbbufferputs(s->response, -1) // remaining
|
|
|
54 |
|| !smbbufferputs(s->response, 0) // datacompactionmode
|
|
|
55 |
|| !smbbufferputs(s->response, 0)) // reserved
|
|
|
56 |
return SmbProcessResultMisc;
|
|
|
57 |
datafixup = smbbufferwriteoffset(s->response);
|
|
|
58 |
if (!smbbufferputbytes(s->response, nil, 6)
|
|
|
59 |
|| !smbbufferfill(s->response, 0, 8)) // reserved
|
|
|
60 |
return SmbProcessResultMisc;
|
|
|
61 |
bytecountfixup = smbbufferwriteoffset(s->response);
|
|
|
62 |
if (!smbbufferputs(s->response, 0)
|
|
|
63 |
|| !smbbufferputb(s->response, 0))
|
|
|
64 |
return SmbProcessResultMisc;
|
|
|
65 |
smbbufferwritelimit(s->response, smbbufferwriteoffset(s->response) + 65535);
|
|
|
66 |
smbbufferoffsetputs(s->response, datafixup + 2, smbbufferwriteoffset(s->response));
|
|
|
67 |
seek(f->fd, offset, 0);
|
|
|
68 |
toread = smbbufferwritespace(s->response);
|
|
|
69 |
if (toread > maxcount)
|
|
|
70 |
toread = maxcount;
|
|
|
71 |
nb = readn(f->fd, smbbufferwritepointer(s->response), toread);
|
|
|
72 |
if (nb < 0) {
|
|
|
73 |
smbseterror(s, ERRDOS, ERRbadaccess);
|
|
|
74 |
return SmbProcessResultError;
|
|
|
75 |
}
|
|
|
76 |
if (!smbbufferputbytes(s->response, nil, nb)
|
|
|
77 |
|| !smbbufferfixuprelatives(s->response, bytecountfixup)
|
|
|
78 |
|| !smbbufferoffsetputs(s->response, datafixup, nb)
|
|
|
79 |
|| !smbbufferoffsetputs(s->response, datafixup + 4, nb >> 16))
|
|
|
80 |
return SmbProcessResultMisc;
|
|
|
81 |
if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
|
|
|
82 |
return smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
|
|
|
83 |
return SmbProcessResultReply;
|
|
|
84 |
}
|