📄 readdir.c
字号:
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 + -