smb_sdrc_t smb_com_open(smb_request_t *sr) { struct open_param *op = &sr->arg.open; smb_node_t *node; smb_attr_t attr; uint16_t file_attr; int rc; op->desired_access = smb_omode_to_amask(op->omode); op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.fq_path.pn_path); op->crtime.tv_sec = op->crtime.tv_nsec = 0; op->create_disposition = FILE_OPEN; op->create_options = FILE_NON_DIRECTORY_FILE; if (op->omode & SMB_DA_WRITE_THROUGH) op->create_options |= FILE_WRITE_THROUGH; if (sr->smb_flg & SMB_FLAGS_OPLOCK) { if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY) op->op_oplock_level = SMB_OPLOCK_BATCH; else op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE; } else { op->op_oplock_level = SMB_OPLOCK_NONE; } if (smb_common_open(sr) != NT_STATUS_SUCCESS) return (SDRC_ERROR); if (op->op_oplock_level == SMB_OPLOCK_NONE) { sr->smb_flg &= ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY); } if (smb_open_dsize_check && op->dsize > UINT_MAX) { smbsr_error(sr, 0, ERRDOS, ERRbadaccess); return (SDRC_ERROR); } file_attr = op->dattr & FILE_ATTRIBUTE_MASK; node = sr->fid_ofile->f_node; if (smb_node_getattr(sr, node, &attr) != 0) { smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, ERRDOS, ERROR_INTERNAL_ERROR); return (SDRC_ERROR); } rc = smbsr_encode_result(sr, 7, 0, "bwwllww", 7, sr->smb_fid, file_attr, smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec), (uint32_t)op->dsize, op->omode, (uint16_t)0); /* bcc */ return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); }
/* * smb_trans2_mbc_encode * * This function encodes the mbc for one directory entry. * * The function returns -1 when the max data requested by client * is reached. If the entry is valid and successful encoded, 0 * will be returned; otherwise, 1 will be returned. * * We always null terminate the filename. The space for the null * is included in the maxdata calculation and is therefore included * in the next_entry_offset. namelen is the unterminated length of * the filename. For levels except STANDARD and EA_SIZE, if the * filename is ascii the name length returned to the client should * include the null terminator. Otherwise the length returned to * the client should not include the terminator. * * Returns: 0 - data successfully encoded * 1 - client request's maxdata limit reached * -1 - error */ static int smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa, smb_fileinfo_t *fileinfo, smb_find_args_t *args) { int namelen, shortlen; uint32_t next_entry_offset; uint32_t dsize32, asize32; uint32_t mb_flags = 0; uint32_t resume_key; char buf83[26]; smb_msgbuf_t mb; namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name); if (namelen == -1) return (-1); /* * If ascii the filename length returned to the client should * include the null terminator for levels except STANDARD and * EASIZE. */ if (!(sr->smb_flg2 & SMB_FLAGS2_UNICODE)) { if ((args->fa_infolev != SMB_INFO_STANDARD) && (args->fa_infolev != SMB_INFO_QUERY_EA_SIZE)) namelen += 1; } next_entry_offset = args->fa_maxdata + namelen; if (MBC_ROOM_FOR(&xa->rep_data_mb, (args->fa_maxdata + namelen)) == 0) return (1); mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0; dsize32 = (fileinfo->fi_size > UINT_MAX) ? UINT_MAX : (uint32_t)fileinfo->fi_size; asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ? UINT_MAX : (uint32_t)fileinfo->fi_alloc_size; resume_key = fileinfo->fi_cookie; if (smbd_use_resume_keys == 0) resume_key = 0; /* * This switch handles all the "information levels" (formats) * that we support. Note that all formats have the file name * placed after some fixed-size data, and the code to write * the file name is factored out at the end of this switch. */ switch (args->fa_infolev) { case SMB_INFO_STANDARD: if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) (void) smb_mbc_encodef(&xa->rep_data_mb, "l", resume_key); (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwb", sr, smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), dsize32, asize32, fileinfo->fi_dosattr, namelen); break; case SMB_INFO_QUERY_EA_SIZE: if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) (void) smb_mbc_encodef(&xa->rep_data_mb, "l", resume_key); (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb", sr, smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), dsize32, asize32, fileinfo->fi_dosattr, 0L, /* EA Size */ namelen); break; case SMB_FIND_FILE_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqll", sr, next_entry_offset, resume_key, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen); break; case SMB_FIND_FILE_FULL_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll", sr, next_entry_offset, resume_key, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L); break; case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.q", sr, next_entry_offset, resume_key, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, fileinfo->fi_nodeid); break; case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: bzero(buf83, sizeof (buf83)); smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), mb_flags); if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) { smb_msgbuf_term(&mb); return (-1); } shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname); (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c", sr, next_entry_offset, resume_key, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, shortlen, buf83); smb_msgbuf_term(&mb); break; case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO: bzero(buf83, sizeof (buf83)); smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), mb_flags); if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) { smb_msgbuf_term(&mb); return (-1); } shortlen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_shortname); (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c2.q", sr, next_entry_offset, resume_key, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, shortlen, buf83, fileinfo->fi_nodeid); smb_msgbuf_term(&mb); break; case SMB_FIND_FILE_NAMES_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%lll", sr, next_entry_offset, resume_key, namelen); break; default: /* invalid info. level */ return (-1); } /* * At this point we have written all the fixed-size data * for the specified info. level, and we're about to put * the file name string in the message. We may later * need the offset in the trans2 data where this string * is placed, so save the message position now. Note: * We also need to account for the alignment padding * that may precede the unicode string. */ args->fa_lno = xa->rep_data_mb.chain_offset; if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0 && (args->fa_lno & 1) != 0) args->fa_lno++; (void) smb_mbc_encodef(&xa->rep_data_mb, "%u", sr, fileinfo->fi_name); return (0); }
smb_sdrc_t smb_com_open_andx(smb_request_t *sr) { struct open_param *op = &sr->arg.open; uint16_t file_attr; smb_attr_t attr; int rc; op->desired_access = smb_omode_to_amask(op->omode); op->share_access = smb_denymode_to_sharemode(op->omode, op->fqi.fq_path.pn_path); if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) { smbsr_error(sr, 0, ERRDOS, ERRbadaccess); return (SDRC_ERROR); } op->create_options = FILE_NON_DIRECTORY_FILE; if (op->omode & SMB_DA_WRITE_THROUGH) op->create_options |= FILE_WRITE_THROUGH; if (smb_common_open(sr) != NT_STATUS_SUCCESS) return (SDRC_ERROR); if (smb_open_dsize_check && op->dsize > UINT_MAX) { smbsr_error(sr, 0, ERRDOS, ERRbadaccess); return (SDRC_ERROR); } if (op->op_oplock_level != SMB_OPLOCK_NONE) op->action_taken |= SMB_OACT_LOCK; else op->action_taken &= ~SMB_OACT_LOCK; file_attr = op->dattr & FILE_ATTRIBUTE_MASK; if (STYPE_ISDSK(sr->tid_tree->t_res_type)) { smb_node_t *node = sr->fid_ofile->f_node; if (smb_node_getattr(sr, node, &attr) != 0) { smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, ERRDOS, ERROR_INTERNAL_ERROR); return (SDRC_ERROR); } rc = smbsr_encode_result(sr, 15, 0, "bb.wwwllwwwwl2.w", 15, sr->andx_com, VAR_BCC, sr->smb_fid, file_attr, smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec), (uint32_t)op->dsize, op->omode, op->ftype, op->devstate, op->action_taken, op->fileid, 0); } else { rc = smbsr_encode_result(sr, 15, 0, "bb.wwwllwwwwl2.w", 15, sr->andx_com, VAR_BCC, sr->smb_fid, file_attr, 0L, 0L, op->omode, op->ftype, op->devstate, op->action_taken, op->fileid, 0); } return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); }
/* * smb_query_encode_response * * Encode the data from smb_queryinfo_t into client response */ int smb_query_encode_response(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev, smb_queryinfo_t *qinfo) { uint16_t dattr; u_offset_t datasz, allocsz; uint32_t isdir; dattr = qinfo->qi_attr.sa_dosattr & FILE_ATTRIBUTE_MASK; datasz = qinfo->qi_attr.sa_vattr.va_size; allocsz = qinfo->qi_attr.sa_allocsz; isdir = ((dattr & FILE_ATTRIBUTE_DIRECTORY) != 0); switch (infolev) { case SMB_QUERY_INFORMATION: (void) smbsr_encode_result(sr, 10, 0, "bwll10.w", 10, dattr, smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec), smb_size32(datasz), 0); break; case SMB_QUERY_INFORMATION2: (void) smbsr_encode_result(sr, 11, 0, "byyyllww", 11, smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec), smb_size32(datasz), smb_size32(allocsz), dattr, 0); break; case SMB_FILE_ACCESS_INFORMATION: ASSERT(sr->fid_ofile); (void) smb_mbc_encodef(&xa->rep_data_mb, "l", sr->fid_ofile->f_granted_access); break; case SMB_INFO_STANDARD: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, ((sr->session->native_os == NATIVE_OS_WIN95) ? "YYYllw" : "yyyllw"), smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec), smb_size32(datasz), smb_size32(allocsz), dattr); break; case SMB_INFO_QUERY_EA_SIZE: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, ((sr->session->native_os == NATIVE_OS_WIN95) ? "YYYllwl" : "yyyllwl"), smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec), smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec), smb_size32(datasz), smb_size32(allocsz), dattr, 0); break; case SMB_INFO_QUERY_ALL_EAS: case SMB_INFO_QUERY_EAS_FROM_LIST: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "l", 0); break; case SMB_INFO_IS_NAME_VALID: break; case SMB_QUERY_FILE_BASIC_INFO: case SMB_FILE_BASIC_INFORMATION: /* * NT includes 6 bytes (spec says 4) at the end of this * response, which are required by NetBench 5.01. */ (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTw6.", &qinfo->qi_crtime, &qinfo->qi_atime, &qinfo->qi_mtime, &qinfo->qi_ctime, dattr); break; case SMB_QUERY_FILE_STANDARD_INFO: case SMB_FILE_STANDARD_INFORMATION: /* 2-byte pad at end */ (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "qqlbb2.", (uint64_t)allocsz, (uint64_t)datasz, qinfo->qi_attr.sa_vattr.va_nlink, qinfo->qi_delete_on_close, (uint8_t)isdir); break; case SMB_QUERY_FILE_EA_INFO: case SMB_FILE_EA_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "l", 0); break; case SMB_QUERY_FILE_NAME_INFO: case SMB_FILE_NAME_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "%lu", sr, qinfo->qi_namelen, qinfo->qi_name); break; case SMB_QUERY_FILE_ALL_INFO: case SMB_FILE_ALL_INFORMATION: /* * There is a 6-byte pad between Attributes and AllocationSize, * and a 2-byte pad after the Directory field. */ (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTw6.qqlbb2.l", &qinfo->qi_crtime, &qinfo->qi_atime, &qinfo->qi_mtime, &qinfo->qi_ctime, dattr, (uint64_t)allocsz, (uint64_t)datasz, qinfo->qi_attr.sa_vattr.va_nlink, qinfo->qi_delete_on_close, isdir, 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "%lu", sr, qinfo->qi_namelen, qinfo->qi_name); break; case SMB_QUERY_FILE_ALT_NAME_INFO: case SMB_FILE_ALT_NAME_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "%lU", sr, smb_wcequiv_strlen(qinfo->qi_shortname), qinfo->qi_shortname); break; case SMB_QUERY_FILE_STREAM_INFO: case SMB_FILE_STREAM_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); smb_encode_stream_info(sr, xa, qinfo); break; case SMB_QUERY_FILE_COMPRESSION_INFO: case SMB_FILE_COMPRESSION_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "qwbbb3.", datasz, 0, 0, 0, 0); break; case SMB_FILE_INTERNAL_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "q", qinfo->qi_attr.sa_vattr.va_nodeid); break; case SMB_FILE_NETWORK_OPEN_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTqql4.", &qinfo->qi_crtime, &qinfo->qi_atime, &qinfo->qi_mtime, &qinfo->qi_ctime, (uint64_t)allocsz, (uint64_t)datasz, (uint32_t)dattr); break; case SMB_FILE_ATTR_TAG_INFORMATION: /* * If dattr includes FILE_ATTRIBUTE_REPARSE_POINT, the * second dword should be the reparse tag. Otherwise * the tag value should be set to zero. * We don't support reparse points, so we set the tag * to zero. */ (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "ll", (uint32_t)dattr, 0); break; default: if ((infolev > 1000) && smb_query_passthru) smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, ERRDOS, ERROR_NOT_SUPPORTED); else smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_LEVEL); return (-1); } return (0); }
/* * smb_trans2_mbc_encode * * This function encodes the mbc for one directory entry. * * The function returns -1 when the max data requested by client * is reached. If the entry is valid and successful encoded, 0 * will be returned; otherwise, 1 will be returned. * * We always null terminate the filename. The space for the null * is included in the maxdata calculation and is therefore included * in the next_entry_offset. namelen is the unterminated length of * the filename. For levels except STANDARD and EA_SIZE, if the * filename is ascii the name length returned to the client should * include the null terminator. Otherwise the length returned to * the client should not include the terminator. * * Returns: 0 - data successfully encoded * 1 - client request's maxdata limit reached * -1 - error */ static int smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa, smb_fileinfo_t *fileinfo, smb_find_args_t *args) { int namelen, shortlen, buflen; uint32_t next_entry_offset; uint32_t dsize32, asize32; uint32_t mb_flags = 0; char buf83[26]; char *tmpbuf; smb_msgbuf_t mb; namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name); if (namelen == -1) return (-1); next_entry_offset = args->fa_maxdata + namelen; if (MBC_ROOM_FOR(&xa->rep_data_mb, (args->fa_maxdata + namelen)) == 0) return (1); /* * If ascii the filename length returned to the client should * include the null terminator for levels except STANDARD and * EASIZE. */ if (!(sr->smb_flg2 & SMB_FLAGS2_UNICODE)) { if ((args->fa_infolev != SMB_INFO_STANDARD) && (args->fa_infolev != SMB_INFO_QUERY_EA_SIZE)) namelen += 1; } mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0; dsize32 = (fileinfo->fi_size > UINT_MAX) ? UINT_MAX : (uint32_t)fileinfo->fi_size; asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ? UINT_MAX : (uint32_t)fileinfo->fi_alloc_size; switch (args->fa_infolev) { case SMB_INFO_STANDARD: if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) (void) smb_mbc_encodef(&xa->rep_data_mb, "l", fileinfo->fi_cookie); (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwbu", sr, smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), dsize32, asize32, fileinfo->fi_dosattr, namelen, fileinfo->fi_name); break; case SMB_INFO_QUERY_EA_SIZE: if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) (void) smb_mbc_encodef(&xa->rep_data_mb, "l", fileinfo->fi_cookie); /* * Unicode filename should NOT be aligned. Encode ('u') * into a temporary buffer, then encode buffer as a * byte stream ('#c'). * Regardless of whether unicode or ascii, a single * termination byte is used. */ buflen = namelen + sizeof (smb_wchar_t); tmpbuf = kmem_zalloc(buflen, KM_SLEEP); smb_msgbuf_init(&mb, (uint8_t *)tmpbuf, buflen, mb_flags); if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_name) < 0) { smb_msgbuf_term(&mb); kmem_free(tmpbuf, buflen); return (-1); } tmpbuf[namelen] = '\0'; (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb#c", sr, smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), dsize32, asize32, fileinfo->fi_dosattr, 0L, /* EA Size */ namelen, namelen + 1, tmpbuf); smb_msgbuf_term(&mb); kmem_free(tmpbuf, buflen); break; case SMB_FIND_FILE_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqllu", sr, next_entry_offset, fileinfo->fi_cookie, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, fileinfo->fi_name); break; case SMB_FIND_FILE_FULL_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllu", sr, next_entry_offset, fileinfo->fi_cookie, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, fileinfo->fi_name); break; case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.qu", sr, next_entry_offset, fileinfo->fi_cookie, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, fileinfo->fi_nodeid, fileinfo->fi_name); break; case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: bzero(buf83, sizeof (buf83)); smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), mb_flags); if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) { smb_msgbuf_term(&mb); return (-1); } shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname); (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24cu", sr, next_entry_offset, fileinfo->fi_cookie, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, shortlen, buf83, fileinfo->fi_name); smb_msgbuf_term(&mb); break; case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO: bzero(buf83, sizeof (buf83)); smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), mb_flags); if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) { smb_msgbuf_term(&mb); return (-1); } shortlen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_shortname); (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c2.qu", sr, next_entry_offset, fileinfo->fi_cookie, &fileinfo->fi_crtime, &fileinfo->fi_atime, &fileinfo->fi_mtime, &fileinfo->fi_ctime, fileinfo->fi_size, fileinfo->fi_alloc_size, fileinfo->fi_dosattr, namelen, 0L, shortlen, buf83, fileinfo->fi_nodeid, fileinfo->fi_name); smb_msgbuf_term(&mb); break; case SMB_FIND_FILE_NAMES_INFO: (void) smb_mbc_encodef(&xa->rep_data_mb, "%lllu", sr, next_entry_offset, fileinfo->fi_cookie, namelen, fileinfo->fi_name); break; } return (0); }