Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "headers.h"
2
 
3
static int
4
getlock(SmbBuffer *b, int large, ushort *pidp, uvlong *offsetp, uvlong *lengthp)
5
{
6
	ulong ohigh, olow;
7
	ulong lhigh, llow;
8
	if (!smbbuffergets(b, pidp))
9
		return 0;
10
	if (large && !smbbuffergetbytes(b, nil, 2))
11
		return 0;
12
	if (large) {
13
		if (!smbbuffergetl(b, &ohigh) || !smbbuffergetl(b, &olow)
14
			|| !smbbuffergetl(b, &lhigh) || !smbbuffergetl(b, &llow))
15
			return 0;
16
		*offsetp = ((uvlong)ohigh << 32) | olow;
17
		*lengthp = ((uvlong)lhigh << 32) | llow;
18
		return 1;
19
	}
20
	if (!smbbuffergetl(b, &olow) || !smbbuffergetl(b, &llow))
21
		return 0;
22
	*offsetp = olow;
23
	*lengthp = llow;
24
	return 1;
25
}
26
 
27
SmbProcessResult
28
smbcomlockingandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
29
{
30
	uchar andxcommand;
31
	ushort andxoffset;
32
	ulong andxoffsetfixup;
33
	ushort fid;
34
	uchar locktype;
35
	uchar oplocklevel;
36
	ulong timeout;
37
	ushort numberofunlocks;
38
	ushort numberoflocks;
39
	SmbTree *t;
40
	SmbFile *f;
41
	int l;
42
	SmbProcessResult pr;
43
	ulong backupoffset;
44
	int large;
45
 
46
	if (!smbcheckwordcount("comlockingandx", h, 8))
47
		return SmbProcessResultFormat;
48
 
49
	andxcommand = *pdata++;
50
	pdata++;
51
	andxoffset = smbnhgets(pdata); pdata += 2;
52
	fid = smbnhgets(pdata); pdata += 2;
53
	locktype = *pdata++;
54
	oplocklevel = *pdata++;
55
	timeout = smbnhgetl(pdata); pdata += 4;
56
	numberofunlocks = smbnhgets(pdata); pdata += 2;
57
	numberoflocks = smbnhgets(pdata);
58
	smblogprint(h->command, "smbcomlockingandx: fid 0x%.4ux locktype 0x%.2ux oplocklevel 0x%.2ux timeout %lud numberofunlocks %d numberoflocks %ud\n",
59
		fid, locktype, oplocklevel, timeout, numberofunlocks, numberoflocks);
60
	large = locktype & 0x10;
61
	locktype &= ~0x10;
62
	if (locktype != 0 || oplocklevel != 0) {
63
		smblogprint(-1, "smbcomlockingandx: locktype 0x%.2ux unimplemented\n", locktype);
64
		return SmbProcessResultUnimp;
65
	}
66
	if (oplocklevel != 0) {
67
		smblogprint(-1, "smbcomlockingandx: oplocklevel 0x%.2ux unimplemented\n", oplocklevel);
68
		return SmbProcessResultUnimp;
69
	}
70
	t = smbidmapfind(s->tidmap, h->tid);
71
	if (t == nil) {
72
		smbseterror(s, ERRSRV, ERRinvtid);
73
	error:
74
		return SmbProcessResultError;
75
	}
76
	f = smbidmapfind(s->fidmap, fid);
77
	if (f == nil) {
78
		smbseterror(s, ERRDOS, ERRbadfid);
79
		goto error;
80
	}
81
	backupoffset = smbbufferreadoffset(b);
82
	for (l = 0; l < numberofunlocks; l++) {
83
		ushort pid;
84
		uvlong offset;
85
		uvlong length;
86
		if (!getlock(b, large, &pid, &offset, &length)) {
87
			pr = SmbProcessResultFormat;
88
			goto done;
89
		}
90
		smblogprint(h->command, "smbcomlockingandx: unlock pid 0x%.4ux offset %llud length %llud\n",
91
			pid, offset, length);
92
		smbsharedfileunlock(f->sf, s, h->pid, offset, offset + length);
93
	}
94
	for (l = 0; l < numberoflocks; l++) {
95
		ushort pid;
96
		uvlong offset;
97
		uvlong length;
98
		if (!getlock(b, large, &pid, &offset, &length)) {
99
			pr = SmbProcessResultFormat;
100
			goto done;
101
		}
102
		smblogprint(h->command, "smbcomlockingandx: lock pid 0x%.4ux offset %llud length %llud\n",
103
			pid, offset, length);
104
		if (!smbsharedfilelock(f->sf, s, h->pid, offset, offset + length))
105
			break;
106
	}
107
	if (l < numberoflocks) {
108
		ushort i;
109
		ushort pid;
110
		uvlong offset;
111
		uvlong length;
112
		smbbufferreadbackup(b, backupoffset);
113
		for (i  = 0; i < l; i++) {
114
			assert(getlock(b, large, &pid, &offset, &length));
115
			smbsharedfileunlock(f->sf, s, h->pid, offset, offset + length);
116
		}
117
		smbseterror(s, ERRDOS, ERRlock);
118
		goto error;
119
	}
120
	h->wordcount = 2;
121
	if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup)
122
		|| !smbbufferputs(s->response, 0)) {	// bytecount 0
123
		pr = SmbProcessResultMisc;
124
		goto done;
125
	}
126
	if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
127
		pr = smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
128
	else
129
		pr = SmbProcessResultReply;
130
done:
131
	return pr;
132
}