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