📄 smbcomopen.c
字号:
char *path; ushort mode, attr; SmbTree *t; ushort fid; Dir *d = nil; SmbFile *f; SmbProcessResult pr; if (!smbcheckwordcount("comopen", h, 2)) return SmbProcessResultFormat; mode = smbnhgets(pdata); attr = smbnhgets(pdata + 2); if (!smbbuffergetb(b, &fmt) || fmt != 4 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { pr = SmbProcessResultFormat; goto done; } t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); error: pr = SmbProcessResultError; goto done; } f = openfile(s, t, path, mode, attr, SMB_OFUN_EXIST_OPEN << SMB_OFUN_EXIST_SHIFT, 0, 0, &fid, &d, nil); if (f == nil) goto error; h->wordcount = 7; if (!smbbufferputheader(s->response, h, &s->peerinfo) || !smbbufferputs(s->response, fid) || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode)) || !smbbufferputl(s->response, smbplan9time2utime(d->mtime, s->tzoff)) || !smbbufferputl(s->response, smbplan9length2size32(d->length)) || !smbbufferputs(s->response, 2) // lies - this should be the actual access allowed || !smbbufferputs(s->response, 0)) pr = SmbProcessResultMisc; else pr = SmbProcessResultReply;done: free(path); free(d); return pr;}typedef struct SmbSblut { char *s; ulong mask;} SmbSblut;static SmbSblut dasblut[] = { { "SMB_DA_SPECIFIC_READ_DATA", SMB_DA_SPECIFIC_READ_DATA }, { "SMB_DA_SPECIFIC_WRITE_DATA", SMB_DA_SPECIFIC_WRITE_DATA }, { "SMB_DA_SPECIFIC_APPEND_DATA", SMB_DA_SPECIFIC_APPEND_DATA }, { "SMB_DA_SPECIFIC_READ_EA", SMB_DA_SPECIFIC_READ_EA }, { "SMB_DA_SPECIFIC_WRITE_EA", SMB_DA_SPECIFIC_WRITE_EA }, { "SMB_DA_SPECIFIC_EXECUTE", SMB_DA_SPECIFIC_EXECUTE }, { "SMB_DA_SPECIFIC_DELETE_CHILD", SMB_DA_SPECIFIC_DELETE_CHILD }, { "SMB_DA_SPECIFIC_READ_ATTRIBUTES", SMB_DA_SPECIFIC_READ_ATTRIBUTES }, { "SMB_DA_SPECIFIC_WRITE_ATTRIBUTES", SMB_DA_SPECIFIC_WRITE_ATTRIBUTES }, { "SMB_DA_STANDARD_DELETE_ACCESS", SMB_DA_STANDARD_DELETE_ACCESS }, { "SMB_DA_STANDARD_READ_CONTROL_ACCESS", SMB_DA_STANDARD_READ_CONTROL_ACCESS }, { "SMB_DA_STANDARD_WRITE_DAC_ACCESS", SMB_DA_STANDARD_WRITE_DAC_ACCESS }, { "SMB_DA_STANDARD_WRITE_OWNER_ACCESS", SMB_DA_STANDARD_WRITE_OWNER_ACCESS }, { "SMB_DA_STANDARD_SYNCHRONIZE_ACCESS", SMB_DA_STANDARD_SYNCHRONIZE_ACCESS }, { "SMB_DA_GENERIC_ALL_ACCESS", SMB_DA_GENERIC_ALL_ACCESS }, { "SMB_DA_GENERIC_EXECUTE_ACCESS", SMB_DA_GENERIC_EXECUTE_ACCESS }, { "SMB_DA_GENERIC_WRITE_ACCESS", SMB_DA_GENERIC_WRITE_ACCESS }, { "SMB_DA_GENERIC_READ_ACCESS", SMB_DA_GENERIC_READ_ACCESS }, { 0 }};static SmbSblut efasblut[] = { { "SMB_ATTR_READ_ONLY", SMB_ATTR_READ_ONLY }, { "SMB_ATTR_HIDDEN", SMB_ATTR_HIDDEN }, { "SMB_ATTR_SYSTEM", SMB_ATTR_SYSTEM }, { "SMB_ATTR_DIRECTORY", SMB_ATTR_DIRECTORY }, { "SMB_ATTR_ARCHIVE", SMB_ATTR_ARCHIVE }, { "SMB_ATTR_NORMAL", SMB_ATTR_NORMAL }, { "SMB_ATTR_COMPRESSED", SMB_ATTR_COMPRESSED }, { "SMB_ATTR_TEMPORARY", SMB_ATTR_TEMPORARY }, { "SMB_ATTR_WRITETHROUGH", SMB_ATTR_WRITETHROUGH }, { "SMB_ATTR_NO_BUFFERING", SMB_ATTR_NO_BUFFERING }, { "SMB_ATTR_RANDOM_ACCESS", SMB_ATTR_RANDOM_ACCESS }, { 0 }};static SmbSblut sasblut[] = { { "SMB_SA_SHARE_READ", SMB_SA_SHARE_READ }, { "SMB_SA_SHARE_WRITE", SMB_SA_SHARE_WRITE }, { "SMB_SA_SHARE_DELETE", SMB_SA_SHARE_DELETE }, { "SMB_SA_NO_SHARE", SMB_SA_NO_SHARE }, { 0 }};static SmbSblut cosblut[] = { { "SMB_CO_DIRECTORY", SMB_CO_DIRECTORY }, { "SMB_CO_WRITETHROUGH", SMB_CO_WRITETHROUGH }, { "SMB_CO_SEQUENTIAL_ONLY", SMB_CO_SEQUENTIAL_ONLY }, { "SMB_CO_FILE", SMB_CO_FILE }, { "SMB_CO_NO_EA_KNOWLEDGE", SMB_CO_NO_EA_KNOWLEDGE }, { "SMB_CO_EIGHT_DOT_THREE_ONLY", SMB_CO_EIGHT_DOT_THREE_ONLY }, { "SMB_CO_RANDOM_ACCESS", SMB_CO_RANDOM_ACCESS }, { "SMB_CO_DELETE_ON_CLOSE", SMB_CO_DELETE_ON_CLOSE }, { 0 }};static SmbSlut cdslut[] = { { "SMB_CD_SUPERCEDE", SMB_CD_SUPERCEDE }, { "SMB_CD_OPEN", SMB_CD_OPEN }, { "SMB_CD_CREATE", SMB_CD_CREATE }, { "SMB_CD_OPEN_IF", SMB_CD_OPEN_IF }, { "SMB_CD_OVERWRITE", SMB_CD_OVERWRITE }, { "SMB_CD_OVERWRITE_IF", SMB_CD_OVERWRITE_IF }, { 0 }};static voidsmbsblutlogprint(uchar cmd, SmbSblut *sblut, ulong mask){ while (sblut->s) { if (mask && (sblut->mask & mask) || (mask == 0 && sblut->mask == 0)) smblogprint(cmd, " %s", sblut->s); sblut++; }}SmbProcessResultsmbcomntcreateandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b){ uchar andxcommand; ushort andxoffset; char *path = nil; SmbProcessResult pr; ulong namelength; ulong flags; ulong rootdirectoryfid, desiredaccess; uvlong allocationsize; ulong extfileattributes, shareaccess, createdisposition, createoptions, impersonationlevel; uchar securityflags; int p9mode; int sharemode; ushort mode; SmbTree *t; ushort ofun; SmbFile *f; ushort fid; Dir *d = nil; ushort action; uvlong mtime; ulong andxoffsetfixup; if (!smbcheckwordcount("comntcreateandx", h, 24)) return SmbProcessResultFormat; andxcommand = *pdata++; pdata++; andxoffset = smbnhgets(pdata); pdata += 2; pdata++; namelength = smbnhgets(pdata); pdata += 2; flags = smbnhgetl(pdata); pdata += 4; rootdirectoryfid = smbnhgetl(pdata); pdata += 4; desiredaccess = smbnhgetl(pdata); pdata += 4; allocationsize = smbnhgetv(pdata); pdata += 8; extfileattributes = smbnhgetl(pdata); pdata += 4; shareaccess = smbnhgetl(pdata); pdata += 4; createdisposition = smbnhgetl(pdata); pdata += 4; createoptions = smbnhgetl(pdata); pdata += 4; impersonationlevel = smbnhgetl(pdata); pdata += 4; securityflags = *pdata++; USED(pdata); if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { pr = SmbProcessResultFormat; goto done; } smblogprint(h->command, "namelength %d\n", namelength); smblogprint(h->command, "flags 0x%.8lux\n", flags); smblogprint(h->command, "rootdirectoryfid %lud\n", rootdirectoryfid); smblogprint(h->command, "desiredaccess 0x%.8lux", desiredaccess); smbsblutlogprint(h->command, dasblut, desiredaccess); smblogprint(h->command, "\n"); smblogprint(h->command, "allocationsize %llud\n", allocationsize); smblogprint(h->command, "extfileattributes 0x%.8lux", extfileattributes); smbsblutlogprint(h->command, efasblut, extfileattributes); smblogprint(h->command, "\n"); smblogprint(h->command, "shareaccess 0x%.8lux", shareaccess); smbsblutlogprint(h->command, sasblut, shareaccess); smblogprint(h->command, "\n"); smblogprint(h->command, "createdisposition 0x%.8lux %s\n", createdisposition, smbrevslut(cdslut, createdisposition)); smblogprint(h->command, "createoptions 0x%.8lux", createoptions); smbsblutlogprint(h->command, cosblut, createoptions); smblogprint(h->command, "\n"); smblogprint(h->command, "impersonationlevel 0x%.8lux\n", impersonationlevel); smblogprint(h->command, "securityflags 0x%.2ux\n", securityflags); smblogprint(h->command, "path %s\n", path); if (rootdirectoryfid != 0) { smblogprint(-1, "smbcomntcreateandx: fid relative not implemented\n"); goto unimp; } if (desiredaccess & SMB_DA_GENERIC_MASK) { smblogprint(-1, "smbcomntcreateandx: generic bits in desiredaccess not implemented\n"); goto unimp; } if (desiredaccess & SMB_DA_SPECIFIC_READ_DATA) if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA)) p9mode = ORDWR; else p9mode = OREAD; else if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA)) p9mode = ORDWR; else p9mode = OREAD; if (shareaccess == SMB_SA_NO_SHARE) sharemode = SMB_OPEN_MODE_SHARE_EXCLUSIVE; else if (shareaccess & (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE) == (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE)) sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE; else if (shareaccess & SMB_SA_SHARE_READ) sharemode = SMB_OPEN_MODE_SHARE_DENY_WRITE; else if (shareaccess & SMB_SA_SHARE_WRITE) sharemode = SMB_OPEN_MODE_SHARE_DENY_READOREXEC; else sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE; mode = (sharemode << SMB_OPEN_MODE_SHARE_SHIFT) | (p9mode << SMB_OPEN_MODE_ACCESS_SHIFT); switch (createdisposition) { default: smblogprint(-1, "smbcomntcreateandx: createdisposition 0x%.8lux not implemented\n", createdisposition); goto unimp; case SMB_CD_OPEN: ofun = SMB_OFUN_EXIST_OPEN; break; case SMB_CD_CREATE: ofun = SMB_OFUN_EXIST_FAIL | SMB_OFUN_NOEXIST_CREATE; break; case SMB_CD_OPEN_IF: ofun = SMB_OFUN_EXIST_OPEN | SMB_OFUN_NOEXIST_CREATE; break; case SMB_CD_OVERWRITE: ofun = SMB_OFUN_EXIST_TRUNCATE; break; case SMB_CD_OVERWRITE_IF: ofun = SMB_OFUN_EXIST_TRUNCATE | SMB_OFUN_NOEXIST_CREATE; break; } t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); pr = SmbProcessResultError; goto done; } f = openfile(s, t, path, mode, extfileattributes, ofun, createoptions, allocationsize, &fid, &d, &action); if (f == nil) { pr = SmbProcessResultError; goto done; } h->wordcount = 42; mtime = smbplan9time2time(d->mtime); if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup) || !smbbufferputb(s->response, 0) // oplocks? pah || !smbbufferputs(s->response, fid) || !smbbufferputl(s->response, action) || !smbbufferputv(s->response, mtime) || !smbbufferputv(s->response, smbplan9time2time(d->atime)) || !smbbufferputv(s->response, mtime) || !smbbufferputv(s->response, mtime) || !smbbufferputl(s->response, smbplan9mode2dosattr(d->mode)) || !smbbufferputv(s->response, smbl2roundupvlong(d->length, smbglobals.l2allocationsize)) || !smbbufferputv(s->response, d->length) || !smbbufferputbytes(s->response, nil, 4) || !smbbufferputb(s->response, (d->qid.type & QTDIR) != 0) || !smbbufferputbytes(s->response, nil, 8) || !smbbufferputs(s->response, 0)) { pr = SmbProcessResultMisc; goto done; } if (andxcommand != SMB_COM_NO_ANDX_COMMAND) pr = smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b); else pr = SmbProcessResultReply; goto done;unimp: pr = SmbProcessResultUnimp;done: free(path); free(d); return pr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -