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

📄 readdir.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 3 页
字号:

                        if ((ts_num + 1) > audio_ts.ats_num_max)
                        {
                            audio_ts.ats_num_max = ts_num + 1;
                        }
                        get_file_entry(&ats_file[ts_num].ifo_length, &ats_file[ts_num].ifo_address, udf_start, offset);
                    }

                    else
                    {

                        if (strncmp(&d_order[order_idx + 8], ".AOB", 4) == 0 || strncmp(&d_order[order_idx + 8], ".aob", 4) == 0)
                        {
                            ts_num = get_ts_num(&d_order[order_idx + 4]);

                            ts_tso = (UBYTE) d_order[order_idx + 7] - 0x30;

                            if ((ts_num + 1) > audio_ts.ats_num_max)
                            {
                                audio_ts.ats_num_max = ts_num + 1;
                            }
                            if (ts_tso > vts_file[ts_num].tso_num)
                            {
                                ats_file[ts_num].tso_num = ts_tso;
                            }
                            get_file_entry(&ats_file[ts_num].ts[ts_tso].length, &ats_file[ts_num].ts[ts_tso].address, udf_start, offset);

                            if (get_le(offset + 168))  /* Extended Attribues? */
                            {
                                temp = get_le(192 + offset);        /* 176 + 16 */

                                cgms_offset = temp + 176 + offset;

                                while (cgms_offset < (2048 + offset))
                                {
                                    if (get_le(cgms_offset) != 2048)
                                    {
                                        break;
                                    }
                                    for (temp = 0; temp < 12; temp++)
                                    {
                                        ts[temp] = NON_CACHED_SBUF[cgms_offset + 17 + temp];
                                    }
                                    /* get the cgms info for Macrovision */
                                    if (strncmp(ts, "*UDF DVD CGMS", 12) == 0)
                                    {
                                        ats_file[ts_num].ts[ts_tso].cgms = NON_CACHED_SBUF[cgms_offset + 50];
                                        cgms_offset += 2048;
                                    }
                                    else
                                    {
                                        l_iu = get_le(cgms_offset + 12);
                                        cgms_offset += 48 + l_iu;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            file_start += 30;
        }
    }
#endif

    read_in_progress = 0;

    DBGPRINT(DBG_ON(DBG_TRACE), ("read_dir done...deallocate memory\n"));

    OS_MemFree(d_order);
    d_order = NULL;

    OS_MemFree(d_loc_order);
    d_loc_order = NULL;

    return (0);
}



BOOLEAN ReaddirIsVidTS(LOADER_HANDLE tLoader)
{
    VMG_FILE_STRUCT video_ts;

    video_ts.present = 0;
    video_ts.ifo_address = 1;
    readdir_FindVid_TS(tLoader, &video_ts);

    return(video_ts.present);
}

BOOLEAN ReaddirIsAudTS(LOADER_HANDLE tLoader)
{
#ifdef AUDIO_TS
    VMG_FILE_STRUCT video_ts;
    AMG_FILE_STRUCT audio_ts;

    audio_ts.present = 0;

    readdir_FindVidAud_TS(tLoader, &video_ts, &audio_ts);
    return(audio_ts.present);
#else
    return(FALSE);
#endif
}

ULONG readdir_FindVid_TS(LOADER_HANDLE tLoader, VMG_FILE_STRUCT *video_ts)
{
    AMG_FILE_STRUCT audio_ts;
    video_ts->ifo_address = 12;
    return( (ULONG)readdir_FindVidAud_TS(tLoader, video_ts, &audio_ts) );
}

ULONG readdir_FindVidAud_TS(LOADER_HANDLE tLoader, VMG_FILE_STRUCT *video_ts, AMG_FILE_STRUCT *audio_ts)
{
    ULONG udf_start, offset, cur_sec, l_ea, retval;
    USHORT l_iu, i;
    char  ts[12];
    char  temp[12] = {0};

    video_ts->ifo_address = 123;

    /* Read in the anchor volume descriptor pointer to find the address of the UDF volume
     * descriptor. In the case of DVD-ROM discs, Anchor Volume Descriptor Pointers shall
     * be recorded in the specified logical sectors having the logical sector number 256
     * and at lease one of the last logical sector number or the last logical sector
     * number - 256. */
    sbuf = (UBYTE *)lbuf;

    if (LoaderSectorRead(tLoader, 256, sbuf, 1) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (2)\n", __FILE__, __LINE__));
        retval = -2;
        goto errout;
    }


    /* store the UDF Main Volume Sequence start address */
    udf_start = get_le(20);

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("\n\nUDF Main Volume Sequence - udf_start: %u\n\n", udf_start));


    /* Find the UDF Partition Descriptor
     * The DVD Read Only Disc Spec (Part 2) states that a Volume Descriptor Sequence shall
     * contain a Primary Volume Descriptor, and Implementation Use Volume Descriptor, a
     * Partition Descriptor, a Logical Volume Descriptor, and an Unallocated Space
     * Descriptor. It does not state that they must be in that order so lets do a loop
     * through these 5 sectors until we find the one we want. */

    /* Read the Entire Sequence */
    if (LoaderSectorRead(tLoader, udf_start, sbuf, 5) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (2)\n", __FILE__, __LINE__));
        retval = -2;
        goto errout;
    }

    /* Find the Partition Table */
    for (i=0; i<5; i++)
    {
        /* Verify the Partition Descriptor Tag */
        if (((NON_CACHED_SBUF[i*2048 + 1] << 8) | (NON_CACHED_SBUF[i*2048 + 0])) == 5)
        {
            /* We've found the Partition Descriptor */
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- We've found the Partition Descriptor, i=%d\n", __FILE__, __LINE__, i));
            break;
        }

        /* if we reach 4 then we've failed */
        if (i == 4)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
            retval = -4;
            goto errout;
        }
    }

    /* Get the start of UDF partition-beginning of file sequence address */
    udf_start = get_le(i*2048 + 188);

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("\n\nUDF partition - udf_start: %u\n\n", udf_start));


    /* go to UDF file structure start and get offset to root ICB */
    if (LoaderSectorRead(tLoader, udf_start, sbuf, 2) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (2)\n", __FILE__, __LINE__));
        retval = -2;
        goto errout;
    }

    /* the file set descriptor tag is 256 so if it's not here, we've got problems */
    if ( ((NON_CACHED_SBUF[1] << 8) | (NON_CACHED_SBUF[0])) != 256)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
        retval = -4;
        goto errout;
    }

    /* get the offset to the root ICB */
    offset  = (NON_CACHED_SBUF[405] << 8) | (NON_CACHED_SBUF[404]);
    cur_sec = udf_start + offset;

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("\n\nROOT ICB - cur_sec: %u\n\n", cur_sec));


    /* get the root ICB  */
    if (LoaderSectorRead(tLoader, cur_sec, sbuf, 3) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (2)\n", __FILE__, __LINE__));
        retval = -2;
        goto errout;
    }

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("\n\nROOT ICB - 26 and 27: %x\n\n", ( (NON_CACHED_SBUF[27] << 8) | (NON_CACHED_SBUF[26]) )));

    /* make sure this is the parent directory */
    if ( ( (NON_CACHED_SBUF[27] << 8) | (NON_CACHED_SBUF[26]) ) != 0x400 )
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
        retval = -4;
        goto errout;
    }

    l_ea = get_le(168);
    DBGPRINT(DBG_ON(DBG_VERBOSE), ("read_directory() - l_ea: %u\n", l_ea));

    /* 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() - cur_sec: %u\n", cur_sec));

    /* read in the file identifier descriptors (parent,audio_ts,video_ts directories) */
    if (LoaderSectorRead(tLoader, cur_sec, sbuf, 1) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (2)\n", __FILE__, __LINE__));
        retval = -2;
        goto errout;
    }

    if ( ((NON_CACHED_SBUF[1] << 8) | (NON_CACHED_SBUF[0])) != 0x101 )   /* 257 */
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
        retval = -4;
        goto errout;
    }

    offset = 38;

    /* ok, go thorugh the descriptors until the video_ts is found */
    while (offset < 2048)
    {
        /* go to next file identifier (either audio_ts or video_ts) */
        while ( ((NON_CACHED_SBUF[offset + 1] << 8) | (NON_CACHED_SBUF[offset])) != 0x101 )
            offset++;

        l_iu = (NON_CACHED_SBUF[offset + 36]) | (NON_CACHED_SBUF[offset + 37] << 8);

        for (i = 0; i < 8; i++)
        {
            ts[i] = NON_CACHED_SBUF[offset + 39 + i + l_iu];

            /* Convert to upper case and store in a temporary variable */
            if ( (ts[i] >= 'a') && (ts[i] <= 'z') )
            {
                temp[i] = ts[i] - ' ';
            }
            else
            {
                temp[i] = ts[i];
            }
        }

        if (strncmp(temp, "VIDEO_TS", 8) == 0)
        {
            video_ts->present = 1;
            DBGPRINT(DBG_ON(DBG_TRACE), ("found VIDEO_TS!\n"));

            /* store the ICB address here for now */
            video_ts->ifo_address = (NON_CACHED_SBUF[offset + 25] << 8) | (NON_CACHED_SBUF[offset + 24]);
            DBGPRINT(DBG_ON(DBG_VERBOSE), ("\nvideo_ts->ifo_address: %x\n\n", video_ts->ifo_address));

#ifdef AUDIO_TS
            if (audio_ts->present)
            {
                offset = 2048;
            }
#else
            offset = 2048;
#endif
        }
#ifdef AUDIO_TS
        if (strncmp(temp, "AUDIO_TS", 8) == 0)
        {
            audio_ts->present = 1;
            DBGPRINT(DBG_ON(DBG_TRACE), ("found AUDIO_TS!\n"));

            /* store the ICB address here for now */
            audio_ts->ifo_address = (NON_CACHED_SBUF[offset + 25] << 8) | NON_CACHED_SBUF[offset + 24]);

            if (video_ts->present)
            {
                offset = 2048;
            }
        }
#endif
        offset += 38;
    }

#ifdef AUDIO_TS
    if ((!video_ts->present) && (!audio_ts->present))
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
        retval = -4;
        goto errout;
    }
#else
    if (!video_ts->present)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d -- return (4)\n", __FILE__, __LINE__));
        retval = -4;
        goto errout;
    }
#endif
    return(udf_start);

errout:

    read_in_progress = 0;
    return(retval);
}




/**
 * Purpose:    Format a little endian number to an unsigned long.
 *
 * Theory:     Takes the requested 4 bytes from sbuf and formats them to a
 *             unsigned long from little endian.
 *
 * Arguments:  offset in sbuf to start from
 *
 * Returns:    formatted unsigned long
 */
ULONG get_le(ULONG offset)
{
    return ( (NON_CACHED_SBUF[offset + 3] << 24) | (NON_CACHED_SBUF[offset + 2] << 16) |
        (NON_CACHED_SBUF[offset + 1] << 8) | NON_CACHED_SBUF[offset]);
}

/**
 * Purpose:    Format a big endian number to an unsigned long.
 *
 * Theory:     Takes the requested 4 bytes from sbuf and formats them to a
 *             unsigned long from big endian.
 *
 * Arguments:  offset in sbuf to start from
 *
 * Returns:    formatted unsigned long
 */
