int smbucs2put(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string) { uchar *p = buf + n; int l; int align; align = (flags & SMB_STRING_UNALIGNED) == 0 && (n & 1) != 0; l = string ? utflen(string) * 2 : 0; if (n + l + ((flags & SMB_STRING_UNTERMINATED) ? 0 : 2) + align > maxlen) return 0; if (align) *p++ = 0; while (string && *string) { Rune r; int i; i = chartorune(&r, string); if (flags & SMB_STRING_CONVERT_MASK) r = smbruneconvert(r, flags); smbhnputs(p, r); p += 2; string += i; } if ((flags & SMB_STRING_UNTERMINATED) == 0) { smbhnputs(p, 0); p += 2; } assert(p <= buf + maxlen); return p - (buf + n); }
int smbbufferoffsetputs(SmbBuffer *sess, ulong offset, ushort s) { if (offset + 2 > sess->wn) return 0; smbhnputs(sess->buf + offset, s); return 1; }
int smbbufferputs(SmbBuffer *sess, ushort s) { if (sess->wn + sizeof(ushort) > sess->maxlen) return 0; smbhnputs(sess->buf + sess->wn, s); sess->wn += sizeof(ushort); return 1; }
int smbbufferfixupabsolutes(SmbBuffer *b, ulong fixupoffset) { if (fixupoffset < b->rn || fixupoffset > b->wn - 2) return 0; if (b->wn > 65535) return 0; smbhnputs(b->buf + fixupoffset, b->wn); return 1; }
int smbbufferfixuprelatives(SmbBuffer *b, ulong fixupoffset) { ulong fixval; if (fixupoffset < b->rn || fixupoffset > b->wn - 2) return 0; fixval = b->wn - fixupoffset - 2; if (fixval > 65535) return 0; smbhnputs(b->buf + fixupoffset, fixval); return 1; }
int smbbufferputheader(SmbBuffer *b, SmbHeader *h, SmbPeerInfo *p) { SmbRawHeader *rh; if (offsetof(SmbRawHeader, parameterwords[0]) > smbbufferwritespace(b)) return 0; if (smbbufferwriteoffset(b) == 0) { rh = (SmbRawHeader *)smbbufferwritepointer(b); rh->protocol[0] = 0xff; memcpy(rh->protocol + 1, "SMB", 3); rh->flags = SMB_FLAGS_SERVER_TO_REDIR | SmbHeaderFlagCaseless; rh->command = h->command; smbhnputs(rh->flags2, BASE_FLAGS | (smbsendunicode(p) ? SMB_FLAGS2_UNICODE : 0)); memset(rh->extra, 0, sizeof(rh->extra)); if (!smbbufferputbytes(b, nil, offsetof(SmbRawHeader, parameterwords[0]))) return 0; rh->wordcount = h->wordcount; } else { rh = (SmbRawHeader *)smbbufferreadpointer(b); smbbufferputb(b, h->wordcount); } rh->status[0] = h->errclass; rh->status[1] = 0; smbhnputs(rh->status + 2, h->error); smbhnputs(rh->tid, h->tid); smbhnputs(rh->pid, h->pid); smbhnputs(rh->uid, h->uid); smbhnputs(rh->mid, h->mid); return 1; }