Author: metze
Date: 2006-07-12 17:14:32 +0000 (Wed, 12 Jul 2006)
New Revision: 16989

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16989

Log:
implement SMB2 Notify in the frontend

metze
Modified:
   branches/SAMBA_4_0/source/smb_server/smb2/fileio.c


Changeset:
Modified: branches/SAMBA_4_0/source/smb_server/smb2/fileio.c
===================================================================
--- branches/SAMBA_4_0/source/smb_server/smb2/fileio.c  2006-07-12 16:36:50 UTC 
(rev 16988)
+++ branches/SAMBA_4_0/source/smb_server/smb2/fileio.c  2006-07-12 17:14:32 UTC 
(rev 16989)
@@ -291,9 +291,83 @@
        smb2srv_send_error(req, NT_STATUS_NOT_IMPLEMENTED);
 }
 
+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);
+}
+
 void smb2srv_notify_recv(struct smb2srv_request *req)
 {
-       smb2srv_send_error(req, NT_STATUS_NOT_IMPLEMENTED);
+       union smb_notify *io;
+
+       SMB2SRV_CHECK_BODY_SIZE(req, 0x20, False);
+       SMB2SRV_TALLOC_IO_PTR(io, union smb_notify);
+       SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_notify_send, 
NTVFS_ASYNC_STATE_MAY_ASYNC);
+
+       io->smb2.level                  = RAW_NOTIFY_SMB2;
+       io->smb2.in.recursive           = SVAL(req->in.body, 0x02);
+       io->smb2.in.buffer_size         = IVAL(req->in.body, 0x04);
+       io->smb2.in.file.ntvfs          = smb2srv_pull_handle(req, 
req->in.body, 0x08);
+       io->smb2.in.completion_filter   = IVAL(req->in.body, 0x18);
+       io->smb2.in.unknown             = BVAL(req->in.body, 0x1C);
+
+       SMB2SRV_CHECK_FILE_HANDLE(io->smb2.in.file.ntvfs);
+       SMB2SRV_CALL_NTVFS_BACKEND(ntvfs_notify(req->ntvfs, io));
 }
 
 void smb2srv_break_recv(struct smb2srv_request *req)

Reply via email to