ULONG get_be(ULONG offset)
{
    return ((NON_CACHED_SBUF[offset] << 24) | (NON_CACHED_SBUF[offset + 1] << 16) |
        (NON_CACHED_SBUF[offset + 2] << 8) | NON_CACHED_SBUF[offset + 3]);
}

/**
 * Purpose:    Get the LBA and size of a file from it's file entry.
 *
 * Theory:     Assuming the file entry is at the beginning of sbuf, it extracts
 *             the file LBA and size in bytes.
 *
 * Arguments:  pointer to file length storage space,
 *             pointer to file address storage space,
 *             partition begin offset to add to address
 *
 * Returns:    nothing
 */
void get_file_entry(ULONG * length, ULONG * address, ULONG udf, ULONG sbuf_off)
{
    ULONG l_ea, offset;

    l_ea = get_le(168 + sbuf_off);

    offset = 176 + l_ea + sbuf_off;

    *length = get_le(offset);

    *address = get_le(offset + 4) + udf;
}

/**
 * Purpose:    Get the vts number from the file name.
 *
 * Theory:     Takes in the file name and extracts the vts number from the BCD
 *             ASCII number in the file name.
 *
 * Arguments:  pointer to a string of the file name
 *
 * Returns:    binary vts number
 */
UBYTE get_ts_num(char *num)
{
    UBYTE hi, low;

    hi = (UBYTE) num[0] - 0x30;

    low = (UBYTE) num[1] - 0x30;

    return ((hi * 10) + low - 1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -