📄 readdir.c
字号:
/******************************************************************************
*******************************************************************************
** **
** Copyright (c) 2002 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
*******************************************************************************
******************************************************************************/
/**
* @file readdir.c
*
* DVD Directory Parsing Commands.
*
* $Id: readdir.c,v 1.33 2007/01/26 21:13:37 rbehe Exp $
*/
#include <stdio.h>
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "loader_app.h"
#include "pe_app.h"
#include "nav_task.h"
#include "readdir.h"
#include "disctask.h"
#include "init.h"
#include "usrapi.h"
#include "dbgprint.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* MACROS AND DEFINES */
#define DEBUG_READDIR DBG_ERROR /* set the debug level for prints, 0 for no prints */
#define DBG_ON(x) (DEBUG_READDIR >= x) /* local macro for deciding if should print */
#define NON_CACHED_SBUF ((UBYTE *)KSEG1(sbuf))
extern LOADER_HANDLE tLoader;
extern UBYTE *sbuf;
extern ULONG lbuf[LBUFSIZE];
/* These structures contain the extended file attribute information. The CGMS
* requirement was in the .vob files but is now parsed out of the VTSI files.
* The LOADER_ERROR_RECOVERY needs the LBN's of the .bup files. This system
* takes longer than the other way because much more information must be loaded
* and parsed. */
VMG_FILE_STRUCT video_ts;
TITLE_SET_FILE_STRUCT vts_file[99];
#ifdef AUDIO_TS
/* The AUDIO_TS define is used to enable parsing of the DVD Audio file system.
* It is currently not expected to be used. The difference between the
* AUDIO_TS CGMS and LOADER_ERROR_RECOVERY options and the VIDEO_TS
* ones is the same. */
AMG_FILE_STRUCT audio_ts;
TITLE_SET_FILE_STRUCT ats_file[99];
#endif
UBYTE read_in_progress = 1; /* power on to KEY_TRAY eject sensitivity */
/* local function prototypes */
ULONG get_le(ULONG);
ULONG get_be(ULONG);
void get_file_entry(ULONG *, ULONG *, ULONG, ULONG);
UBYTE get_ts_num(char *);
ULONG readdir_FindVidAud_TS(LOADER_HANDLE tLoader, VMG_FILE_STRUCT *video_ts, AMG_FILE_STRUCT *audio_ts);
ULONG readdir_FindVid_TS(LOADER_HANDLE tLoader, VMG_FILE_STRUCT *video_ts);
/**
* Purpose: DVD directory parsing routine.
*
* Theory: This routine parses the DVD UDF volume/file structure and
* retrieves the LBA, size in bytes, and cgms info for each
* file in the video_ts and audio_ts directories.
*
* Note: The audio_ts parsing has been #defined out since we
* do not currently process those files.
*
* Arguments: none
*
* Returns: 0 = successful
* 1 = fatal system error, can not proceed
* 2 = error on disc read, can not proceed
* 3 = error on disc read, video_ts.* files processed
* 4 = error in parsing, can not proceed
* 5 = error in parsing, video_ts.* files processed
* 6 = error on disc read, video_ts.* processed, audio_ts can not proceed
* 7 = error on disc read, video_ts.* processed, audio_ts.* files processed
* 8 = error in parsing, video_ts.* processed, audio_ts can not proceed
* 9 = error in parsing, video_ts.* processed, audio_ts.* files processed
* 0xFF = KEY_TRAY has been recieved and needs to be handled
*/
UBYTE read_directory() /* this is the new one currently in use */
{
char *d_order = NULL; /* pointer to the file name array */
USHORT *d_loc_order = NULL; /* pointer to the file location order array */
USHORT i, num_count, l_iu, num_files, file_start = 0, sbuf_count;
ULONG temp, l_ea, cur_sec, udf_start, offset, cgms_offset, order_idx;
UBYTE ts_tso, ts_num, j, icb_sec, cur_icb_sec;
char ts[12];
ULONG loc_order_idx;
ULONG icb_length;
video_ts.bup_address = 0;
video_ts.ifo_address = 0;
video_ts.vob_address = 0;
read_in_progress = 1;
order_idx = 0;
loc_order_idx = 0;
offset = 0;
video_ts.present = 0;
video_ts.vts_num_max = 0;
#ifdef AUDIO_TS
audio_ts.present = 0;
audio_ts.ats_num_max = 0;
#endif
/* there can only be 99 VTS (or ATS) */
for (i=0; i<99; i++)
{
vts_file[i].tso_num = 0;
#ifdef AUDIO_TS
ats_file[i].tso_num = 0;
#endif
}
#ifdef AUDIO_TS
udf_start = readdir_FindVidAud_TS(tLoader, &video_ts, &audio_ts);
#else
udf_start = readdir_FindVid_TS(tLoader, &video_ts);
#endif
/* ToDo: determine original intention and return appropriate error
(this code can not execute since udf_start is unsigned)
*/
#if 0
if (udf_start < 0)
{
return(-1 * (UBYTE)udf_start);
}
#endif
/* Allocate the buffers for parsing file info.
* need 1191 files */
d_order = (char *)OS_MemAlloc(12 * 1191);
if (d_order == NULL)
{
read_in_progress = 0;
return (1);
}
d_loc_order = (USHORT *)OS_MemAlloc(2 * 1191);
if (d_loc_order == NULL)
{
read_in_progress = 0;
OS_MemFree(d_order);
d_order = NULL;
return (1);
}
/* intialize to 0 */
memset(d_order, 0, 12 * 1191);
memset(d_loc_order, 0, 2 * 1191);
if (video_ts.present)
{
video_ts.vts_num_max = 0;
/* ok, go to the video_ts ICB */
cur_sec = udf_start + video_ts.ifo_address;
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - video_ts ICB cur_sec: %u\n", cur_sec));
if (LoaderSectorRead(tLoader, cur_sec, sbuf, 1) != LOADER_SUCCESS)
{
OS_MemFree(d_loc_order);
d_loc_order = NULL;
OS_MemFree(d_order);
d_order = NULL;
read_in_progress = 0;
return (2);
}
l_ea = get_le(168);
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - l_ea: %u\n", l_ea));
/* icb_length is the length of the current ICB. From this we will know which
* file entries are assciated with this ICB. This protects against discs with
* multiple volume systems. */
icb_length = get_le(56);
if (icb_length > 122880)
{
icb_length = 122880; /*60 sectors*/
}
icb_sec = (UBYTE)(icb_length / 2048);
if (icb_length % 2048)
{
icb_sec++;
}
if (icb_sec > 30)
{
cur_icb_sec = 30;
i = 2;
}
else
{
i = 1;
cur_icb_sec = icb_sec;
}
/* get offset to identifier descriptors for this directory */
offset = 176 + l_ea;
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - offset: %u\n", offset));
cur_sec = ((NON_CACHED_SBUF[offset + 5] << 8) | (NON_CACHED_SBUF[offset + 4])) + udf_start;
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - video_ts ICB offset to id descriptors cur_sec: %u\n", cur_sec));
//cur_sec = 276;
video_ts.present = 0;
file_start = 0xFFFF;
for (j = 0; j < i; j++)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - get file identifiers\n"));
/* getting the file identifiers for the video_ts files */
if (LoaderSectorRead(tLoader, cur_sec, sbuf, cur_icb_sec) != LOADER_SUCCESS)
{
OS_MemFree(d_loc_order);
d_loc_order = NULL;
OS_MemFree(d_order);
d_order = NULL;
read_in_progress = 0;
return (2);
}
/* to bypass the parent descriptor */
if (j == 0)
{
offset = 1;
}
else
{
offset = 0;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - check file descriptors\n"));
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - cur_sec: %u\n", cur_sec));
/* Check the file descriptors */
while (offset < (ULONG)(cur_icb_sec * 2048)) /* (2048 * length) */
{
/* To parse out the files correctly, we need to know which filename
* is associated with each file entry. To do this we need to go
* through the directory listing and store each filename with it's
* file entry offset. There is no specification on the order the
* filenames can be written on the disc so we have to assume they
* will be in any order. The d_order array is the array containing
* the filename of that file in the order found on the disc (element
* 0 is the first file in the ICB). The d_loc_order array is the
* file entry offset for that associated file. */
while ( ((NON_CACHED_SBUF[offset + 1]<<8) | (NON_CACHED_SBUF[offset])) != 0x101)
{
offset++;
if ((offset > (ULONG)(cur_icb_sec * 2048))||(offset > icb_length))
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - ended. offset: %u\n", offset));
break;
}
}
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - 0x101 found at offset: %u\n", offset));
l_iu = (NON_CACHED_SBUF[offset + 36]) | (NON_CACHED_SBUF[offset + 37] << 8);
for (i = 0; i < 12; i++)
{
d_order[i + order_idx] = NON_CACHED_SBUF[offset + 39 + i + l_iu];
}
if ((strncmp(&d_order[order_idx], "VIDEO_TS.BUP", 12) == 0) || (strncmp(&d_order[order_idx], "video_ts.bup", 12) == 0))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - BUP\n"));
video_ts.present = 1;
}
if ((strncmp(&d_order[order_idx], "VIDEO_TS.IFO", 12) == 0) || (strncmp(&d_order[order_idx], "video_ts.ifo", 12) == 0))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - IFO\n"));
video_ts.present = 1;
}
if ((strncmp(&d_order[order_idx + 8], ".BUP", 4) == 0) || (strncmp(&d_order[order_idx + 8], ".bup", 4) == 0))
{
d_loc_order[loc_order_idx] = (NON_CACHED_SBUF[offset + 25] << 8) | (NON_CACHED_SBUF[offset + 24]);
if (d_loc_order[loc_order_idx] < file_start)
file_start = d_loc_order[loc_order_idx];
order_idx += 12;
loc_order_idx++;
}
else if (strncmp(&d_order[order_idx + 8], ".IFO", 4) == 0 || strncmp(&d_order[order_idx + 8], ".ifo", 4) == 0)
{
d_loc_order[loc_order_idx] = (NON_CACHED_SBUF[offset + 25] << 8) | (NON_CACHED_SBUF[offset + 24]);
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - file_start: %u\n", d_loc_order[loc_order_idx]));
if (d_loc_order[loc_order_idx] < file_start)
file_start = d_loc_order[loc_order_idx];
order_idx += 12;
loc_order_idx++;
}
else
{
if (strncmp(&d_order[order_idx + 8], ".VOB", 4) == 0 || strncmp(&d_order[order_idx + 8], ".vob", 4) == 0)
{
d_loc_order[loc_order_idx] = (NON_CACHED_SBUF[offset + 25] << 8) | (NON_CACHED_SBUF[offset + 24]);
if (d_loc_order[loc_order_idx] < file_start)
file_start = d_loc_order[loc_order_idx];
order_idx += 12;
loc_order_idx++;
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - VOB\n"));
}
}
offset += 51;
if (offset >= icb_length)
{
j = (UBYTE)(i);
offset = (cur_icb_sec * 2048);
}
}
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - after check file descriptors\n"));
cur_icb_sec = icb_sec - 30;
cur_sec += 30;
}
}
if (video_ts.present)
{
/* Now we load and parse the file entries. This is where the actual start
* LBN, length, and CGMS information is stored. */
num_files = (USHORT)(loc_order_idx + 1);
num_count = num_files;
while (num_files > 0)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("read_directory() - load and parse file entries\n"));
DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - loc: %u\n", udf_start+file_start));
if (LoaderSectorRead(tLoader, udf_start + file_start, sbuf, 30) != LOADER_SUCCESS)
{
OS_MemFree(d_loc_order);
d_loc_order = NULL;
OS_MemFree(d_order);
d_order = NULL;
read_in_progress = 0;
return (2);
}
order_idx = 0;
offset = 0;
loc_order_idx = 0;
if (num_files < 31)
{
sbuf_count = num_files;
num_files = 0;
}
else
{
sbuf_count = 30;
num_files -= 30;
}
while (loc_order_idx < num_count)
{
while (loc_order_idx < num_count)
{
while (d_loc_order[loc_order_idx] == 0)
{
if (loc_order_idx != num_count)
{
loc_order_idx++;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -