123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #include "headers.h"
- static int
- getlock(SmbBuffer *b, int large, ushort *pidp, uvlong *offsetp, uvlong *lengthp)
- {
- ulong ohigh, olow;
- ulong lhigh, llow;
- if (!smbbuffergets(b, pidp))
- return 0;
- if (large && !smbbuffergetbytes(b, nil, 2))
- return 0;
- if (large) {
- if (!smbbuffergetl(b, &ohigh) || !smbbuffergetl(b, &olow)
- || !smbbuffergetl(b, &lhigh) || !smbbuffergetl(b, &llow))
- return 0;
- *offsetp = ((uvlong)ohigh << 32) | olow;
- *lengthp = ((uvlong)lhigh << 32) | llow;
- return 1;
- }
- if (!smbbuffergetl(b, &olow) || !smbbuffergetl(b, &llow))
- return 0;
- *offsetp = olow;
- *lengthp = llow;
- return 1;
- }
- SmbProcessResult
- smbcomlockingandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
- {
- uchar andxcommand;
- ushort andxoffset;
- ulong andxoffsetfixup;
- ushort fid;
- uchar locktype;
- uchar oplocklevel;
- ulong timeout;
- ushort numberofunlocks;
- ushort numberoflocks;
- SmbTree *t;
- SmbFile *f;
- int l;
- SmbProcessResult pr;
- ulong backupoffset;
- int large;
- if (!smbcheckwordcount("comlockingandx", h, 8))
- return SmbProcessResultFormat;
- andxcommand = *pdata++;
- pdata++;
- andxoffset = smbnhgets(pdata); pdata += 2;
- fid = smbnhgets(pdata); pdata += 2;
- locktype = *pdata++;
- oplocklevel = *pdata++;
- timeout = smbnhgetl(pdata); pdata += 4;
- numberofunlocks = smbnhgets(pdata); pdata += 2;
- numberoflocks = smbnhgets(pdata);
- smblogprint(h->command, "smbcomlockingandx: fid 0x%.4ux locktype 0x%.2ux oplocklevel 0x%.2ux timeout %lud numberofunlocks %d numberoflocks %ud\n",
- fid, locktype, oplocklevel, timeout, numberofunlocks, numberoflocks);
- large = locktype & 0x10;
- locktype &= ~0x10;
- if (locktype != 0 || oplocklevel != 0) {
- smblogprint(-1, "smbcomlockingandx: locktype 0x%.2ux unimplemented\n", locktype);
- return SmbProcessResultUnimp;
- }
- if (oplocklevel != 0) {
- smblogprint(-1, "smbcomlockingandx: oplocklevel 0x%.2ux unimplemented\n", oplocklevel);
- return SmbProcessResultUnimp;
- }
- t = smbidmapfind(s->tidmap, h->tid);
- if (t == nil) {
- smbseterror(s, ERRSRV, ERRinvtid);
- error:
- return SmbProcessResultError;
- }
- f = smbidmapfind(s->fidmap, fid);
- if (f == nil) {
- smbseterror(s, ERRDOS, ERRbadfid);
- goto error;
- }
- backupoffset = smbbufferreadoffset(b);
- for (l = 0; l < numberofunlocks; l++) {
- ushort pid;
- uvlong offset;
- uvlong length;
- if (!getlock(b, large, &pid, &offset, &length)) {
- pr = SmbProcessResultFormat;
- goto done;
- }
- smblogprint(h->command, "smbcomlockingandx: unlock pid 0x%.4ux offset %llud length %llud\n",
- pid, offset, length);
- smbsharedfileunlock(f->sf, s, h->pid, offset, offset + length);
- }
- for (l = 0; l < numberoflocks; l++) {
- ushort pid;
- uvlong offset;
- uvlong length;
- if (!getlock(b, large, &pid, &offset, &length)) {
- pr = SmbProcessResultFormat;
- goto done;
- }
- smblogprint(h->command, "smbcomlockingandx: lock pid 0x%.4ux offset %llud length %llud\n",
- pid, offset, length);
- if (!smbsharedfilelock(f->sf, s, h->pid, offset, offset + length))
- break;
- }
- if (l < numberoflocks) {
- ushort i;
- ushort pid;
- uvlong offset;
- uvlong length;
- smbbufferreadbackup(b, backupoffset);
- for (i = 0; i < l; i++) {
- assert(getlock(b, large, &pid, &offset, &length));
- smbsharedfileunlock(f->sf, s, h->pid, offset, offset + length);
- }
- smbseterror(s, ERRDOS, ERRlock);
- goto error;
- }
- h->wordcount = 2;
- if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup)
- || !smbbufferputs(s->response, 0)) { // bytecount 0
- pr = SmbProcessResultMisc;
- goto done;
- }
- if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
- pr = smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
- else
- pr = SmbProcessResultReply;
- done:
- return pr;
- }
|