annotate libmpdvdkit2/dvd_udf.c @ 10560:11826d9f90c7

this patch fixes 1) some bugs introduced in the tuner autodetection and in the channel-parsing functions, 3) retries reading when the mplayer/mencoder don't read fast enough (sooner it exited) but especially 4) makes the stream compliant with the new, modular stream api (the one currently in CVS is not and is totally unreachable). [and maybe more, next time please include cvslog in patch! -- A'rpi] patch by Nico <nsabbi@libero.it>
author arpi
date Mon, 11 Aug 2003 00:02:46 +0000
parents fc5aba542810
children 845c6e56cc91
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7029
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
1 /*
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
2 * This code is based on dvdudf by:
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
3 * Christian Wolff <scarabaeus@convergence.de>.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
4 *
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
5 * Modifications by:
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
6 * Billy Biggs <vektor@dumbterm.net>.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
7 *
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
8 * dvdudf: parse and read the UDF volume information of a DVD Video
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
9 * Copyright (C) 1999 Christian Wolff for convergence integrated media
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
10 * GmbH The author can be reached at scarabaeus@convergence.de, the
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
11 * project's page is at http://linuxtv.org/dvd/
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
12 *
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
13 * This program is free software; you can redistribute it and/or modify
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
14 * it under the terms of the GNU General Public License as published by
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
15 * the Free Software Foundation; either version 2 of the License, or (at
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
16 * your option) any later version.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
17 *
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
18 * This program is distributed in the hope that it will be useful, but
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
21 * General Public License for more details.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
22 *
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
23 * You should have received a copy of the GNU General Public License
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
24 * along with this program; if not, write to the Free Software
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
26 * 02111-1307, USA. Or, point your browser to
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
27 * http://www.gnu.org/copyleft/gpl.html
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
28 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
29
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
30 #include <stdio.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
31 #include <stdlib.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
32 #include <string.h>
7033
596919e4f601 apply mplayer-specific patches
arpi
parents: 7029
diff changeset
33 //#include <assert.h>
9928
fc5aba542810 MINGW32 port
faust3
parents: 7033
diff changeset
34 #ifndef __MINGW32__
7029
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
35 #include <sys/ioctl.h>
9928
fc5aba542810 MINGW32 port
faust3
parents: 7033
diff changeset
36 #endif
7029
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
37 #include <sys/types.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
38 #include <sys/stat.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
39 #include <unistd.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
40 #include <inttypes.h>
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
41
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
42 #include "dvd_reader.h"
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
43 #include "dvd_udf.h"
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
44
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
45 /* Private but located in/shared with dvd_reader.c */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
46 extern int DVDReadBlocksUDFRaw( dvd_reader_t *device, uint32_t lb_number,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
47 size_t block_count, unsigned char *data,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
48 int encrypted );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
49
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
50 /* It's required to either fail or deliver all the blocks asked for. */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
51 static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
52 size_t block_count, unsigned char *data,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
53 int encrypted )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
54 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
55 int ret;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
56 size_t count = block_count;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
57
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
58 while(count > 0) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
59
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
60 ret = DVDReadBlocksUDFRaw(device, lb_number, count, data, encrypted);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
61
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
62 if(ret <= 0) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
63 /* One of the reads failed or nothing more to read, too bad.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
64 * We won't even bother returning the reads that went ok. */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
65 return ret;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
66 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
67
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
68 count -= (size_t)ret;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
69 lb_number += (uint32_t)ret;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
70 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
71
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
72 return block_count;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
73 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
74
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
75
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
76 #ifndef NULL
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
77 #define NULL ((void *)0)
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
78 #endif
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
79
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
80 struct Partition {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
81 int valid;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
82 char VolumeDesc[128];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
83 uint16_t Flags;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
84 uint16_t Number;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
85 char Contents[32];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
86 uint32_t AccessType;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
87 uint32_t Start;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
88 uint32_t Length;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
89 };
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
90
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
91 struct AD {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
92 uint32_t Location;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
93 uint32_t Length;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
94 uint8_t Flags;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
95 uint16_t Partition;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
96 };
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
97
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
98 /* For direct data access, LSB first */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
99 #define GETN1(p) ((uint8_t)data[p])
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
100 #define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8))
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
101 #define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) \
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
102 | ((uint32_t)data[(p) + 2] << 16))
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
103 #define GETN4(p) ((uint32_t)data[p] \
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
104 | ((uint32_t)data[(p) + 1] << 8) \
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
105 | ((uint32_t)data[(p) + 2] << 16) \
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
106 | ((uint32_t)data[(p) + 3] << 24))
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
107 /* This is wrong with regard to endianess */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
108 #define GETN(p, n, target) memcpy(target, &data[p], n)
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
109
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
110 static int Unicodedecode( uint8_t *data, int len, char *target )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
111 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
112 int p = 1, i = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
113
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
114 if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
115 if( data[ 0 ] == 16 ) p++; /* Ignore MSB of unicode16 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
116 if( p < len ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
117 target[ i++ ] = data[ p++ ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
118 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
119 } while( p < len );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
120
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
121 target[ i ] = '\0';
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
122 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
123 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
124
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
125 static int UDFDescriptor( uint8_t *data, uint16_t *TagID )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
126 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
127 *TagID = GETN2(0);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
128 // TODO: check CRC 'n stuff
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
129 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
130 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
131
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
132 static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
133 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
134 *Length = GETN4(0);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
135 *Location = GETN4(4);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
136 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
137 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
138
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
139 static int UDFShortAD( uint8_t *data, struct AD *ad,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
140 struct Partition *partition )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
141 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
142 ad->Length = GETN4(0);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
143 ad->Flags = ad->Length >> 30;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
144 ad->Length &= 0x3FFFFFFF;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
145 ad->Location = GETN4(4);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
146 ad->Partition = partition->Number; // use number of current partition
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
147 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
148 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
149
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
150 static int UDFLongAD( uint8_t *data, struct AD *ad )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
151 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
152 ad->Length = GETN4(0);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
153 ad->Flags = ad->Length >> 30;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
154 ad->Length &= 0x3FFFFFFF;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
155 ad->Location = GETN4(4);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
156 ad->Partition = GETN2(8);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
157 //GETN(10, 6, Use);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
158 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
159 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
160
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
161 static int UDFExtAD( uint8_t *data, struct AD *ad )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
162 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
163 ad->Length = GETN4(0);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
164 ad->Flags = ad->Length >> 30;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
165 ad->Length &= 0x3FFFFFFF;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
166 ad->Location = GETN4(12);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
167 ad->Partition = GETN2(16);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
168 //GETN(10, 6, Use);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
169 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
170 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
171
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
172 static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
173 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
174 *FileType = GETN1(11);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
175 *Flags = GETN2(18);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
176 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
177 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
178
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
179
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
180 static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
181 char *Contents, uint32_t *Start, uint32_t *Length )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
182 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
183 *Flags = GETN2(20);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
184 *Number = GETN2(22);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
185 GETN(24, 32, Contents);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
186 *Start = GETN4(188);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
187 *Length = GETN4(192);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
188 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
189 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
190
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
191 /**
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
192 * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
193 * on error.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
194 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
195 static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
196 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
197 uint32_t lbsize, MT_L, N_PM;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
198 Unicodedecode(&data[84], 128, VolumeDescriptor);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
199 lbsize = GETN4(212); // should be 2048
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
200 MT_L = GETN4(264); // should be 6
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
201 N_PM = GETN4(268); // should be 1
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
202 if (lbsize != DVD_VIDEO_LB_LEN) return 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
203 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
204 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
205
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
206 static int UDFFileEntry( uint8_t *data, uint8_t *FileType,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
207 struct Partition *partition, struct AD *ad )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
208 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
209 uint16_t flags;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
210 uint32_t L_EA, L_AD;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
211 unsigned int p;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
212
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
213 UDFICB( &data[ 16 ], FileType, &flags );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
214
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
215 /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
216 ad->Length = GETN4( 60 ); // Really 8 bytes a 56
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
217 ad->Flags = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
218 ad->Location = 0; // what should we put here?
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
219 ad->Partition = partition->Number; // use number of current partition
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
220
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
221 L_EA = GETN4( 168 );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
222 L_AD = GETN4( 172 );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
223 p = 176 + L_EA;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
224 while( p < 176 + L_EA + L_AD ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
225 switch( flags & 0x0007 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
226 case 0: UDFShortAD( &data[ p ], ad, partition ); p += 8; break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
227 case 1: UDFLongAD( &data[ p ], ad ); p += 16; break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
228 case 2: UDFExtAD( &data[ p ], ad ); p += 20; break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
229 case 3:
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
230 switch( L_AD ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
231 case 8: UDFShortAD( &data[ p ], ad, partition ); break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
232 case 16: UDFLongAD( &data[ p ], ad ); break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
233 case 20: UDFExtAD( &data[ p ], ad ); break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
234 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
235 p += L_AD;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
236 break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
237 default:
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
238 p += L_AD; break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
239 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
240 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
241 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
242 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
243
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
244 static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
245 char *FileName, struct AD *FileICB )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
246 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
247 uint8_t L_FI;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
248 uint16_t L_IU;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
249
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
250 *FileCharacteristics = GETN1(18);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
251 L_FI = GETN1(19);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
252 UDFLongAD(&data[20], FileICB);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
253 L_IU = GETN2(36);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
254 if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
255 else FileName[0] = '\0';
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
256 return 4 * ((38 + L_FI + L_IU + 3) / 4);
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
257 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
258
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
259 /**
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
260 * Maps ICB to FileAD
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
261 * ICB: Location of ICB of directory to scan
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
262 * FileType: Type of the file
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
263 * File: Location of file the ICB is pointing to
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
264 * return 1 on success, 0 on error;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
265 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
266 static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
267 struct Partition *partition, struct AD *File )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
268 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
269 uint8_t LogBlock[DVD_VIDEO_LB_LEN];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
270 uint32_t lbnum;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
271 uint16_t TagID;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
272
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
273 lbnum = partition->Start + ICB.Location;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
274 do {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
275 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
276 TagID = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
277 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
278 UDFDescriptor( LogBlock, &TagID );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
279 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
280
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
281 if( TagID == 261 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
282 UDFFileEntry( LogBlock, FileType, partition, File );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
283 return 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
284 };
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
285 } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
286 / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
287
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
288 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
289 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
290
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
291 /**
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
292 * Dir: Location of directory to scan
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
293 * FileName: Name of file to look for
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
294 * FileICB: Location of ICB of the found file
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
295 * return 1 on success, 0 on error;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
296 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
297 static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
298 struct Partition *partition, struct AD *FileICB )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
299 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
300 char filename[ MAX_UDF_FILE_NAME_LEN ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
301 uint8_t directory[ 2 * DVD_VIDEO_LB_LEN ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
302 uint32_t lbnum;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
303 uint16_t TagID;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
304 uint8_t filechar;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
305 unsigned int p;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
306
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
307 /* Scan dir for ICB of file */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
308 lbnum = partition->Start + Dir.Location;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
309
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
310 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
311 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
312 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
313
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
314 p = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
315 while( p < Dir.Length ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
316 if( p > DVD_VIDEO_LB_LEN ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
317 ++lbnum;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
318 p -= DVD_VIDEO_LB_LEN;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
319 Dir.Length -= DVD_VIDEO_LB_LEN;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
320 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
321 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
322 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
323 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
324 UDFDescriptor( &directory[ p ], &TagID );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
325 if( TagID == 257 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
326 p += UDFFileIdentifier( &directory[ p ], &filechar,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
327 filename, FileICB );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
328 if( !strcasecmp( FileName, filename ) ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
329 return 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
330 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
331 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
332 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
333 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
334 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
335
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
336 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
337 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
338
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
339 /**
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
340 * Looks for partition on the disc. Returns 1 if partition found, 0 on error.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
341 * partnum: Number of the partition, starting at 0.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
342 * part: structure to fill with the partition information
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
343 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
344 static int UDFFindPartition( dvd_reader_t *device, int partnum,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
345 struct Partition *part )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
346 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
347 uint8_t LogBlock[ DVD_VIDEO_LB_LEN ], Anchor[ DVD_VIDEO_LB_LEN ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
348 uint32_t lbnum, MVDS_location, MVDS_length;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
349 uint16_t TagID;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
350 uint32_t lastsector;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
351 int i, terminate, volvalid;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
352
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
353 /* Find Anchor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
354 lastsector = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
355 lbnum = 256; /* Try #1, prime anchor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
356 terminate = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
357
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
358 for(;;) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
359 if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
360 UDFDescriptor( Anchor, &TagID );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
361 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
362 TagID = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
363 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
364 if (TagID != 2) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
365 /* Not an anchor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
366 if( terminate ) return 0; /* Final try failed */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
367
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
368 if( lastsector ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
369
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
370 /* We already found the last sector. Try #3, alternative
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
371 * backup anchor. If that fails, don't try again.
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
372 */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
373 lbnum = lastsector;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
374 terminate = 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
375 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
376 /* TODO: Find last sector of the disc (this is optional). */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
377 if( lastsector ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
378 /* Try #2, backup anchor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
379 lbnum = lastsector - 256;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
380 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
381 /* Unable to find last sector */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
382 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
383 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
384 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
385 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
386 /* It's an anchor! We can leave */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
387 break;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
388 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
389 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
390 /* Main volume descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
391 UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
392
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
393 part->valid = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
394 volvalid = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
395 part->VolumeDesc[ 0 ] = '\0';
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
396 i = 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
397 do {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
398 /* Find Volume Descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
399 lbnum = MVDS_location;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
400 do {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
401
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
402 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
403 TagID = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
404 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
405 UDFDescriptor( LogBlock, &TagID );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
406 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
407
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
408 if( ( TagID == 5 ) && ( !part->valid ) ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
409 /* Partition Descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
410 UDFPartition( LogBlock, &part->Flags, &part->Number,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
411 part->Contents, &part->Start, &part->Length );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
412 part->valid = ( partnum == part->Number );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
413 } else if( ( TagID == 6 ) && ( !volvalid ) ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
414 /* Logical Volume Descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
415 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
416 /* TODO: sector size wrong! */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
417 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
418 volvalid = 1;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
419 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
420 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
421
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
422 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
423 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
424 && ( ( !part->valid ) || ( !volvalid ) ) );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
425
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
426 if( ( !part->valid) || ( !volvalid ) ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
427 /* Backup volume descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
428 UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
429 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
430 } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
431
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
432 /* We only care for the partition, not the volume */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
433 return part->valid;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
434 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
435
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
436 uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
437 uint32_t *filesize )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
438 {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
439 uint8_t LogBlock[ DVD_VIDEO_LB_LEN ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
440 uint32_t lbnum;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
441 uint16_t TagID;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
442 struct Partition partition;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
443 struct AD RootICB, File, ICB;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
444 char tokenline[ MAX_UDF_FILE_NAME_LEN ];
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
445 char *token;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
446 uint8_t filetype;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
447
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
448 *filesize = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
449 tokenline[0] = '\0';
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
450 strcat( tokenline, filename );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
451
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
452 /* Find partition, 0 is the standard location for DVD Video.*/
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
453 if( !UDFFindPartition( device, 0, &partition ) ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
454
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
455 /* Find root dir ICB */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
456 lbnum = partition.Start;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
457 do {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
458 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
459 TagID = 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
460 } else {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
461 UDFDescriptor( LogBlock, &TagID );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
462 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
463
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
464 /* File Set Descriptor */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
465 if( TagID == 256 ) { // File Set Descriptor
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
466 UDFLongAD( &LogBlock[ 400 ], &RootICB );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
467 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
468 } while( ( lbnum < partition.Start + partition.Length )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
469 && ( TagID != 8 ) && ( TagID != 256 ) );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
470
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
471 /* Sanity checks. */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
472 if( TagID != 256 ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
473 if( RootICB.Partition != 0 ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
474
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
475 /* Find root dir */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
476 if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
477 if( filetype != 4 ) return 0; /* Root dir should be dir */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
478
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
479 /* Tokenize filepath */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
480 token = strtok(tokenline, "/");
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
481 while( token != NULL ) {
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
482 if( !UDFScanDir( device, File, token, &partition, &ICB ) ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
483 if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
484 token = strtok( NULL, "/" );
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
485 }
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
486
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
487 /* Sanity check. */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
488 if( File.Partition != 0 ) return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
489
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
490 *filesize = File.Length;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
491 /* Hack to not return partition.Start for empty files. */
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
492 if( !File.Location )
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
493 return 0;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
494 else
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
495 return partition.Start + File.Location;
9db58ffbd73c importing libdvdread 0.9.3 files
arpi
parents:
diff changeset
496 }