📄 reply.c
字号:
****************************************************************************/void smbsrv_reply_echo(struct smbsrv_request *req){ uint16_t count; int i; SMBSRV_CHECK_WCT(req, 1); count = SVAL(req->in.vwv, VWV(0)); smbsrv_setup_reply(req, 1, req->in.data_size); memcpy(req->out.data, req->in.data, req->in.data_size); for (i=1; i <= count;i++) { struct smbsrv_request *this_req; if (i != count) { this_req = smbsrv_setup_secondary_request(req); } else { this_req = req; } SSVAL(this_req->out.vwv, VWV(0), i); smbsrv_send_reply(this_req); }}/**************************************************************************** Reply to a printopen (async reply)****************************************************************************/static void reply_printopen_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_open *oi; SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open); /* construct reply */ smbsrv_setup_reply(req, 1, 0); smbsrv_push_fnum(req->out.vwv, VWV(0), oi->openold.out.file.ntvfs); smbsrv_send_reply(req);}/**************************************************************************** Reply to a printopen.****************************************************************************/void smbsrv_reply_printopen(struct smbsrv_request *req){ union smb_open *oi; /* parse request */ SMBSRV_CHECK_WCT(req, 2); SMBSRV_TALLOC_IO_PTR(oi, union smb_open); SMBSRV_SETUP_NTVFS_REQUEST(reply_printopen_send, NTVFS_ASYNC_STATE_MAY_ASYNC); oi->splopen.level = RAW_OPEN_SPLOPEN; oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0)); oi->splopen.in.mode = SVAL(req->in.vwv, VWV(1)); req_pull_ascii4(&req->in.bufinfo, &oi->splopen.in.ident, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));}/**************************************************************************** Reply to a printclose.****************************************************************************/void smbsrv_reply_printclose(struct smbsrv_request *req){ union smb_close *io; /* parse request */ SMBSRV_CHECK_WCT(req, 3); SMBSRV_TALLOC_IO_PTR(io, union smb_close); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->splclose.level = RAW_CLOSE_SPLCLOSE; io->splclose.in.file.ntvfs = smbsrv_pull_fnum(req, req->in.vwv, VWV(0)); SMBSRV_CHECK_FILE_HANDLE(io->splclose.in.file.ntvfs); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_close(req->ntvfs, io));}/**************************************************************************** Reply to a printqueue.****************************************************************************/static void reply_printqueue_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_lpq *lpq; int i, maxcount; const uint_t el_size = 28; SMBSRV_CHECK_ASYNC_STATUS(lpq,union smb_lpq); /* construct reply */ smbsrv_setup_reply(req, 2, 0); /* truncate the returned list to fit in the negotiated buffer size */ maxcount = (req_max_data(req) - 3) / el_size; if (maxcount < lpq->retq.out.count) { lpq->retq.out.count = maxcount; } /* setup enough space in the reply */ req_grow_data(req, 3 + el_size*lpq->retq.out.count); /* and fill it in */ SSVAL(req->out.vwv, VWV(0), lpq->retq.out.count); SSVAL(req->out.vwv, VWV(1), lpq->retq.out.restart_idx); SCVAL(req->out.data, 0, SMB_DATA_BLOCK); SSVAL(req->out.data, 1, el_size*lpq->retq.out.count); req->out.ptr = req->out.data + 3; for (i=0;i<lpq->retq.out.count;i++) { srv_push_dos_date2(req->smb_conn, req->out.ptr, 0 , lpq->retq.out.queue[i].time); SCVAL(req->out.ptr, 4, lpq->retq.out.queue[i].status); SSVAL(req->out.ptr, 5, lpq->retq.out.queue[i].job); SIVAL(req->out.ptr, 7, lpq->retq.out.queue[i].size); SCVAL(req->out.ptr, 11, 0); /* reserved */ req_push_str(req, req->out.ptr+12, lpq->retq.out.queue[i].user, 16, STR_ASCII); req->out.ptr += el_size; } smbsrv_send_reply(req);}/**************************************************************************** Reply to a printqueue.****************************************************************************/void smbsrv_reply_printqueue(struct smbsrv_request *req){ union smb_lpq *lpq; /* parse request */ SMBSRV_CHECK_WCT(req, 2); SMBSRV_TALLOC_IO_PTR(lpq, union smb_lpq); SMBSRV_SETUP_NTVFS_REQUEST(reply_printqueue_send, NTVFS_ASYNC_STATE_MAY_ASYNC); lpq->retq.level = RAW_LPQ_RETQ; lpq->retq.in.maxcount = SVAL(req->in.vwv, VWV(0)); lpq->retq.in.startidx = SVAL(req->in.vwv, VWV(1)); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_lpq(req->ntvfs, lpq));}/**************************************************************************** Reply to a printwrite.****************************************************************************/void smbsrv_reply_printwrite(struct smbsrv_request *req){ union smb_write *io; /* parse request */ SMBSRV_CHECK_WCT(req, 1); SMBSRV_TALLOC_IO_PTR(io, union smb_write); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); if (req->in.data_size < 3) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } io->splwrite.level = RAW_WRITE_SPLWRITE; io->splwrite.in.file.ntvfs = smbsrv_pull_fnum(req, req->in.vwv, VWV(0)); io->splwrite.in.count = SVAL(req->in.data, 1); io->splwrite.in.data = req->in.data + 3; /* make sure they gave us the data they promised */ if (req_data_oob(&req->in.bufinfo, io->splwrite.in.data, io->splwrite.in.count)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } SMBSRV_CHECK_FILE_HANDLE(io->splwrite.in.file.ntvfs); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));}/**************************************************************************** Reply to a mkdir.****************************************************************************/void smbsrv_reply_mkdir(struct smbsrv_request *req){ union smb_mkdir *io; /* parse the request */ SMBSRV_CHECK_WCT(req, 0); SMBSRV_TALLOC_IO_PTR(io, union smb_mkdir); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->generic.level = RAW_MKDIR_MKDIR; req_pull_ascii4(&req->in.bufinfo, &io->mkdir.in.path, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io));}/**************************************************************************** Reply to a rmdir.****************************************************************************/void smbsrv_reply_rmdir(struct smbsrv_request *req){ struct smb_rmdir *io; /* parse the request */ SMBSRV_CHECK_WCT(req, 0); SMBSRV_TALLOC_IO_PTR(io, struct smb_rmdir); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); req_pull_ascii4(&req->in.bufinfo, &io->in.path, req->in.data, STR_TERMINATE); SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io));}/**************************************************************************** Reply to a mv.****************************************************************************/void smbsrv_reply_mv(struct smbsrv_request *req){ union smb_rename *io; uint8_t *p; /* parse the request */ SMBSRV_CHECK_WCT(req, 1); SMBSRV_TALLOC_IO_PTR(io, union smb_rename); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->generic.level = RAW_RENAME_RENAME; io->rename.in.attrib = SVAL(req->in.vwv, VWV(0)); p = req->in.data; p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern1, p, STR_TERMINATE); p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern2, p, STR_TERMINATE); if (!io->rename.in.pattern1 || !io->rename.in.pattern2) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rename(req->ntvfs, io));}/**************************************************************************** Reply to an NT rename.****************************************************************************/void smbsrv_reply_ntrename(struct smbsrv_request *req){ union smb_rename *io; uint8_t *p; /* parse the request */ SMBSRV_CHECK_WCT(req, 4); SMBSRV_TALLOC_IO_PTR(io, union smb_rename); SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->generic.level = RAW_RENAME_NTRENAME; io->ntrename.in.attrib = SVAL(req->in.vwv, VWV(0)); io->ntrename.in.flags = SVAL(req->in.vwv, VWV(1)); io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2)); p = req->in.data; p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.old_name, p, STR_TERMINATE); p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.new_name, p, STR_TERMINATE); if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rename(req->ntvfs, io));}/**************************************************************************** Reply to a file copy (async reply)****************************************************************************/static void reply_copy_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; struct smb_copy *cp; SMBSRV_CHECK_ASYNC_STATUS(cp, struct smb_copy); /* build the reply */ smbsrv_setup_reply(req, 1, 0); SSVAL(req->out.vwv, VWV(0), cp->out.count); smbsrv_send_reply(req);}/**************************************************************************** Reply to a file copy.****************************************************************************/void smbsrv_reply_copy(struct smbsrv_request *req){ struct smb_copy *cp; uint8_t *p; /* parse request */ SMBSRV_CHECK_WCT(req, 3); SMBSRV_TALLOC_IO_PTR(cp, struct smb_copy); SMBSRV_SETUP_NTVFS_REQUEST(reply_copy_send, NTVFS_ASYNC_STATE_MAY_ASYNC); cp->in.tid2 = SVAL(req->in.vwv, VWV(0)); cp->in.ofun = SVAL(req->in.vwv, VWV(1)); cp->in.flags = SVAL(req->in.vwv, VWV(2)); p = req->in.data; p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path1, p, STR_TERMINATE); p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path2, p, STR_TERMINATE); if (!cp->in.path1 || !cp->in.path2) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } SMBSRV_CALL_NTVFS_BACKEND(ntvfs_copy(req->ntvfs, cp));}/**************************************************************************** Reply to a lockingX request (async send)****************************************************************************/static void reply_lockingX_send(struct ntvfs_request *ntvfs){ struct smbsrv_request *req; union smb_lock *lck; SMBSRV_CHECK_ASYNC_STATUS(lck, union smb_lock); /* if it was an oplock break ack then we only send a reply if there was an error */ if (lck->lockx.in.ulock_cnt + lck->lockx.in.lock_cnt == 0) { talloc_free(req); return; } /* construct reply */ smbsrv_setup_reply(req, 2, 0); SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE); SSVAL(req->out.vwv, VWV(1), 0); smbsrv_chain_reply(req);}/**************************************************************************** Reply to a lockingX request.****************************************************************************/void smbsrv_reply_lockingX(struct smbsrv_request *req){ union smb_lock *lck; uint_t total_locks, i; uint_t lck_size; uint8_t *p; /* parse request */ SMBSRV_CHECK_WCT(req, 8); SMBSRV_TALLOC_IO_PTR(lck, union smb_lock); SMBSRV_SETUP_NTVFS_REQUEST(reply_lockingX_send, NTVFS_ASYNC_STATE_MAY_ASYNC); lck->lockx.level = RAW_LOCK_LOCKX; lck->lockx.in.file.ntvfs= smbsrv_pull_fnum(req, req->in.vwv, VWV(2)); lck->lockx.in.mode = SVAL(req->in.vwv, VWV(3)); lck->lockx.in.timeout = IVAL(req->in.vwv, VWV(4)); lck->lockx.in.ulock_cnt = SVAL(req->in.vwv, VWV(6)); lck->lockx.in.lock_cnt = SVAL(req->in.vwv, VWV(7)); total_locks = lck->lockx.in.ulock_cnt + lck->lockx.in.lock_cnt; /* there are two variants, one with 64 bit offsets and counts */ if (lck->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) { lck_size = 20; } else { lck_size = 10; } /* make sure we got the promised data */ if (req_data_oob(&req->in.bufinfo, req->in.data, total_locks * lck_size)) { smbsrv_send_error(req, NT_STATUS_FOOBAR); return; } /* allocate the locks array */ if (total_locks) { lck->lockx.in.locks = talloc_array(req, struct smb_lock_entry, total_locks); if (lck->lockx.in.locks == NULL) { smbsrv_send_error(req, NT_STATUS_NO_MEMORY); return; } } p = req->in.data; /* construct the locks array */ for (i=0;i<total_locks;i++) { uint32_t ofs_high=0, count_high=0; lck->lockx.in.locks[i].pid = SVAL(p, 0); if (lck->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) { ofs_high = IVAL(p, 4); lck->lockx.in.locks[i].offset = IVAL(p, 8); count_high = IVAL(p, 12); lck->lockx.in.locks[i].count = IVAL(p, 16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -