📄 vfs_simple.c
字号:
return NT_STATUS_INVALID_HANDLE; } ret = pwrite(f->fd, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); if (ret == -1) { return map_nt_error_from_unix(errno); } wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ return NT_STATUS_OK;}/* seek in a file*/static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_seek *io){ return NT_STATUS_NOT_SUPPORTED;}/* flush a file*/static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io){ struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; switch (io->generic.level) { case RAW_FLUSH_FLUSH: case RAW_FLUSH_SMB2: /* ignore the additional unknown option in SMB2 */ f = find_fd(private, io->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } fsync(f->fd); return NT_STATUS_OK; case RAW_FLUSH_ALL: for (f=private->open_files;f;f=f->next) { fsync(f->fd); } return NT_STATUS_OK; } return NT_STATUS_INVALID_LEVEL;}/* close a file*/static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io){ struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ return NT_STATUS_INVALID_LEVEL; } f = find_fd(private, io->close.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } if (close(f->fd) == -1) { return map_nt_error_from_unix(errno); } DLIST_REMOVE(private->open_files, f); talloc_free(f->name); talloc_free(f); return NT_STATUS_OK;}/* exit - closing files*/static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req){ return NT_STATUS_NOT_SUPPORTED;}/* logoff - closing files*/static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req){ return NT_STATUS_NOT_SUPPORTED;}/* setup for an async call*/static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, void *private){ return NT_STATUS_OK;}/* cancel an async call*/static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req){ return NT_STATUS_UNSUCCESSFUL;}/* lock a byte range*/static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *lck){ DEBUG(0,("REWRITE: not doing byte range locking!\n")); return NT_STATUS_OK;}/* set info on a pathname*/static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *st){ CHECK_READ_ONLY(req); return NT_STATUS_NOT_SUPPORTED;}/* set info on a open file*/static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *info){ struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; struct utimbuf unix_times; CHECK_READ_ONLY(req); f = find_fd(private, info->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } switch (info->generic.level) { case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: if (ftruncate(f->fd, info->end_of_file_info.in.size) == -1) { return map_nt_error_from_unix(errno); } break; case RAW_SFILEINFO_SETATTRE: unix_times.actime = info->setattre.in.access_time; unix_times.modtime = info->setattre.in.write_time; if (unix_times.actime == 0 && unix_times.modtime == 0) { break; } /* set modify time = to access time if modify time was 0 */ if (unix_times.actime != 0 && unix_times.modtime == 0) { unix_times.modtime = unix_times.actime; } /* Set the date on this file */ if (svfs_file_utime(f->fd, &unix_times) != 0) { return NT_STATUS_ACCESS_DENIED; } break; default: DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", info->generic.level)); return NT_STATUS_NOT_IMPLEMENTED; } return NT_STATUS_OK;}/* return filesystem space info*/static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs){ struct svfs_private *private = ntvfs->private_data; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { return ntvfs_map_fsinfo(ntvfs, req, fs); } if (sys_fsusage(private->connectpath, &fs->generic.out.blocks_free, &fs->generic.out.blocks_total) == -1) { return map_nt_error_from_unix(errno); } fs->generic.out.block_size = 512; if (stat(private->connectpath, &st) != 0) { return NT_STATUS_DISK_CORRUPT_ERROR; } fs->generic.out.fs_id = st.st_ino; unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); fs->generic.out.serial_number = st.st_ino; fs->generic.out.fs_attr = 0; fs->generic.out.max_file_component_length = 255; fs->generic.out.device_type = 0; fs->generic.out.device_characteristics = 0; fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK;}#if 0/* return filesystem attribute info*/static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsattr *fs){ struct stat st; struct svfs_private *private = ntvfs->private_data; if (fs->generic.level != RAW_FSATTR_GENERIC) { return ntvfs_map_fsattr(ntvfs, req, fs); } if (stat(private->connectpath, &st) == -1) { return map_nt_error_from_unix(errno); } unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); fs->generic.out.fs_attr = FILE_CASE_PRESERVED_NAMES | FILE_CASE_SENSITIVE_SEARCH | FILE_PERSISTENT_ACLS; fs->generic.out.max_file_component_length = 255; fs->generic.out.serial_number = 1; fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(req->tcon->service)); return NT_STATUS_OK;}#endif/* return print queue info*/static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lpq *lpq){ return NT_STATUS_NOT_SUPPORTED;}/* list files in a directory matching a wildcard pattern*/static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, bool (*callback)(void *, const union smb_search_data *)){ struct svfs_dir *dir; int i; struct svfs_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; if (io->generic.level != RAW_SEARCH_TRANS2) { return NT_STATUS_NOT_SUPPORTED; } if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } search = talloc_zero(private, struct search_state); if (!search) { return NT_STATUS_NO_MEMORY; } max_count = io->t2ffirst.in.max_count; dir = svfs_list(ntvfs, req, io->t2ffirst.in.pattern); if (!dir) { return NT_STATUS_FOOBAR; } search->handle = private->next_search_handle; search->dir = dir; if (dir->count < max_count) { max_count = dir->count; } for (i=0; i < max_count;i++) { ZERO_STRUCT(file); unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; } } search->current_index = i; io->t2ffirst.out.count = i; io->t2ffirst.out.handle = search->handle; io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; /* work out if we are going to keep the search state */ if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { talloc_free(search); } else { private->next_search_handle++; DLIST_ADD(private->search, search); } return NT_STATUS_OK;}/* continue a search */static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, bool (*callback)(void *, const union smb_search_data *)){ struct svfs_dir *dir; int i; struct svfs_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; if (io->generic.level != RAW_SEARCH_TRANS2) { return NT_STATUS_NOT_SUPPORTED; } if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } for (search=private->search; search; search = search->next) { if (search->handle == io->t2fnext.in.handle) break; } if (!search) { /* we didn't find the search handle */ return NT_STATUS_FOOBAR; } dir = search->dir; /* the client might be asking for something other than just continuing with the search */ if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { /* look backwards first */ for (i=search->current_index; i > 0; i--) { if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { search->current_index = i; goto found; } } /* then look forwards */ for (i=search->current_index+1; i <= dir->count; i++) { if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { search->current_index = i; goto found; } } }found: max_count = search->current_index + io->t2fnext.in.max_count; if (max_count > dir->count) { max_count = dir->count; } for (i = search->current_index; i < max_count;i++) { ZERO_STRUCT(file); unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; } } io->t2fnext.out.count = i - search->current_index; io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; search->current_index = i; /* work out if we are going to keep the search state */ if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { DLIST_REMOVE(private->search, search); talloc_free(search); } return NT_STATUS_OK;}/* close a search */static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io){ struct svfs_private *private = ntvfs->private_data; struct search_state *search; for (search=private->search; search; search = search->next) { if (search->handle == io->findclose.in.handle) break; } if (!search) { /* we didn't find the search handle */ return NT_STATUS_FOOBAR; } DLIST_REMOVE(private->search, search); talloc_free(search); return NT_STATUS_OK;}/* SMBtrans - not used on file shares */static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_trans2 *trans2){ return NT_STATUS_ACCESS_DENIED;}/* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem */NTSTATUS ntvfs_simple_init(void){ NTSTATUS ret; struct ntvfs_ops ops; NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); /* fill in all the operations */ ops.connect = svfs_connect; ops.disconnect = svfs_disconnect; ops.unlink = svfs_unlink; ops.chkpath = svfs_chkpath; ops.qpathinfo = svfs_qpathinfo; ops.setpathinfo = svfs_setpathinfo; ops.open = svfs_open; ops.mkdir = svfs_mkdir; ops.rmdir = svfs_rmdir; ops.rename = svfs_rename; ops.copy = svfs_copy; ops.ioctl = svfs_ioctl; ops.read = svfs_read; ops.write = svfs_write; ops.seek = svfs_seek; ops.flush = svfs_flush; ops.close = svfs_close; ops.exit = svfs_exit; ops.lock = svfs_lock; ops.setfileinfo = svfs_setfileinfo; ops.qfileinfo = svfs_qfileinfo; ops.fsinfo = svfs_fsinfo; ops.lpq = svfs_lpq; ops.search_first = svfs_search_first; ops.search_next = svfs_search_next; ops.search_close = svfs_search_close; ops.trans = svfs_trans; ops.logoff = svfs_logoff; ops.async_setup = svfs_async_setup; ops.cancel = svfs_cancel; /* register ourselves with the NTVFS subsystem. We register under names 'simple' */ ops.type = NTVFS_DISK; ops.name = "simple"; ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register simple backend with name: %s!\n", ops.name)); } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -