/* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_notify *io) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; int saved_timeout = p->transport->options.request_timeout; struct cvfs_file *f; if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { return NT_STATUS_NOT_IMPLEMENTED; } SETUP_PID; f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); if (!f) return NT_STATUS_INVALID_HANDLE; io->nttrans.in.file.fnum = f->fnum; /* this request doesn't make sense unless its async */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return NT_STATUS_INVALID_PARAMETER; } /* we must not timeout on notify requests - they wait forever */ p->transport->options.request_timeout = 0; c_req = smb_raw_changenotify_send(p->tree, io); p->transport->options.request_timeout = saved_timeout; ASYNC_RECV_TAIL(io, async_changenotify); }
/* return filesystem space info */ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { struct cvfs_private *p = ntvfs->private_data; struct smb2_request *c_req; enum smb_fsinfo_level level = fs->generic.level; CHECK_ASYNC(req); switch (level) { /* some levels go straight through */ case RAW_QFS_VOLUME_INFORMATION: case RAW_QFS_SIZE_INFORMATION: case RAW_QFS_DEVICE_INFORMATION: case RAW_QFS_ATTRIBUTE_INFORMATION: case RAW_QFS_QUOTA_INFORMATION: case RAW_QFS_FULL_SIZE_INFORMATION: case RAW_QFS_OBJECTID_INFORMATION: break; /* some get mapped */ case RAW_QFS_VOLUME_INFO: level = RAW_QFS_VOLUME_INFORMATION; break; case RAW_QFS_SIZE_INFO: level = RAW_QFS_SIZE_INFORMATION; break; case RAW_QFS_DEVICE_INFO: level = RAW_QFS_DEVICE_INFORMATION; break; case RAW_QFS_ATTRIBUTE_INFO: level = RAW_QFS_ATTRIBUTE_INFO; break; default: /* the rest get refused for now */ DEBUG(0,("fsinfo level %u not possible on SMB2\n", (unsigned)fs->generic.level)); break; } fs->generic.level = level; fs->generic.handle = p->roothandle; c_req = smb2_getinfo_fs_send(p->tree, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); }
/* query info on a open file */ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *io) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID_AND_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fileinfo(p->tree, req, io); } c_req = smb_raw_fileinfo_send(p->tree, io); ASYNC_RECV_TAIL(io, async_qfileinfo); }
/* ioctl interface */ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID_AND_FILE; /* see if the front end will allow us to perform this function asynchronously. */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_ioctl(p->tree, req, io); } c_req = smb_raw_ioctl_send(p->tree, io); ASYNC_RECV_TAIL(io, async_ioctl); }
/* raw trans2 */ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_trans2 *trans2) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; if (p->map_trans2) { return NT_STATUS_NOT_IMPLEMENTED; } SETUP_PID; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_trans2(p->tree, req, trans2); } c_req = smb_raw_trans2_send(p->tree, trans2); ASYNC_RECV_TAIL(trans2, async_trans2); }
/* write to a file */ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *io) { struct cvfs_private *p = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID; if (io->generic.level != RAW_WRITE_GENERIC && p->map_generic) { return ntvfs_map_write(ntvfs, req, io); } SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_write(p->tree, io); } c_req = smb_raw_write_send(p->tree, io); ASYNC_RECV_TAIL(io, async_write); }