static void smb2srv_notify_send(struct ntvfs_request *ntvfs) { struct smb2srv_request *req; union smb_notify *io; size_t size = 0; int i; uint8_t *p; DATA_BLOB blob = data_blob(NULL, 0); SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_notify); SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, True, 0)); #define MAX_BYTES_PER_CHAR 3 /* work out how big the reply buffer could be */ for (i=0;i<io->smb2.out.num_changes;i++) { size += 12 + 3 + (1+strlen(io->smb2.out.changes[i].name.s)) * MAX_BYTES_PER_CHAR; } blob = data_blob_talloc(req, NULL, size); if (size > 0 && !blob.data) { SMB2SRV_CHECK(NT_STATUS_NO_MEMORY); } p = blob.data; /* construct the changes buffer */ for (i=0;i<io->smb2.out.num_changes;i++) { uint32_t ofs; ssize_t len; SIVAL(p, 4, io->smb2.out.changes[i].action); len = push_string(p + 12, io->smb2.out.changes[i].name.s, blob.length - (p+12 - blob.data), STR_UNICODE); SIVAL(p, 8, len); ofs = len + 12; if (ofs & 3) { int pad = 4 - (ofs & 3); memset(p+ofs, 0, pad); ofs += pad; } if (i == io->smb2.out.num_changes-1) { SIVAL(p, 0, 0); } else { SIVAL(p, 0, ofs); } p += ofs; } blob.length = p - blob.data; SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, blob)); smb2srv_send_reply(req); }
static void smb2srv_read_send(struct ntvfs_request *ntvfs) { struct smb2srv_request *req; union smb_read *io; SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_read); SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x10, True, io->smb2.out.data.length)); /* TODO: avoid the memcpy */ SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, io->smb2.out.data)); SBVAL(req->out.body, 0x08, io->smb2.out.unknown1); smb2srv_send_reply(req); }
/* send a write request */ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write *io) { NTSTATUS status; struct smb2_request *req; req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, true, io->in.data.length); if (req == NULL) return NULL; status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; } SBVAL(req->out.body, 0x08, io->in.offset); smb2_push_handle(req->out.body+0x10, &io->in.file.handle); SBVAL(req->out.body, 0x20, io->in.unknown1); SBVAL(req->out.body, 0x28, io->in.unknown2); smb2_transport_send(req); return req; }