static int BrowseDirectory( stream_t *p_access, input_item_node_t *p_node ) { access_sys_t *p_sys = p_access->p_sys; smb_stat_list files; smb_stat st; char *psz_query; const char *psz_name; size_t files_count; int i_ret = VLC_SUCCESS; if( p_sys->psz_path != NULL ) { if( asprintf( &psz_query, "%s\\*", p_sys->psz_path ) == -1 ) return VLC_ENOMEM; files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query ); free( psz_query ); } else files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" ); if( files == NULL ) return VLC_EGENERIC; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_access, p_node ); files_count = smb_stat_list_count( files ); for( size_t i = 0; i < files_count && i_ret == VLC_SUCCESS; i++ ) { int i_type; st = smb_stat_list_at( files, i ); if( st == NULL ) { continue; } psz_name = smb_stat_name( st ); i_type = smb_stat_get( st, SMB_STAT_ISDIR ) ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE; i_ret = add_item( p_access, &rdh, psz_name, i_type ); } vlc_readdir_helper_finish( &rdh, i_ret == VLC_SUCCESS ); smb_stat_list_destroy( files ); return i_ret; }
/***************************************************************************** * Close: free unused data structures *****************************************************************************/ static void Close( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys = p_access->p_sys; if( p_sys->p_ns ) netbios_ns_destroy( p_sys->p_ns ); if( p_sys->i_fd ) smb_fclose( p_sys->p_session, p_sys->i_fd ); if( p_sys->p_session ) smb_session_destroy( p_sys->p_session ); vlc_UrlClean( &p_sys->url ); if( p_sys->shares ) smb_share_list_destroy( p_sys->shares ); if( p_sys->files ) smb_stat_list_destroy( p_sys->files ); free( p_sys->psz_fullpath ); free( p_sys ); }
void smb_stat_destroy(smb_stat stat) { smb_stat_list_destroy((smb_stat_list) stat); }
smb_file *smb_find(smb_session *s, smb_tid tid, const char *pattern) { smb_file *files = NULL; smb_message *msg; smb_trans2_resp *tr2_resp; smb_tr2_findfirst2_params *findfirst2_params; smb_tr2_findnext2_params *findnext2_params; bool end_of_search; uint16_t sid; uint16_t resume_key; uint16_t error_offset; assert(s != NULL && pattern != NULL); // Send FIND_FIRST request msg = smb_trans2_find_first(s,tid,pattern); if (msg) { smb_find_first_parse(msg,&files); if (files) { // Check if we shall send a FIND_NEXT request tr2_resp = (smb_trans2_resp *)msg->packet->payload; findfirst2_params = (smb_tr2_findfirst2_params *)tr2_resp->payload; sid = findfirst2_params->id; end_of_search = findfirst2_params->eos; resume_key = findfirst2_params->last_name_offset; error_offset = findfirst2_params->ea_error_offset; smb_message_destroy(msg); // Send FIND_NEXT queries until the find is finished // or until an error occurs while ((!end_of_search) && (error_offset == 0)) { msg = smb_trans2_find_next(s, tid, resume_key, sid, pattern); if (msg) { // Update info for next FIND_NEXT query tr2_resp = (smb_trans2_resp *)msg->packet->payload; findnext2_params = (smb_tr2_findnext2_params *)tr2_resp->payload; end_of_search = findnext2_params->eos; resume_key = findnext2_params->last_name_offset; error_offset = findnext2_params->ea_error_offset; // parse the result for files smb_find_next_parse(msg, &files); smb_message_destroy(msg); if (!files) { BDSM_dbg("Error during FIND_NEXT answer parsing\n"); end_of_search = true; } } else { BDSM_dbg("Error during FIND_NEXT request\n"); smb_stat_list_destroy(files); return NULL; } } } else { BDSM_dbg("Error during FIND_FIRST answer parsing\n"); smb_message_destroy(msg); } } else { BDSM_dbg("Error during FIND_FIRST request\n"); smb_stat_list_destroy(files); smb_message_destroy(msg); return NULL; } return files; }