Mercurial > libdvdread4.hg
annotate dvd_udf.c @ 64:70c34d162e6e src
Replaces the hard-coded values
The parental management structure has ratings levels. The size
of the bit mask is constant but magic values were being used
instead of named constants. This commit changes them to named
constants. This is based on a patch submitted by Frederic Marchal,
fmarchal at perso dot be. Thanks for this tidy cleanup.
author | erik |
---|---|
date | Sun, 30 Jan 2011 23:44:13 +0000 |
parents | 3bc841283972 |
children | 99af5ed114a4 |
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; |
3 | 332 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
333 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
|
334 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
|
335 if( p < len ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
336 target[ i++ ] = data[ p++ ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
337 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
338 } while( p < len ); |
3 | 339 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
340 target[ i ] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
341 return 0; |
3 | 342 } |
343 | |
20 | 344 static int UDFDescriptor( uint8_t *data, uint16_t *TagID ) |
3 | 345 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
346 *TagID = GETN2(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
347 /* TODO: check CRC 'n stuff */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
348 return 0; |
3 | 349 } |
350 | |
20 | 351 static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location ) |
3 | 352 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
353 *Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
354 *Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
355 return 0; |
3 | 356 } |
357 | |
20 | 358 static int UDFShortAD( uint8_t *data, struct AD *ad, |
26 | 359 struct Partition *partition ) |
3 | 360 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
361 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
362 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
363 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
364 ad->Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
365 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
|
366 return 0; |
3 | 367 } |
368 | |
369 static int UDFLongAD( uint8_t *data, struct AD *ad ) | |
370 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
371 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
372 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
373 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
374 ad->Location = GETN4(4); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
375 ad->Partition = GETN2(8); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
376 /* GETN(10, 6, Use); */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
377 return 0; |
3 | 378 } |
379 | |
380 static int UDFExtAD( uint8_t *data, struct AD *ad ) | |
381 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
382 ad->Length = GETN4(0); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
383 ad->Flags = ad->Length >> 30; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
384 ad->Length &= 0x3FFFFFFF; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
385 ad->Location = GETN4(12); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
386 ad->Partition = GETN2(16); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
387 /* GETN(10, 6, Use); */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
388 return 0; |
3 | 389 } |
390 | |
391 static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags ) | |
392 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
393 *FileType = GETN1(11); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
394 *Flags = GETN2(18); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
395 return 0; |
3 | 396 } |
397 | |
398 | |
399 static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number, | |
26 | 400 char *Contents, uint32_t *Start, uint32_t *Length ) |
3 | 401 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
402 *Flags = GETN2(20); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
403 *Number = GETN2(22); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
404 GETN(24, 32, Contents); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
405 *Start = GETN4(188); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
406 *Length = GETN4(192); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
407 return 0; |
3 | 408 } |
409 | |
410 /** | |
411 * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1 | |
412 * on error. | |
413 */ | |
414 static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor ) | |
415 { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
416 uint32_t lbsize, MT_L, N_PM; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
417 Unicodedecode(&data[84], 128, VolumeDescriptor); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
418 lbsize = GETN4(212); /* should be 2048 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
419 MT_L = GETN4(264); /* should be 6 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
420 N_PM = GETN4(268); /* should be 1 */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
421 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
|
422 return 0; |
3 | 423 } |
424 | |
20 | 425 static int UDFFileEntry( uint8_t *data, uint8_t *FileType, |
26 | 426 struct Partition *partition, struct AD *ad ) |
3 | 427 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
428 uint16_t flags; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
429 uint32_t L_EA, L_AD; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
430 unsigned int p; |
3 | 431 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
432 UDFICB( &data[ 16 ], FileType, &flags ); |
3 | 433 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
434 /* 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
|
435 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
|
436 ad->Flags = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
437 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
|
438 ad->Partition = partition->Number; /* use number of current partition */ |
3 | 439 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
440 L_EA = GETN4( 168 ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
441 L_AD = GETN4( 172 ); |
48 | 442 |
443 if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN) | |
444 return 0; | |
445 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
446 p = 176 + L_EA; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
447 while( p < 176 + L_EA + L_AD ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
448 switch( flags & 0x0007 ) { |
31 | 449 case 0: |
450 UDFShortAD( &data[ p ], ad, partition ); | |
451 p += 8; | |
452 break; | |
453 case 1: | |
454 UDFLongAD( &data[ p ], ad ); | |
455 p += 16; | |
456 break; | |
457 case 2: | |
458 UDFExtAD( &data[ p ], ad ); | |
459 p += 20; | |
460 break; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
461 case 3: |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
462 switch( L_AD ) { |
31 | 463 case 8: |
464 UDFShortAD( &data[ p ], ad, partition ); | |
465 break; | |
466 case 16: | |
467 UDFLongAD( &data[ p ], ad ); | |
468 break; | |
469 case 20: | |
470 UDFExtAD( &data[ p ], ad ); | |
471 break; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
472 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
473 p += L_AD; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
474 break; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
475 default: |
31 | 476 p += L_AD; |
477 break; | |
3 | 478 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
479 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
480 return 0; |
3 | 481 } |
482 | |
483 static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics, | |
26 | 484 char *FileName, struct AD *FileICB ) |
3 | 485 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
486 uint8_t L_FI; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
487 uint16_t L_IU; |
3 | 488 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
489 *FileCharacteristics = GETN1(18); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
490 L_FI = GETN1(19); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
491 UDFLongAD(&data[20], FileICB); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
492 L_IU = GETN2(36); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
493 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
|
494 else FileName[0] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
495 return 4 * ((38 + L_FI + L_IU + 3) / 4); |
3 | 496 } |
497 | |
498 /** | |
499 * Maps ICB to FileAD | |
500 * ICB: Location of ICB of directory to scan | |
501 * FileType: Type of the file | |
502 * File: Location of file the ICB is pointing to | |
503 * return 1 on success, 0 on error; | |
504 */ | |
505 static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType, | |
26 | 506 struct Partition *partition, struct AD *File ) |
3 | 507 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
508 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
|
509 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
|
510 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
511 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
512 struct icbmap tmpmap; |
3 | 513 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
514 lbnum = partition->Start + ICB.Location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
515 tmpmap.lbn = lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
516 if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
517 *FileType = tmpmap.filetype; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
518 memcpy(File, &tmpmap.file, sizeof(tmpmap.file)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
519 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
520 } |
3 | 521 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
522 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
523 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
|
524 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
525 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
526 UDFDescriptor( LogBlock, &TagID ); |
3 | 527 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
528 if( TagID == 261 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
529 UDFFileEntry( LogBlock, FileType, partition, File ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
530 memcpy(&tmpmap.file, File, sizeof(tmpmap.file)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
531 tmpmap.filetype = *FileType; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
532 SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
533 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
534 }; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
535 } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 ) |
3 | 536 / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) ); |
537 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
538 return 0; |
3 | 539 } |
540 | |
541 /** | |
542 * Dir: Location of directory to scan | |
543 * FileName: Name of file to look for | |
544 * FileICB: Location of ICB of the found file | |
545 * return 1 on success, 0 on error; | |
546 */ | |
547 static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName, | |
548 struct Partition *partition, struct AD *FileICB, | |
26 | 549 int cache_file_info) |
3 | 550 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
551 char filename[ MAX_UDF_FILE_NAME_LEN ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
552 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
|
553 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
|
554 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
555 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
556 uint8_t filechar; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
557 unsigned int p; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
558 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
|
559 uint32_t dir_lba; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
560 struct AD tmpICB; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
561 int found = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
562 int in_cache = 0; |
3 | 563 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
564 /* Scan dir for ICB of file */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
565 lbnum = partition->Start + Dir.Location; |
3 | 566 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
567 if(DVDUDFCacheLevel(device, -1) > 0) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
568 /* caching */ |
3 | 569 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
570 if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
571 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
|
572 if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) |
3 | 573 return 0; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
574 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
|
575 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
|
576 free(cached_dir_base); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
577 cached_dir_base = NULL; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
578 cached_dir = NULL; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
579 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
580 /* |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
581 if(cached_dir) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
582 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
|
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 { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
586 uint8_t *data[2]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
587 data[0] = cached_dir_base; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
588 data[1] = cached_dir; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
589 SetUDFCache(device, LBUDFCache, lbnum, data); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
590 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
591 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
592 in_cache = 1; |
3 | 593 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
594 if(cached_dir == NULL) |
3 | 595 return 0; |
596 | |
597 p = 0; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
598 |
3 | 599 while( p < Dir.Length ) { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
600 UDFDescriptor( &cached_dir[ p ], &TagID ); |
3 | 601 if( TagID == 257 ) { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
602 p += UDFFileIdentifier( &cached_dir[ p ], &filechar, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
603 filename, &tmpICB ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
604 if(cache_file_info && !in_cache) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
605 uint8_t tmpFiletype; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
606 struct AD tmpFile; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
607 |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
608 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
609 memcpy(FileICB, &tmpICB, sizeof(tmpICB)); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
610 found = 1; |
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 UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
613 } else { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
614 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
615 memcpy(FileICB, &tmpICB, sizeof(tmpICB)); |
3 | 616 return 1; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
617 } |
3 | 618 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
619 } else { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
620 if(cache_file_info && (!in_cache) && found) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
621 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
622 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
623 } |
3 | 624 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
625 if(cache_file_info && (!in_cache) && found) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
626 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
627 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
628 } |
3 | 629 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
630 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) |
3 | 631 return 0; |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
632 |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
633 p = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
634 while( p < Dir.Length ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
635 if( p > DVD_VIDEO_LB_LEN ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
636 ++lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
637 p -= DVD_VIDEO_LB_LEN; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
638 Dir.Length -= DVD_VIDEO_LB_LEN; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
639 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
|
640 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
641 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
642 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
643 UDFDescriptor( &directory[ p ], &TagID ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
644 if( TagID == 257 ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
645 p += UDFFileIdentifier( &directory[ p ], &filechar, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
646 filename, FileICB ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
647 if( !strcasecmp( FileName, filename ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
648 return 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
649 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
650 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
651 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
652 } |
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 return 0; |
3 | 655 } |
656 | |
657 | |
658 static int UDFGetAVDP( dvd_reader_t *device, | |
26 | 659 struct avdp_t *avdp) |
3 | 660 { |
661 uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ]; | |
662 uint8_t *Anchor = (uint8_t *)(((uintptr_t)Anchor_base & ~((uintptr_t)2047)) + 2048); | |
663 uint32_t lbnum, MVDS_location, MVDS_length; | |
664 uint16_t TagID; | |
665 uint32_t lastsector; | |
666 int terminate; | |
20 | 667 struct avdp_t; |
3 | 668 |
669 if(GetUDFCache(device, AVDPCache, 0, avdp)) | |
670 return 1; | |
671 | |
672 /* Find Anchor */ | |
673 lastsector = 0; | |
674 lbnum = 256; /* Try #1, prime anchor */ | |
675 terminate = 0; | |
676 | |
677 for(;;) { | |
678 if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { | |
679 UDFDescriptor( Anchor, &TagID ); | |
680 } else { | |
681 TagID = 0; | |
682 } | |
683 if (TagID != 2) { | |
684 /* Not an anchor */ | |
685 if( terminate ) return 0; /* Final try failed */ | |
686 | |
687 if( lastsector ) { | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
688 /* We already found the last sector. Try #3, alternative |
3 | 689 * 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
|
690 */ |
3 | 691 lbnum = lastsector; |
692 terminate = 1; | |
693 } else { | |
694 /* TODO: Find last sector of the disc (this is optional). */ | |
695 if( lastsector ) | |
696 /* Try #2, backup anchor */ | |
697 lbnum = lastsector - 256; | |
698 else | |
699 /* Unable to find last sector */ | |
700 return 0; | |
701 } | |
702 } else | |
703 /* It's an anchor! We can leave */ | |
704 break; | |
705 } | |
706 /* Main volume descriptor */ | |
707 UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); | |
708 avdp->mvds.location = MVDS_location; | |
709 avdp->mvds.length = MVDS_length; | |
710 | |
711 /* Backup volume descriptor */ | |
712 UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); | |
713 avdp->rvds.location = MVDS_location; | |
714 avdp->rvds.length = MVDS_length; | |
715 | |
716 SetUDFCache(device, AVDPCache, 0, avdp); | |
717 | |
718 return 1; | |
719 } | |
720 | |
721 /** | |
722 * Looks for partition on the disc. Returns 1 if partition found, 0 on error. | |
723 * partnum: Number of the partition, starting at 0. | |
724 * part: structure to fill with the partition information | |
725 */ | |
726 static int UDFFindPartition( dvd_reader_t *device, int partnum, | |
26 | 727 struct Partition *part ) |
3 | 728 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
729 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
|
730 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
|
731 uint32_t lbnum, MVDS_location, MVDS_length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
732 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
733 int i, volvalid; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
734 struct avdp_t avdp; |
3 | 735 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
736 if(!UDFGetAVDP(device, &avdp)) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
737 return 0; |
3 | 738 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
739 /* Main volume descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
740 MVDS_location = avdp.mvds.location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
741 MVDS_length = avdp.mvds.length; |
3 | 742 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
743 part->valid = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
744 volvalid = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
745 part->VolumeDesc[ 0 ] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
746 i = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
747 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
748 /* Find Volume Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
749 lbnum = MVDS_location; |
3 | 750 do { |
751 | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
752 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
|
753 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
754 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
755 UDFDescriptor( LogBlock, &TagID ); |
3 | 756 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
757 if( ( TagID == 5 ) && ( !part->valid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
758 /* Partition Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
759 UDFPartition( LogBlock, &part->Flags, &part->Number, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
760 part->Contents, &part->Start, &part->Length ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
761 part->valid = ( partnum == part->Number ); |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
762 } else if( ( TagID == 6 ) && ( !volvalid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
763 /* Logical Volume Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
764 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
765 /* TODO: sector size wrong! */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
766 } else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
767 volvalid = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
768 } |
3 | 769 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
770 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
771 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
772 && ( ( !part->valid ) || ( !volvalid ) ) ); |
3 | 773 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
774 if( ( !part->valid) || ( !volvalid ) ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
775 /* Backup volume descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
776 MVDS_location = avdp.mvds.location; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
777 MVDS_length = avdp.mvds.length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
778 } |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
779 } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) ); |
3 | 780 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
781 /* 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
|
782 return part->valid; |
3 | 783 } |
784 | |
785 uint32_t UDFFindFile( dvd_reader_t *device, char *filename, | |
26 | 786 uint32_t *filesize ) |
3 | 787 { |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
788 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
|
789 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
|
790 uint32_t lbnum; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
791 uint16_t TagID; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
792 struct Partition partition; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
793 struct AD RootICB, File, ICB; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
794 char tokenline[ MAX_UDF_FILE_NAME_LEN ]; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
795 char *token; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
796 uint8_t filetype; |
3 | 797 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
798 *filesize = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
799 tokenline[0] = '\0'; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
800 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
|
801 memset(&ICB, 0, sizeof(ICB)); |
3 | 802 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
803 if(!(GetUDFCache(device, PartitionCache, 0, &partition) && |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
804 GetUDFCache(device, RootICBCache, 0, &RootICB))) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
805 /* 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
|
806 if( !UDFFindPartition( device, 0, &partition ) ) return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
807 SetUDFCache(device, PartitionCache, 0, &partition); |
3 | 808 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
809 /* Find root dir ICB */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
810 lbnum = partition.Start; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
811 do { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
812 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
|
813 TagID = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
814 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
815 UDFDescriptor( LogBlock, &TagID ); |
3 | 816 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
817 /* File Set Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
818 if( TagID == 256 ) /* File Set Descriptor */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
819 UDFLongAD( &LogBlock[ 400 ], &RootICB ); |
3 | 820 } while( ( lbnum < partition.Start + partition.Length ) |
821 && ( TagID != 8 ) && ( TagID != 256 ) ); | |
822 | |
823 /* Sanity checks. */ | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
824 if( TagID != 256 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
825 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
826 if( RootICB.Partition != 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
827 return 0; |
3 | 828 SetUDFCache(device, RootICBCache, 0, &RootICB); |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
829 } |
3 | 830 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
831 /* Find root dir */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
832 if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
833 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
834 if( filetype != 4 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
835 return 0; /* Root dir should be dir */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
836 { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
837 int cache_file_info = 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
838 /* Tokenize filepath */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
839 token = strtok(tokenline, "/"); |
3 | 840 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
841 while( token != NULL ) { |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
842 if( !UDFScanDir( device, File, token, &partition, &ICB, |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
843 cache_file_info)) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
844 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
845 if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) |
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(!strcmp(token, "VIDEO_TS")) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
848 cache_file_info = 1; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
849 token = strtok( NULL, "/" ); |
3 | 850 } |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
851 } |
3 | 852 |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
853 /* Sanity check. */ |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
854 if( File.Partition != 0 ) |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
855 return 0; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
856 *filesize = File.Length; |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
857 /* 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
|
858 if( !File.Location ) |
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 else |
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
861 return partition.Start + File.Location; |
3 | 862 } |
863 | |
864 | |
865 | |
866 /** | |
867 * Gets a Descriptor . | |
868 * Returns 1 if descriptor found, 0 on error. | |
869 * id, tagid of descriptor | |
870 * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN). | |
871 */ | |
872 static int UDFGetDescriptor( dvd_reader_t *device, int id, | |
26 | 873 uint8_t *descriptor, int bufsize) |
3 | 874 { |
875 uint32_t lbnum, MVDS_location, MVDS_length; | |
876 struct avdp_t avdp; | |
877 uint16_t TagID; | |
878 uint32_t lastsector; | |
879 int i, terminate; | |
880 int desc_found = 0; | |
881 /* Find Anchor */ | |
882 lastsector = 0; | |
883 lbnum = 256; /* Try #1, prime anchor */ | |
884 terminate = 0; | |
885 if(bufsize < DVD_VIDEO_LB_LEN) | |
886 return 0; | |
887 | |
888 if(!UDFGetAVDP(device, &avdp)) | |
889 return 0; | |
890 | |
891 /* Main volume descriptor */ | |
892 MVDS_location = avdp.mvds.location; | |
893 MVDS_length = avdp.mvds.length; | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
894 |
3 | 895 i = 1; |
896 do { | |
897 /* Find Descriptor */ | |
898 lbnum = MVDS_location; | |
899 do { | |
900 if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) | |
901 TagID = 0; | |
902 else | |
903 UDFDescriptor( descriptor, &TagID ); | |
904 if( (TagID == id) && ( !desc_found ) ) | |
905 /* Descriptor */ | |
906 desc_found = 1; | |
907 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) | |
26 | 908 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
909 && ( !desc_found) ); | |
3 | 910 |
911 if( !desc_found ) { | |
912 /* Backup volume descriptor */ | |
913 MVDS_location = avdp.rvds.location; | |
914 MVDS_length = avdp.rvds.length; | |
915 } | |
916 } while( i-- && ( !desc_found ) ); | |
917 | |
918 return desc_found; | |
919 } | |
920 | |
921 | |
922 static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd) | |
923 { | |
924 uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048]; | |
925 uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048); | |
926 if(GetUDFCache(device, PVDCache, 0, pvd)) | |
927 return 1; | |
928 | |
49
1acf15da93ba
fixed buffer size dimension in UDFGetPVD(); patch A00 by John Stebbins
nicodvb
parents:
48
diff
changeset
|
929 if(!UDFGetDescriptor( device, 1, pvd_buf, DVD_VIDEO_LB_LEN)) |
3 | 930 return 0; |
931 | |
932 memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32); | |
933 memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128); | |
934 SetUDFCache(device, PVDCache, 0, pvd); | |
935 return 1; | |
936 } | |
937 | |
938 /** | |
939 * Gets the Volume Identifier string, in 8bit unicode (latin-1) | |
940 * volid, place to put the string | |
941 * volid_size, size of the buffer volid points to | |
942 * returns the size of buffer needed for all data | |
943 */ | |
944 int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid, | |
26 | 945 unsigned int volid_size) |
3 | 946 { |
947 struct pvd_t pvd; | |
948 unsigned int volid_len; | |
949 | |
950 /* get primary volume descriptor */ | |
951 if(!UDFGetPVD(device, &pvd)) | |
952 return 0; | |
953 | |
954 volid_len = pvd.VolumeIdentifier[31]; | |
955 if(volid_len > 31) | |
956 /* this field is only 32 bytes something is wrong */ | |
957 volid_len = 31; | |
958 if(volid_size > volid_len) | |
959 volid_size = volid_len; | |
960 Unicodedecode(pvd.VolumeIdentifier, volid_size, volid); | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
961 |
3 | 962 return volid_len; |
963 } | |
964 | |
965 /** | |
966 * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) | |
967 * WARNING This is not a null terminated string | |
968 * volsetid, place to put the data | |
20 | 969 * volsetid_size, size of the buffer volsetid points to |
3 | 970 * the buffer should be >=128 bytes to store the whole volumesetidentifier |
971 * returns the size of the available volsetid information (128) | |
972 * or 0 on error | |
973 */ | |
974 int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid, | |
26 | 975 unsigned int volsetid_size) |
3 | 976 { |
977 struct pvd_t pvd; | |
978 | |
979 /* get primary volume descriptor */ | |
980 if(!UDFGetPVD(device, &pvd)) | |
981 return 0; | |
982 | |
983 | |
984 if(volsetid_size > 128) | |
985 volsetid_size = 128; | |
986 | |
987 memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size); | |
27
98951f8ec89c
cosmetics: Sync indentation and similar changes from libdvdread 0.9.5.
diego
parents:
26
diff
changeset
|
988 |
3 | 989 return 128; |
990 } |