Mercurial > libdvdread4.hg
annotate dvd_udf.c @ 59:bfefcc426154 src
Provide BUP file support for more issues.
The BUP file is only opened when the IFO file open fails. We have a
few times where file corruption could happen and we could use the
BUP instead. This patch attempts to address this by trying to
open the BUP if there is any reported error w/ the IFO. Inspiration
for this patch came from Rich E, thanks for the detailed bug
report and attempts at using earlier patches.
author | erik |
---|---|
date | Sat, 31 Jul 2010 00:21:01 +0000 |
parents | 1acf15da93ba |
children | 3bc841283972 |
rev | line source |
---|---|
3 | 1 /* |
2 * This code is based on dvdudf by: | |
3 * Christian Wolff <scarabaeus@convergence.de>. | |
4 * | |
5 * Modifications by: | |
6 * Billy Biggs <vektor@dumbterm.net>. | |
22 | 7 * Björn Englund <d4bjorn@dtek.chalmers.se>. |
3 | 8 * |
9 * dvdudf: parse and read the UDF volume information of a DVD Video | |
10 * Copyright (C) 1999 Christian Wolff for convergence integrated media | |
11 * GmbH The author can be reached at scarabaeus@convergence.de, the | |
12 * project's page is at http://linuxtv.org/dvd/ | |
20 | 13 * |
21
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
14 * This file is part of libdvdread. |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
15 * |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
16 * libdvdread is free software; you can redistribute it and/or modify |
3 | 17 * it under the terms of the GNU General Public License as published by |
21
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
18 * the Free Software Foundation; either version 2 of the License, or |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
19 * (at your option) any later version. |
20 | 20 * |
21
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
21 * libdvdread is distributed in the hope that it will be useful, |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
24 * GNU General Public License for more details. |
20 | 25 * |
21
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
26 * You should have received a copy of the GNU General Public License along |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
27 * with libdvdread; if not, write to the Free Software Foundation, Inc., |
4aa618ae094f
Use consistent license headers everywhere: Fix FSF address and boilerplate.
diego
parents:
20
diff
changeset
|
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
3 | 29 */ |
20 | 30 |
3 | 31 #include <stdio.h> |
32 #include <stdlib.h> | |
33 #include <string.h> | |
34 | |
35 #include <sys/types.h> | |
36 #include <sys/stat.h> | |
37 #include <unistd.h> | |
38 #include <inttypes.h> | |
39 | |
33
c743d79f187b
Move installed headers into dvdread directory to make them easier to
reimar
parents:
31
diff
changeset
|
40 #include "dvdread/dvd_reader.h" |
c743d79f187b
Move installed headers into dvdread directory to make them easier to
reimar
parents:
31
diff
changeset
|
41 #include "dvdread/dvd_udf.h" |
3 | 42 |
43 /* Private but located in/shared with dvd_reader.c */ | |
44 extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
45 size_t block_count, unsigned char *data, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
46 int encrypted ); |
3 | 47 |
48 /* It's required to either fail or deliver all the blocks asked for. */ | |
49 static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number, | |
26 | 50 size_t block_count, unsigned char *data, |
51 int encrypted ) | |
3 | 52 { |
53 int ret; | |
54 size_t count = block_count; | |
55 | |
56 while(count > 0) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
57 |
3 | 58 ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted); |
59 | |
60 if(ret <= 0) { | |
61 /* One of the reads failed or nothing more to read, too bad. | |
62 * We won't even bother returning the reads that went ok. */ | |
63 return ret; | |
64 } | |
65 | |
66 count -= (size_t)ret; | |
67 lb_number += (uint32_t)ret; | |
68 } | |
69 | |
70 return block_count; | |
71 } | |
72 | |
73 | |
74 #ifndef NULL | |
75 #define NULL ((void *)0) | |
76 #endif | |
77 | |
78 struct Partition { | |
79 int valid; | |
80 char VolumeDesc[128]; | |
81 uint16_t Flags; | |
82 uint16_t Number; | |
83 char Contents[32]; | |
84 uint32_t AccessType; | |
85 uint32_t Start; | |
86 uint32_t Length; | |
87 }; | |
88 | |
89 struct AD { | |
90 uint32_t Location; | |
91 uint32_t Length; | |
92 uint8_t Flags; | |
93 uint16_t Partition; | |
94 }; | |
95 | |
96 struct extent_ad { | |
97 uint32_t location; | |
98 uint32_t length; | |
99 }; | |
100 | |
101 struct avdp_t { | |
102 struct extent_ad mvds; | |
103 struct extent_ad rvds; | |
104 }; | |
105 | |
106 struct pvd_t { | |
107 uint8_t VolumeIdentifier[32]; | |
108 uint8_t VolumeSetIdentifier[128]; | |
109 }; | |
110 | |
111 struct lbudf { | |
112 uint32_t lb; | |
113 uint8_t *data; | |
114 /* needed for proper freeing */ | |
115 uint8_t *data_base; | |
116 }; | |
117 | |
118 struct icbmap { | |
119 uint32_t lbn; | |
120 struct AD file; | |
121 uint8_t filetype; | |
122 }; | |
123 | |
124 struct udf_cache { | |
125 int avdp_valid; | |
126 struct avdp_t avdp; | |
127 int pvd_valid; | |
128 struct pvd_t pvd; | |
129 int partition_valid; | |
130 struct Partition partition; | |
131 int rooticb_valid; | |
132 struct AD rooticb; | |
133 int lb_num; | |
134 struct lbudf *lbs; | |
135 int map_num; | |
136 struct icbmap *maps; | |
137 }; | |
138 | |
139 typedef enum { | |
140 PartitionCache, RootICBCache, LBUDFCache, MapCache, AVDPCache, PVDCache | |
141 } UDFCacheType; | |
142 | |
143 void FreeUDFCache(void *cache) | |
144 { | |
145 struct udf_cache *c = (struct udf_cache *)cache; | |
146 if(c == NULL) | |
147 return; | |
148 | |
149 if(c->lbs) { | |
150 int n; | |
151 for(n = 0; n < c->lb_num; n++) | |
152 free(c->lbs[n].data_base); | |
153 free(c->lbs); | |
154 } | |
155 if(c->maps) | |
156 free(c->maps); | |
157 free(c); | |
158 } | |
159 | |
160 | |
161 static int GetUDFCache(dvd_reader_t *device, UDFCacheType type, | |
26 | 162 uint32_t nr, void *data) |
3 | 163 { |
164 int n; | |
165 struct udf_cache *c; | |
166 | |
167 if(DVDUDFCacheLevel(device, -1) <= 0) | |
168 return 0; | |
169 | |
170 c = (struct udf_cache *)GetUDFCacheHandle(device); | |
171 | |
172 if(c == NULL) | |
173 return 0; | |
174 | |
175 switch(type) { | |
176 case AVDPCache: | |
177 if(c->avdp_valid) { | |
178 *(struct avdp_t *)data = c->avdp; | |
179 return 1; | |
180 } | |
181 break; | |
182 case PVDCache: | |
183 if(c->pvd_valid) { | |
184 *(struct pvd_t *)data = c->pvd; | |
185 return 1; | |
186 } | |
187 break; | |
188 case PartitionCache: | |
189 if(c->partition_valid) { | |
190 *(struct Partition *)data = c->partition; | |
191 return 1; | |
192 } | |
193 break; | |
194 case RootICBCache: | |
195 if(c->rooticb_valid) { | |
196 *(struct AD *)data = c->rooticb; | |
197 return 1; | |
198 } | |
199 break; | |
200 case LBUDFCache: | |
201 for(n = 0; n < c->lb_num; n++) { | |
202 if(c->lbs[n].lb == nr) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
203 *(uint8_t **)data = c->lbs[n].data; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
204 return 1; |
3 | 205 } |
206 } | |
207 break; | |
208 case MapCache: | |
209 for(n = 0; n < c->map_num; n++) { | |
210 if(c->maps[n].lbn == nr) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
211 *(struct icbmap *)data = c->maps[n]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
212 return 1; |
3 | 213 } |
214 } | |
215 break; | |
216 default: | |
217 break; | |
218 } | |
219 | |
220 return 0; | |
221 } | |
222 | |
223 static int SetUDFCache(dvd_reader_t *device, UDFCacheType type, | |
26 | 224 uint32_t nr, void *data) |
3 | 225 { |
226 int n; | |
227 struct udf_cache *c; | |
228 void *tmp; | |
229 | |
230 if(DVDUDFCacheLevel(device, -1) <= 0) | |
231 return 0; | |
232 | |
233 c = (struct udf_cache *)GetUDFCacheHandle(device); | |
234 | |
235 if(c == NULL) { | |
20 | 236 c = calloc(1, sizeof(struct udf_cache)); |
3 | 237 /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */ |
238 if(c == NULL) | |
239 return 0; | |
240 SetUDFCacheHandle(device, c); | |
241 } | |
242 | |
243 | |
244 switch(type) { | |
245 case AVDPCache: | |
20 | 246 c->avdp = *(struct avdp_t *)data; |
3 | 247 c->avdp_valid = 1; |
248 break; | |
249 case PVDCache: | |
20 | 250 c->pvd = *(struct pvd_t *)data; |
3 | 251 c->pvd_valid = 1; |
252 break; | |
253 case PartitionCache: | |
20 | 254 c->partition = *(struct Partition *)data; |
3 | 255 c->partition_valid = 1; |
256 break; | |
257 case RootICBCache: | |
20 | 258 c->rooticb = *(struct AD *)data; |
3 | 259 c->rooticb_valid = 1; |
260 break; | |
261 case LBUDFCache: | |
262 for(n = 0; n < c->lb_num; n++) { | |
263 if(c->lbs[n].lb == nr) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
264 /* replace with new data */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
265 c->lbs[n].data_base = ((uint8_t **)data)[0]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
266 c->lbs[n].data = ((uint8_t **)data)[1]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
267 c->lbs[n].lb = nr; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
268 return 1; |
3 | 269 } |
270 } | |
271 c->lb_num++; | |
272 tmp = realloc(c->lbs, c->lb_num * sizeof(struct lbudf)); | |
273 /* | |
274 fprintf(stderr, "realloc lb: %d * %d = %d\n", | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
275 c->lb_num, sizeof(struct lbudf), |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
276 c->lb_num * sizeof(struct lbudf)); |
3 | 277 */ |
278 if(tmp == NULL) { | |
279 if(c->lbs) free(c->lbs); | |
280 c->lb_num = 0; | |
281 return 0; | |
282 } | |
283 c->lbs = tmp; | |
284 c->lbs[n].data_base = ((uint8_t **)data)[0]; | |
285 c->lbs[n].data = ((uint8_t **)data)[1]; | |
286 c->lbs[n].lb = nr; | |
287 break; | |
288 case MapCache: | |
289 for(n = 0; n < c->map_num; n++) { | |
290 if(c->maps[n].lbn == nr) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
291 /* replace with new data */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
292 c->maps[n] = *(struct icbmap *)data; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
293 c->maps[n].lbn = nr; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
294 return 1; |
3 | 295 } |
296 } | |
297 c->map_num++; | |
298 tmp = realloc(c->maps, c->map_num * sizeof(struct icbmap)); | |
299 /* | |
300 fprintf(stderr, "realloc maps: %d * %d = %d\n", | |
301 c->map_num, sizeof(struct icbmap), | |
302 c->map_num * sizeof(struct icbmap)); | |
303 */ | |
304 if(tmp == NULL) { | |
305 if(c->maps) free(c->maps); | |
306 c->map_num = 0; | |
307 return 0; | |
308 } | |
309 c->maps = tmp; | |
310 c->maps[n] = *(struct icbmap *)data; | |
311 c->maps[n].lbn = nr; | |
312 break; | |
313 default: | |
314 return 0; | |
315 } | |
316 | |
317 return 1; | |
318 } | |
319 | |
320 | |
321 /* For direct data access, LSB first */ | |
322 #define GETN1(p) ((uint8_t)data[p]) | |
323 #define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8)) | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
324 #define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) \ |
26 | 325 | ((uint32_t)data[(p) + 2] << 16)) |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
326 #define GETN4(p) ((uint32_t)data[p] \ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
327 | ((uint32_t)data[(p) + 1] << 8) \ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
328 | ((uint32_t)data[(p) + 2] << 16) \ |
26 | 329 | ((uint32_t)data[(p) + 3] << 24)) |
3 | 330 /* This is wrong with regard to endianess */ |
331 #define GETN(p, n, target) memcpy(target, &data[p], n) | |
332 | |
20 | 333 static int Unicodedecode( uint8_t *data, int len, char *target ) |
3 | 334 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
335 int p = 1, i = 0; |
3 | 336 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
337 if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
338 if( data[ 0 ] == 16 ) p++; /* Ignore MSB of unicode16 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
339 if( p < len ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
340 target[ i++ ] = data[ p++ ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
341 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
342 } while( p < len ); |
3 | 343 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
344 target[ i ] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
345 return 0; |
3 | 346 } |
347 | |
20 | 348 static int UDFDescriptor( uint8_t *data, uint16_t *TagID ) |
3 | 349 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
350 *TagID = GETN2(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
351 /* TODO: check CRC 'n stuff */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
352 return 0; |
3 | 353 } |
354 | |
20 | 355 static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location ) |
3 | 356 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
357 *Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
358 *Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
359 return 0; |
3 | 360 } |
361 | |
20 | 362 static int UDFShortAD( uint8_t *data, struct AD *ad, |
26 | 363 struct Partition *partition ) |
3 | 364 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
365 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
366 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
367 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
368 ad->Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
369 ad->Partition = partition->Number; /* use number of current partition */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
370 return 0; |
3 | 371 } |
372 | |
373 static int UDFLongAD( uint8_t *data, struct AD *ad ) | |
374 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
375 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
376 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
377 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
378 ad->Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
379 ad->Partition = GETN2(8); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
380 /* GETN(10, 6, Use); */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
381 return 0; |
3 | 382 } |
383 | |
384 static int UDFExtAD( uint8_t *data, struct AD *ad ) | |
385 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
386 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
387 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
388 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
389 ad->Location = GETN4(12); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
390 ad->Partition = GETN2(16); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
391 /* GETN(10, 6, Use); */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
392 return 0; |
3 | 393 } |
394 | |
395 static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags ) | |
396 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
397 *FileType = GETN1(11); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
398 *Flags = GETN2(18); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
399 return 0; |
3 | 400 } |
401 | |
402 | |
403 static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number, | |
26 | 404 char *Contents, uint32_t *Start, uint32_t *Length ) |
3 | 405 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
406 *Flags = GETN2(20); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
407 *Number = GETN2(22); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
408 GETN(24, 32, Contents); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
409 *Start = GETN4(188); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
410 *Length = GETN4(192); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
411 return 0; |
3 | 412 } |
413 | |
414 /** | |
415 * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1 | |
416 * on error. | |
417 */ | |
418 static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor ) | |
419 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
420 uint32_t lbsize, MT_L, N_PM; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
421 Unicodedecode(&data[84], 128, VolumeDescriptor); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
422 lbsize = GETN4(212); /* should be 2048 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
423 MT_L = GETN4(264); /* should be 6 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
424 N_PM = GETN4(268); /* should be 1 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
425 if (lbsize != DVD_VIDEO_LB_LEN) return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
426 return 0; |
3 | 427 } |
428 | |
20 | 429 static int UDFFileEntry( uint8_t *data, uint8_t *FileType, |
26 | 430 struct Partition *partition, struct AD *ad ) |
3 | 431 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
432 uint16_t flags; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
433 uint32_t L_EA, L_AD; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
434 unsigned int p; |
3 | 435 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
436 UDFICB( &data[ 16 ], FileType, &flags ); |
3 | 437 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
438 /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
439 ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
440 ad->Flags = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
441 ad->Location = 0; /* what should we put here? */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
442 ad->Partition = partition->Number; /* use number of current partition */ |
3 | 443 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
444 L_EA = GETN4( 168 ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
445 L_AD = GETN4( 172 ); |
48 | 446 |
447 if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN) | |
448 return 0; | |
449 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
450 p = 176 + L_EA; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
451 while( p < 176 + L_EA + L_AD ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
452 switch( flags & 0x0007 ) { |
31 | 453 case 0: |
454 UDFShortAD( &data[ p ], ad, partition ); | |
455 p += 8; | |
456 break; | |
457 case 1: | |
458 UDFLongAD( &data[ p ], ad ); | |
459 p += 16; | |
460 break; | |
461 case 2: | |
462 UDFExtAD( &data[ p ], ad ); | |
463 p += 20; | |
464 break; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
465 case 3: |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
466 switch( L_AD ) { |
31 | 467 case 8: |
468 UDFShortAD( &data[ p ], ad, partition ); | |
469 break; | |
470 case 16: | |
471 UDFLongAD( &data[ p ], ad ); | |
472 break; | |
473 case 20: | |
474 UDFExtAD( &data[ p ], ad ); | |
475 break; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
476 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
477 p += L_AD; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
478 break; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
479 default: |
31 | 480 p += L_AD; |
481 break; | |
3 | 482 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
483 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
484 return 0; |
3 | 485 } |
486 | |
487 static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics, | |
26 | 488 char *FileName, struct AD *FileICB ) |
3 | 489 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
490 uint8_t L_FI; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
491 uint16_t L_IU; |
3 | 492 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
493 *FileCharacteristics = GETN1(18); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
494 L_FI = GETN1(19); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
495 UDFLongAD(&data[20], FileICB); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
496 L_IU = GETN2(36); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
497 if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
498 else FileName[0] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
499 return 4 * ((38 + L_FI + L_IU + 3) / 4); |
3 | 500 } |
501 | |
502 /** | |
503 * Maps ICB to FileAD | |
504 * ICB: Location of ICB of directory to scan | |
505 * FileType: Type of the file | |
506 * File: Location of file the ICB is pointing to | |
507 * return 1 on success, 0 on error; | |
508 */ | |
509 static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType, | |
26 | 510 struct Partition *partition, struct AD *File ) |
3 | 511 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
512 uint8_t LogBlock_base[DVD_VIDEO_LB_LEN + 2048]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
513 uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
514 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
515 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
516 struct icbmap tmpmap; |
3 | 517 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
518 lbnum = partition->Start + ICB.Location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
519 tmpmap.lbn = lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
520 if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
521 *FileType = tmpmap.filetype; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
522 memcpy(File, &tmpmap.file, sizeof(tmpmap.file)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
523 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
524 } |
3 | 525 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
526 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
527 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
528 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
529 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
530 UDFDescriptor( LogBlock, &TagID ); |
3 | 531 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
532 if( TagID == 261 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
533 UDFFileEntry( LogBlock, FileType, partition, File ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
534 memcpy(&tmpmap.file, File, sizeof(tmpmap.file)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
535 tmpmap.filetype = *FileType; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
536 SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
537 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
538 }; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
539 } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 ) |
3 | 540 / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) ); |
541 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
542 return 0; |
3 | 543 } |
544 | |
545 /** | |
546 * Dir: Location of directory to scan | |
547 * FileName: Name of file to look for | |
548 * FileICB: Location of ICB of the found file | |
549 * return 1 on success, 0 on error; | |
550 */ | |
551 static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName, | |
552 struct Partition *partition, struct AD *FileICB, | |
26 | 553 int cache_file_info) |
3 | 554 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
555 char filename[ MAX_UDF_FILE_NAME_LEN ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
556 uint8_t directory_base[ 2 * DVD_VIDEO_LB_LEN + 2048]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
557 uint8_t *directory = (uint8_t *)(((uintptr_t)directory_base & ~((uintptr_t)2047)) + 2048); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
558 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
559 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
560 uint8_t filechar; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
561 unsigned int p; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
562 uint8_t *cached_dir_base = NULL, *cached_dir; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
563 uint32_t dir_lba; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
564 struct AD tmpICB; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
565 int found = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
566 int in_cache = 0; |
3 | 567 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
568 /* Scan dir for ICB of file */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
569 lbnum = partition->Start + Dir.Location; |
3 | 570 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
571 if(DVDUDFCacheLevel(device, -1) > 0) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
572 /* caching */ |
3 | 573 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
574 if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
575 dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
576 if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) |
3 | 577 return 0; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
578 cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
579 if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
580 free(cached_dir_base); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
581 cached_dir_base = NULL; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
582 cached_dir = NULL; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
583 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
584 /* |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
585 if(cached_dir) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
586 fprintf(stderr, "malloc dir: %d\n", dir_lba * DVD_VIDEO_LB_LEN); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
587 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
588 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
589 { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
590 uint8_t *data[2]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
591 data[0] = cached_dir_base; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
592 data[1] = cached_dir; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
593 SetUDFCache(device, LBUDFCache, lbnum, data); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
594 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
595 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
596 in_cache = 1; |
3 | 597 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
598 if(cached_dir == NULL) |
3 | 599 return 0; |
600 | |
601 p = 0; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
602 |
3 | 603 while( p < Dir.Length ) { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
604 UDFDescriptor( &cached_dir[ p ], &TagID ); |
3 | 605 if( TagID == 257 ) { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
606 p += UDFFileIdentifier( &cached_dir[ p ], &filechar, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
607 filename, &tmpICB ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
608 if(cache_file_info && !in_cache) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
609 uint8_t tmpFiletype; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
610 struct AD tmpFile; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
611 |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
612 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
613 memcpy(FileICB, &tmpICB, sizeof(tmpICB)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
614 found = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
615 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
616 UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
617 } else { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
618 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
619 memcpy(FileICB, &tmpICB, sizeof(tmpICB)); |
3 | 620 return 1; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
621 } |
3 | 622 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
623 } else { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
624 if(cache_file_info && (!in_cache) && found) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
625 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
626 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
627 } |
3 | 628 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
629 if(cache_file_info && (!in_cache) && found) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
630 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
631 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
632 } |
3 | 633 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
634 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) |
3 | 635 return 0; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
636 |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
637 p = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
638 while( p < Dir.Length ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
639 if( p > DVD_VIDEO_LB_LEN ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
640 ++lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
641 p -= DVD_VIDEO_LB_LEN; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
642 Dir.Length -= DVD_VIDEO_LB_LEN; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
643 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
644 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
645 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
646 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
647 UDFDescriptor( &directory[ p ], &TagID ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
648 if( TagID == 257 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
649 p += UDFFileIdentifier( &directory[ p ], &filechar, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
650 filename, FileICB ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
651 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
652 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
653 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
654 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
655 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
656 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
657 |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
658 return 0; |
3 | 659 } |
660 | |
661 | |
662 static int UDFGetAVDP( dvd_reader_t *device, | |
26 | 663 struct avdp_t *avdp) |
3 | 664 { |
665 uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ]; | |
666 uint8_t *Anchor = (uint8_t *)(((uintptr_t)Anchor_base & ~((uintptr_t)2047)) + 2048); | |
667 uint32_t lbnum, MVDS_location, MVDS_length; | |
668 uint16_t TagID; | |
669 uint32_t lastsector; | |
670 int terminate; | |
20 | 671 struct avdp_t; |
3 | 672 |
673 if(GetUDFCache(device, AVDPCache, 0, avdp)) | |
674 return 1; | |
675 | |
676 /* Find Anchor */ | |
677 lastsector = 0; | |
678 lbnum = 256; /* Try #1, prime anchor */ | |
679 terminate = 0; | |
680 | |
681 for(;;) { | |
682 if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { | |
683 UDFDescriptor( Anchor, &TagID ); | |
684 } else { | |
685 TagID = 0; | |
686 } | |
687 if (TagID != 2) { | |
688 /* Not an anchor */ | |
689 if( terminate ) return 0; /* Final try failed */ | |
690 | |
691 if( lastsector ) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
692 /* We already found the last sector. Try #3, alternative |
3 | 693 * backup anchor. If that fails, don't try again. |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
694 */ |
3 | 695 lbnum = lastsector; |
696 terminate = 1; | |
697 } else { | |
698 /* TODO: Find last sector of the disc (this is optional). */ | |
699 if( lastsector ) | |
700 /* Try #2, backup anchor */ | |
701 lbnum = lastsector - 256; | |
702 else | |
703 /* Unable to find last sector */ | |
704 return 0; | |
705 } | |
706 } else | |
707 /* It's an anchor! We can leave */ | |
708 break; | |
709 } | |
710 /* Main volume descriptor */ | |
711 UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); | |
712 avdp->mvds.location = MVDS_location; | |
713 avdp->mvds.length = MVDS_length; | |
714 | |
715 /* Backup volume descriptor */ | |
716 UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); | |
717 avdp->rvds.location = MVDS_location; | |
718 avdp->rvds.length = MVDS_length; | |
719 | |
720 SetUDFCache(device, AVDPCache, 0, avdp); | |
721 | |
722 return 1; | |
723 } | |
724 | |
725 /** | |
726 * Looks for partition on the disc. Returns 1 if partition found, 0 on error. | |
727 * partnum: Number of the partition, starting at 0. | |
728 * part: structure to fill with the partition information | |
729 */ | |
730 static int UDFFindPartition( dvd_reader_t *device, int partnum, | |
26 | 731 struct Partition *part ) |
3 | 732 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
733 uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
734 uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
735 uint32_t lbnum, MVDS_location, MVDS_length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
736 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
737 int i, volvalid; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
738 struct avdp_t avdp; |
3 | 739 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
740 if(!UDFGetAVDP(device, &avdp)) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
741 return 0; |
3 | 742 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
743 /* Main volume descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
744 MVDS_location = avdp.mvds.location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
745 MVDS_length = avdp.mvds.length; |
3 | 746 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
747 part->valid = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
748 volvalid = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
749 part->VolumeDesc[ 0 ] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
750 i = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
751 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
752 /* Find Volume Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
753 lbnum = MVDS_location; |
3 | 754 do { |
755 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
756 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
757 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
758 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
759 UDFDescriptor( LogBlock, &TagID ); |
3 | 760 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
761 if( ( TagID == 5 ) && ( !part->valid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
762 /* Partition Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
763 UDFPartition( LogBlock, &part->Flags, &part->Number, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
764 part->Contents, &part->Start, &part->Length ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
765 part->valid = ( partnum == part->Number ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
766 } else if( ( TagID == 6 ) && ( !volvalid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
767 /* Logical Volume Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
768 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
769 /* TODO: sector size wrong! */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
770 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
771 volvalid = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
772 } |
3 | 773 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
774 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
775 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
776 && ( ( !part->valid ) || ( !volvalid ) ) ); |
3 | 777 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
778 if( ( !part->valid) || ( !volvalid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
779 /* Backup volume descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
780 MVDS_location = avdp.mvds.location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
781 MVDS_length = avdp.mvds.length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
782 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
783 } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) ); |
3 | 784 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
785 /* We only care for the partition, not the volume */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
786 return part->valid; |
3 | 787 } |
788 | |
789 uint32_t UDFFindFile( dvd_reader_t *device, char *filename, | |
26 | 790 uint32_t *filesize ) |
3 | 791 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
792 uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
793 uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
794 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
795 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
796 struct Partition partition; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
797 struct AD RootICB, File, ICB; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
798 char tokenline[ MAX_UDF_FILE_NAME_LEN ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
799 char *token; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
800 uint8_t filetype; |
3 | 801 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
802 *filesize = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
803 tokenline[0] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
804 strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
805 memset(&ICB, 0, sizeof(ICB)); |
3 | 806 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
807 if(!(GetUDFCache(device, PartitionCache, 0, &partition) && |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
808 GetUDFCache(device, RootICBCache, 0, &RootICB))) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
809 /* Find partition, 0 is the standard location for DVD Video.*/ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
810 if( !UDFFindPartition( device, 0, &partition ) ) return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
811 SetUDFCache(device, PartitionCache, 0, &partition); |
3 | 812 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
813 /* Find root dir ICB */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
814 lbnum = partition.Start; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
815 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
816 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
817 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
818 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
819 UDFDescriptor( LogBlock, &TagID ); |
3 | 820 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
821 /* File Set Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
822 if( TagID == 256 ) /* File Set Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
823 UDFLongAD( &LogBlock[ 400 ], &RootICB ); |
3 | 824 } while( ( lbnum < partition.Start + partition.Length ) |
825 && ( TagID != 8 ) && ( TagID != 256 ) ); | |
826 | |
827 /* Sanity checks. */ | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
828 if( TagID != 256 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
829 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
830 if( RootICB.Partition != 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
831 return 0; |
3 | 832 SetUDFCache(device, RootICBCache, 0, &RootICB); |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
833 } |
3 | 834 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
835 /* Find root dir */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
836 if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
837 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
838 if( filetype != 4 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
839 return 0; /* Root dir should be dir */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
840 { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
841 int cache_file_info = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
842 /* Tokenize filepath */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
843 token = strtok(tokenline, "/"); |
3 | 844 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
845 while( token != NULL ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
846 if( !UDFScanDir( device, File, token, &partition, &ICB, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
847 cache_file_info)) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
848 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
849 if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
850 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
851 if(!strcmp(token, "VIDEO_TS")) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
852 cache_file_info = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
853 token = strtok( NULL, "/" ); |
3 | 854 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
855 } |
3 | 856 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
857 /* Sanity check. */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
858 if( File.Partition != 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
859 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
860 *filesize = File.Length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
861 /* Hack to not return partition.Start for empty files. */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
862 if( !File.Location ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
863 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
864 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
865 return partition.Start + File.Location; |
3 | 866 } |
867 | |
868 | |
869 | |
870 /** | |
871 * Gets a Descriptor . | |
872 * Returns 1 if descriptor found, 0 on error. | |
873 * id, tagid of descriptor | |
874 * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN). | |
875 */ | |
876 static int UDFGetDescriptor( dvd_reader_t *device, int id, | |
26 | 877 uint8_t *descriptor, int bufsize) |
3 | 878 { |
879 uint32_t lbnum, MVDS_location, MVDS_length; | |
880 struct avdp_t avdp; | |
881 uint16_t TagID; | |
882 uint32_t lastsector; | |
883 int i, terminate; | |
884 int desc_found = 0; | |
885 /* Find Anchor */ | |
886 lastsector = 0; | |
887 lbnum = 256; /* Try #1, prime anchor */ | |
888 terminate = 0; | |
889 if(bufsize < DVD_VIDEO_LB_LEN) | |
890 return 0; | |
891 | |
892 if(!UDFGetAVDP(device, &avdp)) | |
893 return 0; | |
894 | |
895 /* Main volume descriptor */ | |
896 MVDS_location = avdp.mvds.location; | |
897 MVDS_length = avdp.mvds.length; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
898 |
3 | 899 i = 1; |
900 do { | |
901 /* Find Descriptor */ | |
902 lbnum = MVDS_location; | |
903 do { | |
904 if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) | |
905 TagID = 0; | |
906 else | |
907 UDFDescriptor( descriptor, &TagID ); | |
908 if( (TagID == id) && ( !desc_found ) ) | |
909 /* Descriptor */ | |
910 desc_found = 1; | |
911 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) | |
26 | 912 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
913 && ( !desc_found) ); | |
3 | 914 |
915 if( !desc_found ) { | |
916 /* Backup volume descriptor */ | |
917 MVDS_location = avdp.rvds.location; | |
918 MVDS_length = avdp.rvds.length; | |
919 } | |
920 } while( i-- && ( !desc_found ) ); | |
921 | |
922 return desc_found; | |
923 } | |
924 | |
925 | |
926 static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd) | |
927 { | |
928 uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048]; | |
929 uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048); | |
930 if(GetUDFCache(device, PVDCache, 0, pvd)) | |
931 return 1; | |
932 | |
49
1acf15da93ba
fixed buffer size dimension in UDFGetPVD(); patch A00 by John Stebbins
nicodvb
parents:
48
diff
changeset
|
933 if(!UDFGetDescriptor( device, 1, pvd_buf, DVD_VIDEO_LB_LEN)) |
3 | 934 return 0; |
935 | |
936 memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32); | |
937 memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128); | |
938 SetUDFCache(device, PVDCache, 0, pvd); | |
939 return 1; | |
940 } | |
941 | |
942 /** | |
943 * Gets the Volume Identifier string, in 8bit unicode (latin-1) | |
944 * volid, place to put the string | |
945 * volid_size, size of the buffer volid points to | |
946 * returns the size of buffer needed for all data | |
947 */ | |
948 int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid, | |
26 | 949 unsigned int volid_size) |
3 | 950 { |
951 struct pvd_t pvd; | |
952 unsigned int volid_len; | |
953 | |
954 /* get primary volume descriptor */ | |
955 if(!UDFGetPVD(device, &pvd)) | |
956 return 0; | |
957 | |
958 volid_len = pvd.VolumeIdentifier[31]; | |
959 if(volid_len > 31) | |
960 /* this field is only 32 bytes something is wrong */ | |
961 volid_len = 31; | |
962 if(volid_size > volid_len) | |
963 volid_size = volid_len; | |
964 Unicodedecode(pvd.VolumeIdentifier, volid_size, volid); | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
965 |
3 | 966 return volid_len; |
967 } | |
968 | |
969 /** | |
970 * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) | |
971 * WARNING This is not a null terminated string | |
972 * volsetid, place to put the data | |
20 | 973 * volsetid_size, size of the buffer volsetid points to |
3 | 974 * the buffer should be >=128 bytes to store the whole volumesetidentifier |
975 * returns the size of the available volsetid information (128) | |
976 * or 0 on error | |
977 */ | |
978 int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid, | |
26 | 979 unsigned int volsetid_size) |
3 | 980 { |
981 struct pvd_t pvd; | |
982 | |
983 /* get primary volume descriptor */ | |
984 if(!UDFGetPVD(device, &pvd)) | |
985 return 0; | |
986 | |
987 | |
988 if(volsetid_size > 128) | |
989 volsetid_size = 128; | |
990 | |
991 memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size); | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
992 |
3 | 993 return 128; |
994 } |