📄 ntvfs_generic.c
字号:
status = ntvfs_map_async_setup(ntvfs, req, io, io2, (second_stage_t)ntvfs_map_open_finish); if (!NT_STATUS_IS_OK(status)) { return status; } io2->generic.level = RAW_OPEN_GENERIC; switch (io->generic.level) { case RAW_OPEN_OPENX: status = map_openx_open(io->openx.in.flags, io->openx.in.open_mode, io->openx.in.open_func, io->openx.in.fname, io2); if (!NT_STATUS_IS_OK(status)) { goto done; } io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_OPEN: status = map_openx_open(0, io->openold.in.open_mode, OPENX_OPEN_FUNC_OPEN, io->openold.in.fname, io2); if (!NT_STATUS_IS_OK(status)) { goto done; } io2->generic.in.file_attr = io->openold.in.search_attrs; io2->generic.in.fname = io->openold.in.fname; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_T2OPEN: io2->generic.level = RAW_OPEN_NTTRANS_CREATE; if (io->t2open.in.open_func == 0) { status = NT_STATUS_OBJECT_NAME_COLLISION; goto done; } status = map_openx_open(io->t2open.in.flags, io->t2open.in.open_mode, io->t2open.in.open_func, io->t2open.in.fname, io2); if (!NT_STATUS_IS_OK(status)) { goto done; } io2->generic.in.file_attr = io->t2open.in.file_attrs; io2->generic.in.fname = io->t2open.in.fname; io2->generic.in.ea_list = talloc(io2, struct smb_ea_list); io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas; io2->generic.in.ea_list->eas = io->t2open.in.eas; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_MKNEW: io2->generic.in.file_attr = io->mknew.in.attrib; io2->generic.in.fname = io->mknew.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_CREATE: io2->generic.in.file_attr = io->mknew.in.attrib; io2->generic.in.fname = io->mknew.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_CTEMP: io2->generic.in.file_attr = io->ctemp.in.attrib; io2->generic.in.fname = talloc_asprintf(io2, "%s\\SRV%s", io->ctemp.in.directory, generate_random_str_list(io2, 5, "0123456789")); io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_SMB2: switch (io->smb2.in.oplock_level) { case SMB2_OPLOCK_LEVEL_BATCH: io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | NTCREATEX_FLAGS_REQUEST_OPLOCK; break; case SMB2_OPLOCK_LEVEL_EXCLUSIVE: io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_OPLOCK; break; default: io2->generic.in.flags = 0; break; } io2->generic.in.root_fid = 0; io2->generic.in.access_mask = io->smb2.in.desired_access; io2->generic.in.alloc_size = io->smb2.in.alloc_size; io2->generic.in.file_attr = io->smb2.in.file_attributes; io2->generic.in.share_access = io->smb2.in.share_access; io2->generic.in.open_disposition= io->smb2.in.create_disposition; io2->generic.in.create_options = io->smb2.in.create_options; io2->generic.in.impersonation = io->smb2.in.impersonation_level; io2->generic.in.security_flags = 0; io2->generic.in.fname = io->smb2.in.fname; io2->generic.in.sec_desc = io->smb2.in.sec_desc; io2->generic.in.ea_list = &io->smb2.in.eas; io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access; /* we don't support timewarp yet */ if (io->smb2.in.timewarp != 0) { status = NT_STATUS_OBJECT_NAME_NOT_FOUND; break; } /* we need to check these bits before we check the private mask */ if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { status = NT_STATUS_NOT_SUPPORTED; break; } /* we use a couple of bits of the create options internally */ if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) { status = NT_STATUS_INVALID_PARAMETER; break; } status = ntvfs->ops->open(ntvfs, req, io2); break; default: status = NT_STATUS_INVALID_LEVEL; break; }done: return ntvfs_map_async_finish(req, status);}/* NTVFS fsinfo generic to any mapper*/NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs){ NTSTATUS status; union smb_fsinfo *fs2; fs2 = talloc(req, union smb_fsinfo); if (fs2 == NULL) { return NT_STATUS_NO_MEMORY; } if (fs->generic.level == RAW_QFS_GENERIC) { return NT_STATUS_INVALID_LEVEL; } /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; /* ask the backend for the generic info */ fs2->generic.level = RAW_QFS_GENERIC; status = ntvfs->ops->fsinfo(ntvfs, req, fs2); if (!NT_STATUS_IS_OK(status)) { return status; } /* and convert it to the required level */ switch (fs->generic.level) { case RAW_QFS_GENERIC: return NT_STATUS_INVALID_LEVEL; case RAW_QFS_DSKATTR: { /* map from generic to DSKATTR */ uint_t bpunit = 64; /* we need to scale the sizes to fit */ for (bpunit=64; bpunit<0x10000; bpunit *= 2) { if (fs2->generic.out.blocks_total * (double)fs2->generic.out.block_size < bpunit * 512 * 65535.0) { break; } } fs->dskattr.out.blocks_per_unit = bpunit; fs->dskattr.out.block_size = 512; fs->dskattr.out.units_total = (fs2->generic.out.blocks_total * (double)fs2->generic.out.block_size) / (bpunit * 512); fs->dskattr.out.units_free = (fs2->generic.out.blocks_free * (double)fs2->generic.out.block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ if (bpunit > 64 && req->ctx->protocol <= PROTOCOL_LANMAN2) { fs->dskattr.out.blocks_per_unit = 64; fs->dskattr.out.units_total = 0xFFFF; fs->dskattr.out.units_free = 0xFFFF; } return NT_STATUS_OK; } case RAW_QFS_ALLOCATION: fs->allocation.out.fs_id = fs2->generic.out.fs_id; fs->allocation.out.total_alloc_units = fs2->generic.out.blocks_total; fs->allocation.out.avail_alloc_units = fs2->generic.out.blocks_free; fs->allocation.out.sectors_per_unit = 1; fs->allocation.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_VOLUME: fs->volume.out.serial_number = fs2->generic.out.serial_number; fs->volume.out.volume_name.s = fs2->generic.out.volume_name; return NT_STATUS_OK; case RAW_QFS_VOLUME_INFO: case RAW_QFS_VOLUME_INFORMATION: fs->volume_info.out.create_time = fs2->generic.out.create_time; fs->volume_info.out.serial_number = fs2->generic.out.serial_number; fs->volume_info.out.volume_name.s = fs2->generic.out.volume_name; return NT_STATUS_OK; case RAW_QFS_SIZE_INFO: case RAW_QFS_SIZE_INFORMATION: fs->size_info.out.total_alloc_units = fs2->generic.out.blocks_total; fs->size_info.out.avail_alloc_units = fs2->generic.out.blocks_free; fs->size_info.out.sectors_per_unit = 1; fs->size_info.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_DEVICE_INFO: case RAW_QFS_DEVICE_INFORMATION: fs->device_info.out.device_type = fs2->generic.out.device_type; fs->device_info.out.characteristics = fs2->generic.out.device_characteristics; return NT_STATUS_OK; case RAW_QFS_ATTRIBUTE_INFO: case RAW_QFS_ATTRIBUTE_INFORMATION: fs->attribute_info.out.fs_attr = fs2->generic.out.fs_attr; fs->attribute_info.out.max_file_component_length = fs2->generic.out.max_file_component_length; fs->attribute_info.out.fs_type.s = fs2->generic.out.fs_type; return NT_STATUS_OK; case RAW_QFS_QUOTA_INFORMATION: ZERO_STRUCT(fs->quota_information.out.unknown); fs->quota_information.out.quota_soft = fs2->generic.out.quota_soft; fs->quota_information.out.quota_hard = fs2->generic.out.quota_hard; fs->quota_information.out.quota_flags = fs2->generic.out.quota_flags; return NT_STATUS_OK; case RAW_QFS_FULL_SIZE_INFORMATION: fs->full_size_information.out.total_alloc_units = fs2->generic.out.blocks_total; fs->full_size_information.out.call_avail_alloc_units = fs2->generic.out.blocks_free; fs->full_size_information.out.actual_avail_alloc_units = fs2->generic.out.blocks_free; fs->full_size_information.out.sectors_per_unit = 1; fs->full_size_information.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_OBJECTID_INFORMATION: fs->objectid_information.out.guid = fs2->generic.out.guid; ZERO_STRUCT(fs->objectid_information.out.unknown); return NT_STATUS_OK; } return NT_STATUS_INVALID_LEVEL;}/* NTVFS fileinfo generic to any mapper*/NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, union smb_fileinfo *info, union smb_fileinfo *info2){ int i; /* and convert it to the required level using results in info2 */ switch (info->generic.level) { case RAW_FILEINFO_GENERIC: return NT_STATUS_INVALID_LEVEL; case RAW_FILEINFO_GETATTR: info->getattr.out.attrib = info2->generic.out.attrib & 0xff; info->getattr.out.size = info2->generic.out.size; info->getattr.out.write_time = nt_time_to_unix(info2->generic.out.write_time); return NT_STATUS_OK; case RAW_FILEINFO_GETATTRE: info->getattre.out.attrib = info2->generic.out.attrib; info->getattre.out.size = info2->generic.out.size; info->getattre.out.write_time = nt_time_to_unix(info2->generic.out.write_time); info->getattre.out.create_time = nt_time_to_unix(info2->generic.out.create_time); info->getattre.out.access_time = nt_time_to_unix(info2->generic.out.access_time); info->getattre.out.alloc_size = info2->generic.out.alloc_size; return NT_STATUS_OK; case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: info->network_open_information.out.create_time = info2->generic.out.create_time; info->network_open_information.out.access_time = info2->generic.out.access_time; info->network_open_information.out.write_time = info2->generic.out.write_time; info->network_open_information.out.change_time = info2->generic.out.change_time; info->network_open_information.out.alloc_size = info2->generic.out.alloc_size; info->network_open_information.out.size = info2->generic.out.size; info->network_open_information.out.attrib = info2->generic.out.attrib; return NT_STATUS_OK; case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: info->all_info.out.create_time = info2->generic.out.create_time; info->all_info.out.access_time = info2->generic.out.access_time; info->all_info.out.write_time = info2->generic.out.write_time; info->all_info.out.change_time = info2->generic.out.change_time; info->all_info.out.attrib = info2->generic.out.attrib; info->all_info.out.alloc_size = info2->generic.out.alloc_size; info->all_info.out.size = info2->generic.out.size; info->all_info.out.nlink = info2->generic.out.nlink; info->all_info.out.delete_pending = info2->generic.out.delete_pending; info->all_info.out.directory = info2->generic.out.directory; info->all_info.out.ea_size = info2->generic.out.ea_size; info->all_info.out.fname.s = info2->generic.out.fname.s; info->all_info.out.fname.private_length = info2->generic.out.fname.private_length; return NT_STATUS_OK; case RAW_FILEINFO_BASIC_INFO: case RAW_FILEINFO_BASIC_INFORMATION: info->basic_info.out.create_time = info2->generic.out.create_time; info->basic_info.out.access_time = info2->generic.out.access_time; info->basic_info.out.write_time = info2->generic.out.write_time; info->basic_info.out.change_time = info2->generic.out.change_time; info->basic_info.out.attrib = info2->generic.out.attrib; return NT_STATUS_OK; case RAW_FILEINFO_STANDARD: info->standard.out.create_time = nt_time_to_unix(info2->generic.out.create_time); info->standard.out.access_time = nt_time_to_unix(info2->generic.out.access_time); info->standard.out.write_time = nt_time_to_unix(info2->generic.out.write_time); info->standard.out.size = info2->generic.out.size; info->standard.out.alloc_size = info2->generic.out.alloc_size; info->standard.out.attrib = info2->generic.out.attrib; return NT_STATUS_OK; case RAW_FILEINFO_EA_SIZE: info->ea_size.out.create_time = nt_time_to_unix(info2->generic.out.create_time); info->ea_size.out.access_time = nt_time_to_unix(info2->generic.out.access_time); info->ea_size.out.write_time = nt_time_to_unix(info2->generic.out.write_time); info->ea_size.out.size = info2->generic.out.size; info->ea_size.out.alloc_size = info2->generic.out.alloc_size; info->ea_size.out.attrib = info2->generic.out.attrib; info->ea_size.out.ea_size = info2->generic.out.ea_size; return NT_STATUS_OK; case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: info->standard_info.out.alloc_size = info2->generic.out.alloc_size; info->standard_info.out.size = info2->generic.out.size; info->standard_info.out.nlink = info2->generic.out.nlink; info->standard_info.out.delete_pending = info2->generic.out.delete_pending; info->standard_info.out.directory = info2->generic.out.directory; return NT_STATUS_OK; case RAW_FILEINFO_INTERNAL_INFORMATION:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -