⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readdir.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
*******************************************************************************
**                                                                           **
**  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 + -