📄 xfile.c
字号:
* use_last_dir_ctx - use dir context from previous search operation * \return index of song item, or 0 when nothing was found * \remark *//******************************************************************************/GRESULT XAR_NextSong2(uint16 vol, uint16 cur, uint16 use_last_dir_ctx){ GRESULT tmp, vol_node; uint16 curr_dir; uint16 dirstop; if (!vol) { if (!cur) { vol_node = 0; while (1) { if ((vol_node >= X_NEXTFREE_ITEM) || (XAR_NodeType(vol_node) != XTYPE_VOLUME)) return 0; if (FS_TOC != X_array[vol_node].data.xvolume.fs_type) { if (X_array[vol_node].nodetype.i & FLAG_VOLUME_VALID) break; else return 0; } vol_node = vol_node + X_array[vol_node].data.xvolume.nodes_num + 1; } } else { if ((XAR_NodeType(cur) != XTYPE_DATA_FILE) || (cur >= X_NEXTFREE_ITEM)) return 0; vol_node = XAR_VolumeNodeForItem(cur); } } else { vol_node = XAR_VolumeNode(vol); if (!VALID_VOLUME_NODE(vol_node)) return 0; if (!X_array[vol_node].nodetype.i & FLAG_VOLUME_VALID) return 0; if (cur) { if (vol_node != XAR_VolumeNodeForItem(cur)) return 0; } } // vol_node was found if(use_last_dir_ctx) dirstop = X_dir_stop; else dirstop = 0; if (cur) { tmp = XAR_NextFile(cur,dirstop); if (tmp != S_NOT_FOUND) return tmp; if((!use_last_dir_ctx)||(!X_last_dir)) { curr_dir = XAR_DirFromFile(cur); X_last_dir = curr_dir; } else curr_dir = X_last_dir; } else { curr_dir = vol_node + 1; X_last_dir = curr_dir; X_dir_stop = XAR_DirStopFromDir(curr_dir); tmp = XAR_FindFile(curr_dir, 1); if (tmp > 0) return tmp; } do { tmp = XAR_ForwDir(curr_dir, 0); if (tmp == S_NOT_FOUND) return tmp; curr_dir = tmp; X_last_dir = tmp; X_dir_stop = XAR_DirStopFromDir(curr_dir); // XAR_SetDirRange(tmp); tmp = XAR_FindFile(curr_dir, 1); } while (tmp == S_NOT_FOUND); return tmp;}#endif // #if XARREMGRESULT XAR_UpdateFilePosition(t_SongInfos *song_info, uint32 count){ uint16 offs; song_info->position += count; if (song_info->position >= song_info->size) { song_info->flags |= XFILE_FLAG_EOF; song_info->extent_position = song_info->extent_size; return count; } song_info->extent_position += count; if (song_info->extent_position == song_info->extent_size) { offs = X_array[song_info->extent_index].data.xfile.next_extent & 0x7FFF; // O.T. mask off UDF simple file flag if (offs) { if (XAR_NodeType(offs) == XTYPE_FILE_EXTEND) { song_info->extent_index = offs; song_info->extent_position = 0; song_info->extent_size = X_array[offs].data.xfile.size;#if HAVE_EXTERNAL_XARRAY song_info->extent_lba = X_array[offs].data.xfile.lba;#else song_info->extent_lba = X_array[offs].data.xfile.lba_lsp + (X_array[offs].data.xfile.lba_msp << 16);#endif } else { song_info->flags |= XFILE_FLAG_READ_ERROR; return count; } } else { song_info->flags |= XFILE_FLAG_EOF; } return count; } return count;}/******************************************************************************//* Function: XAR_PrepareReadFile *//* *//* \brief Limits requested amount of bytes to available count in extent *//* and prepares command struct */ /* \param song_info - pointer to valid file info struct *//* pt - pointer to destination memory *//* count - number of bytes to read *//* cmd_event - command for reading task *//* \return Number of bytes that can be read from current extent *//* \remark *//* *//******************************************************************************/GRESULT XAR_PrepareReadFile(t_SongInfos *song_info, uint8 *pt, uint32 count, t_child_cmd_event *cmd_event){ uint32 xlba; uint32 offs, stop; uint32 dev_block_size; //clear all previous flags song_info->flags &= ~XFILE_FLAG_EOF; song_info->flags &= ~XFILE_FLAG_EOF_NEXT; song_info->flags &= ~XFILE_FLAG_FSEOF; cmd_event->command_params.xfer_params.type = song_info->type; if (song_info->type == TRACK_CDDA) { xlba = /*song_info->partitionLBA +*/ song_info->extent_lba + (song_info->extent_position / 2352); if (cmd_event->command_params.xfer_params.end_mode) stop = 0; // for CDDA without SEARCH mode ask till end_of_XXX (stop_lba = 0) else stop = xlba + (((song_info->extent_position % 2352) + count - 1) / 2352); // SEARCH - end_of_target_time PREPARE_IOREAD((*cmd_event), song_info->devid, xlba , stop, 0, 2352,pt,count,song_info->iopar); return count; } if (song_info->extent_size == song_info->extent_position) { song_info->flags |= XFILE_FLAG_EOF; // wrongly set position, either EOF of new extent had to be found return 0; } if ((song_info->extent_size - song_info->extent_position) < count) { count = song_info->extent_size - song_info->extent_position; } // data can be read from current extent if (song_info->fs_type != FS_FAT_TYPE) { // add 2 sec for CA tracks (TOC_OFFSET_SECTOR) xlba = /*song_info->partitionLBA +*/ song_info->extent_lba + (song_info->extent_position >> 11) + 150 ; stop = (((0x7ff & song_info->extent_position) + count - 1) >> 11); offs = 0x7ff & song_info->extent_position; if ((song_info->fs_type == FS_UDF_TYPE) && (0x8000 & X_array[song_info->xid].data.xfile.next_extent)) offs += UDF_SMALL_FILE_OFFSET; PREPARE_IOREAD((*cmd_event), song_info->devid, xlba, xlba + stop, offs, 2048, pt, count, song_info->iopar); } else // FAT uses different size of sectors (512B) { dev_block_size = SYS_DeviceInfoStruct(SYS_GetDeviceID(song_info->devid))->LargeBlockSize; xlba = song_info->extent_lba + ((song_info->extent_position) / dev_block_size) ; stop = count / dev_block_size; offs = ((song_info->extent_position) % dev_block_size); PREPARE_IOREAD((*cmd_event), song_info->devid, xlba, xlba + 1 + stop, offs, dev_block_size, pt, count, song_info->iopar); } return count;}/******************************************************************************//* Function: XAR_ReadFile *//* *//* \brief Reading from file */ /* \param song_info - pointer to valid file info struct *//* pt - pointer to destination memory *//* count - number of bytes to read *//* iopar - flags for IO_Read *//* \return Number of read bytes *//* \remark Can be called only from FS task !!! *//* *//******************************************************************************/GRESULT XAR_ReadFile(t_SongInfos *song_info, uint8 *pt, uint16 count, uint32 iopar){ GRESULT ret; int cnt,read = 0; int cnt2=0; // loop limit song_info->iopar = iopar;#if (1 == HAVE_WMDRM) if (song_info->fs_type == FS_WMDRM_TYPE) { DRM_RESULT dr; ProximityContext.MaxDataBlockSize = count; ProximityContext.NextDataBuffer = (DRM_BYTE *) pt; if ( IS_USBDeviceSessionObject_WMDRM_NDR ) { /* This file is DRM protected file in WMDRM_ND transmitter. */ dr = WmdrmNet_DATA_transition( WMDRM_GET_NEXT_DATA_BLOCK, NULL, 1 ); if ( dr == DRM_SUCCESS ) { song_info->position += ProximityContext.MaxDataBlockSize; /* MaxDataBlockSize is updated by actual transferred size. */ return ProximityContext.MaxDataBlockSize; /* Return size */ } } else { /* This file is non DRM protected file in WMDRM_ND transimitter. */ ProximityContext.NextDataOffset = song_info->position; dr = WmdrmNet_DATA_transition( WMDRM_GET_PARTIAL_OBJECT_DATA, NULL, 1 ); if ( dr == DRM_SUCCESS ) { cnt = XAR_UpdateFilePosition(song_info, ProximityContext.MaxDataBlockSize); /* MaxDataBlockSize is updated by actual transferred size. */ return cnt; } } /* dr != DRM_SUCCESS */ return 0; }#endif while(count && (song_info->size>song_info->position) && (cnt2<100)) { ret = XAR_PrepareReadFile(song_info, pt, count, &FS_XFER_command_event); if (ret == 0) return read; // some error occured if (0 > IO_Read(iopar)) { //song_info->flags |= XFILE_FLAG_READ_ERROR; return 0; } else { cnt = XAR_UpdateFilePosition(song_info, FS_XFER_command_event.command_params.xfer_params.count); } count -= cnt; read += cnt; cnt2++;} return read;}GRESULT XAR_InitFile(uint16 xindex, t_SongInfos *song_info, uint8 end_mode){ uint16 i; int16 vol; if (XAR_XNodeType(xindex) == TRACK_CDDA) { song_info->xid = xindex; song_info->song_number = xindex; //FindSongNrForIndex(xindex, PATH_TABLE, FALSE); song_info->type = TRACK_CDDA; // AUDIO song_info->devid = DEV_CD_ID; song_info->flags = 0; song_info->fs_type = FS_TOC; // treat CDDA as one track from begining of the disc song_info->extent_lba = 0; //XAR_GetFileLBA(XAR_GetMinTrack(xindex)); song_info->size = 0xFFFFFFFF; song_info->position = 0; song_info->extent_position = 0; song_info->extent_size = song_info->size; song_info->extent_index = xindex; return S_OK; } ASSERT((XAR_NodeType(xindex) == XTYPE_DATA_FILE), "XAR_InitFile invalid index"); /*if(XAR_NodeType(xindex)!= XTYPE_DATA_FILE) return E_FAIL; */ vol = XAR_VolumeNodeForItem(xindex); if (!VALID_VOLUME_NODE(vol)) { ASSERT(0, "XAR_InitFile volume not found"); return E_FAIL; // invalid xindex } // vol=XAR_FSVolume(v); song_info->xid = xindex; //just for data tracks#if (0 != HAVE_UPDATE)if (!(CDinfo & HAVE_FLASH_IMAGE)) song_info->song_number = FindSongNrForIndex(xindex, player_dir_numbering, FALSE) ; // xindex + AUDIO_TRACKS_SET;#endif song_info->extent_index = xindex; i = xindex; song_info->size = 0; do { song_info->size += X_array[i].data.xfile.size; i = X_array[i].data.xfile.next_extent & 0x7FFF; // O.T. mask off UDF simple file flag // if(X_array[i].type != XTYPE_FILE_EXTEND) // break; } while (i); song_info->end_offset = song_info->size; song_info->start_offset = 0; song_info->curr_start_offset = 0; song_info->extent_position = 0; song_info->position = 0;#if HAVE_EXTERNAL_XARRAY song_info->extent_lba = X_array[xindex].data.xfile.lba;#else song_info->extent_lba = X_array[xindex].data.xfile.lba_lsp + ((X_array[xindex].data.xfile.lba_msp) << 16);#endif song_info->extent_size = X_array[xindex].data.xfile.size; song_info->volume_node = vol; // song_info->partitionLBA = X_array[vol].data.xvolume.partitionLBA; song_info->devid = XAR_VolNodeDevType(vol); //X_array[vol].data.xvolume.devtype; song_info->fs_type = (t_FStype) X_array[vol].data.xvolume.fs_type; song_info->type = XAR_XNodeType(xindex); song_info->flags = 0; song_info->strtop = 0; song_info->n_infos = 0; return S_OK;}GRESULT XAR_DirRecordIsFile(int16 index) //M.Ch.{ if (XAR_NodeType(index) == XTYPE_DATA_FILE) return S_TRUE; else return S_FALSE;}uint32 XAR_FileSize(int16 index) //M.Ch.{ return X_array[index].data.xfile.size;}uint32 XAR_FileTotalSize(int16 index) //M.Ch.{ int16 i = index; uint32 FileTotalSize = 0; if(XAR_NodeType(i) == XTYPE_TRACK) return X_array[i].data.xfile.size; do { FileTotalSize += X_array[i].data.xfile.size; i = X_array[i].data.xfile.next_extent & 0x7FFF; // O.T. mask off UDF simple file flag } while (i); return FileTotalSize;}GRESULT XAR_IsExtent(int16 index) //M.Ch.{ if ((XAR_NodeType(index) == XTYPE_FILE_EXTEND)) return S_TRUE; else return S_FALSE;}GRESULT XAR_UpdateItem(int16 index, DIR_ITEM *item, uint8 flags){ if (flags & UPDATE_LBA) {#if HAVE_EXTERNAL_XARRAY writeSDRAM32((int16 *)&X_array[index].data.xfile.lba, item->file.ExtentLba);#else X_array[index].data.xfile.lba_lsp = 0xffff & item->file.ExtentLba; X_array[index].data.xfile.lba_msp = (0xff0000 & item->file.ExtentLba) >> 16;#endif } if (flags & UPDATE_EXTEND) X_array[index].data.xfile.next_extent = item->file.Position; if (flags & UPDATE_SIZE) #if HAVE_EXTERNAL_XARRAY writeSDRAM32((int16 *)&X_array[index].data.xfile.size, item->file.FileSize);#else X_array[index].data.xfile.size = item->file.FileSize;#endif if (flags & UPDATE_UDF_FLAGS) if(item->file.Attributes & XTYPE_DATA_FILE_UDF_SHORT_FILE) X_array[index].data.xfile.next_extent = 0x8000; // no next extent, single sector with starting offset return S_OK;}GRESULT XAR_TestFileExtension(FILE_STRUCT *file, uint8 *filt){ uint8 *ext2,cbuf[6]; uint8 *ext, exlen = 0; char *spex; file->FileType = XFLAG_FILE_OTHER; ext = file->Name + file->NameLength - 1; while (*ext == 0) ext--; ; // ignore terminating nulls memcpy(cbuf,ext-5,6); ext = cbuf+5; while ((*ext != '.') && (ext > cbuf )) //file->Name)) { if ((*ext < 0x5B) && (*ext > 0x40)) *ext |= 0x20; // convert to lower case exlen++; ext--; } if ((!exlen) || (ext < cbuf /*file->Name*/ ) || (*ext != '.')) {// no extension found // if ((filt == NULL) || (*filt == 0))// return S_TRUE; return S_FALSE; // files without extension are not allowed } ext2 = filt; ext++; file->FileType = XAR_FileType((char *) ext); // test for known file types if(file->FileType == DATA_FILE) { // only allowed DATA_FILE is with special names if(*SpecialFileNameList != 0) { if(module_config.data.host_update_method & 0x01) { // use extension based filter spex = SpecialFileNameList; while((*spex != '\0') && (spex < SpecialFileNameList+UPDATE_IMAGE_LENGTH)) { if(!strncmp(spex,(char *)ext,exlen)) { if( (*(spex+exlen) == '.') || (*(spex+exlen) == '\0') || (spex+exlen >= SpecialFileNameList+UPDATE_IMAGE_LENGTH) ) return S_SPECIAL_FILE_FOUND; } do { spex++; }while( (*spex != '\0') && (spex < (SpecialFileNameList+UPDATE_IMAGE_LENGTH - 1)) && (*spex != '.') ); if(*spex == '.') spex++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -