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