diff options
author | Andrew Tridgell <tridge@samba.org> | 2006-03-08 05:47:51 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:52:36 -0500 |
commit | 276162cc9daf3c3e71f1481f7aa19d19d5909824 (patch) | |
tree | 9978c3ec02b8ddd75f698fd68af5e0f65ae8938f /source4/smb_server | |
parent | 91931f97e8a926ad812d5a353524e7d5c5dc8a04 (diff) | |
download | samba-276162cc9daf3c3e71f1481f7aa19d19d5909824.tar.gz samba-276162cc9daf3c3e71f1481f7aa19d19d5909824.tar.bz2 samba-276162cc9daf3c3e71f1481f7aa19d19d5909824.zip |
r14013: added construction of the notify reply buffer in the nttrans server
code
the RAW-NOTIFY test now passes against the CIFS backend
(This used to be commit e03a2e2de2ad7cd7e692248a681a46ffc1447541)
Diffstat (limited to 'source4/smb_server')
-rw-r--r-- | source4/smb_server/smb/nttrans.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c index 0a7f0d7dc2..03f5f398fe 100644 --- a/source4/smb_server/smb/nttrans.c +++ b/source4/smb_server/smb/nttrans.c @@ -39,17 +39,25 @@ struct nttrans_op { /* setup a nttrans reply, given the data and params sizes */ -static void nttrans_setup_reply(struct smbsrv_request *req, - struct smb_nttrans *trans, - uint16_t param_size, uint16_t data_size, - uint16_t setup_count) +static NTSTATUS nttrans_setup_reply(struct nttrans_op *op, + struct smb_nttrans *trans, + uint16_t param_size, uint16_t data_size, + uint16_t setup_count) { trans->out.setup_count = setup_count; if (setup_count != 0) { - trans->out.setup = talloc_zero_array(req, uint16_t, setup_count); + trans->out.setup = talloc_zero_array(op, uint16_t, setup_count); + NT_STATUS_HAVE_NO_MEMORY(trans->out.setup); } - trans->out.params = data_blob_talloc(req, NULL, param_size); - trans->out.data = data_blob_talloc(req, NULL, data_size); + trans->out.params = data_blob_talloc(op, NULL, param_size); + if (param_size != 0) { + NT_STATUS_HAVE_NO_MEMORY(trans->out.params.data); + } + trans->out.data = data_blob_talloc(op, NULL, data_size); + if (data_size != 0) { + NT_STATUS_HAVE_NO_MEMORY(trans->out.data.data); + } + return NT_STATUS_OK; } /* @@ -296,6 +304,7 @@ static NTSTATUS nttrans_ioctl(struct smbsrv_request *req, uint8_t filter; BOOL fsctl; DATA_BLOB *blob; + NTSTATUS status; /* should have at least 4 setup words */ if (trans->in.setup_count != 4) { @@ -318,7 +327,9 @@ static NTSTATUS nttrans_ioctl(struct smbsrv_request *req, nt->ntioctl.in.fsctl = fsctl; nt->ntioctl.in.filter = filter; - nttrans_setup_reply(req, trans, 0, 0, 1); + status = nttrans_setup_reply(op, trans, 0, 0, 1); + NT_STATUS_NOT_OK_RETURN(status); + trans->out.setup[0] = 0; return ntvfs_ioctl(req, nt); @@ -330,7 +341,49 @@ static NTSTATUS nttrans_ioctl(struct smbsrv_request *req, */ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op) { - return NT_STATUS_NOT_IMPLEMENTED; + struct smb_notify *info = talloc_get_type(op->op_info, struct smb_notify); + size_t size = 0; + int i; + NTSTATUS status; + uint32_t ofs=0; + uint8_t *p; +#define MAX_BYTES_PER_CHAR 3 + + /* work out how big the reply buffer could be */ + for (i=0;i<info->out.num_changes;i++) { + size += 12 + 3 + (1+strlen(info->out.changes[i].name.s)) * MAX_BYTES_PER_CHAR; + } + + status = nttrans_setup_reply(op, op->trans, size, 0, 0); + NT_STATUS_NOT_OK_RETURN(status); + + p = op->trans->out.params.data; + + /* construct the changes buffer */ + for (i=0;i<info->out.num_changes;i++) { + ssize_t len; + + SIVAL(p, 4, info->out.changes[i].action); + len = push_string(p + 12, info->out.changes[i].name.s, + op->trans->out.params.length - (ofs+12), STR_UNICODE); + SIVAL(p, 8, len); + + ofs += len + 12; + + if (ofs & 3) { + int pad = 4 - (ofs & 3); + memset(p+ofs, 0, pad); + ofs += pad; + } + + SIVAL(p, 0, ofs); + + p = op->trans->out.params.data + ofs; + } + + op->trans->out.params.length = ofs; + + return NT_STATUS_OK; } /* |