/* append raw bytes into the data portion of the request packet return the number of bytes added */ size_t smbcli_req_append_bytes(struct smbcli_request *req, const uint8_t *bytes, size_t byte_len) { smbcli_req_grow_allocation(req, byte_len + req->out.data_size); memcpy(req->out.data + req->out.data_size, bytes, byte_len); smbcli_req_grow_data(req, byte_len + req->out.data_size); return byte_len; }
/* push a blob into the data portion of the request packet, growing it if necessary this gets quite tricky - please be very careful to cover all cases when modifying this if dest is NULL, then put the blob at the end of the data portion of the packet */ size_t smbcli_req_append_blob(struct smbcli_request *req, const DATA_BLOB *blob) { smbcli_req_grow_allocation(req, req->out.data_size + blob->length); memcpy(req->out.data + req->out.data_size, blob->data, blob->length); smbcli_req_grow_data(req, req->out.data_size + blob->length); return blob->length; }
/* append variable block (type 5 buffer) into the data portion of the request packet return the number of bytes added */ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *bytes, uint16_t byte_len) { smbcli_req_grow_allocation(req, byte_len + 3 + req->out.data_size); SCVAL(req->out.data + req->out.data_size, 0, 5); SSVAL(req->out.data + req->out.data_size, 1, byte_len); /* add field length */ if (byte_len > 0) { memcpy(req->out.data + req->out.data_size + 3, bytes, byte_len); } smbcli_req_grow_data(req, byte_len + 3 + req->out.data_size); return byte_len + 3; }
/* grow the data buffer portion of a reply packet. Note that as this can reallocate the packet buffer this invalidates any local pointers into the packet. To cope with this req->out.ptr is supplied. This will be updated to point at the same offset into the packet as before this call */ static void smbcli_req_grow_data(struct smbcli_request *req, unsigned int new_size) { int delta; smbcli_req_grow_allocation(req, new_size); delta = new_size - req->out.data_size; req->out.size += delta; req->out.data_size += delta; /* set the BCC to the new data size */ SSVAL(req->out.vwv, VWV(req->out.wct), new_size); }
/* append a string into the data portion of the request packet return the number of bytes added to the packet */ size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, unsigned int flags) { size_t len; /* determine string type to use */ if (!(flags & (STR_ASCII|STR_UNICODE))) { flags |= (req->transport->negotiate.capabilities & CAP_UNICODE) ? STR_UNICODE : STR_ASCII; } len = (strlen(str)+2) * MAX_BYTES_PER_CHAR; smbcli_req_grow_allocation(req, len + req->out.data_size); len = push_string(req->out.data + req->out.data_size, str, len, flags); smbcli_req_grow_data(req, len + req->out.data_size); return len; }
/* setup a chained reply in req->out with the given word count and initial data buffer size. */ NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req, uint8_t command, unsigned int wct, size_t buflen) { unsigned int new_size = 1 + (wct*2) + 2 + buflen; SSVAL(req->out.vwv, VWV(0), command); SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE); smbcli_req_grow_allocation(req, req->out.data_size + new_size); req->out.vwv = req->out.buffer + req->out.size + 1; SCVAL(req->out.vwv, -1, wct); SSVAL(req->out.vwv, VWV(wct), buflen); req->out.size += new_size; req->out.data_size += new_size; return NT_STATUS_OK; }