Mercurial > libdvdnav.hg
comparison dvdread/dvd_udf.c @ 356:da4ae9160df7 src
100% cosmetics: removed various spaces/tabs and useless braces. Tiny reindentation
author | nicodvb |
---|---|
date | Sat, 10 May 2008 10:24:22 +0000 |
parents | 80a6f5839cf7 |
children | 8949e15ebbd4 |
comparison
equal
deleted
inserted
replaced
355:80a6f5839cf7 | 356:da4ae9160df7 |
---|---|
52 size_t block_count, unsigned char *data, | 52 size_t block_count, unsigned char *data, |
53 int encrypted ) | 53 int encrypted ) |
54 { | 54 { |
55 int ret; | 55 int ret; |
56 size_t count = block_count; | 56 size_t count = block_count; |
57 | 57 |
58 while(count > 0) { | 58 while(count > 0) { |
59 | |
60 ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted); | 59 ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted); |
61 | 60 |
62 if(ret <= 0) { | 61 if(ret <= 0) { |
63 /* One of the reads failed or nothing more to read, too bad. | 62 /* One of the reads failed or nothing more to read, too bad. |
64 * We won't even bother returning the reads that went ok. */ | 63 * We won't even bother returning the reads that went ok. */ |
65 return ret; | 64 return ret; |
66 } | 65 } |
67 | 66 |
68 count -= (size_t)ret; | 67 count -= (size_t)ret; |
69 lb_number += (uint32_t)ret; | 68 lb_number += (uint32_t)ret; |
70 } | 69 } |
71 | 70 |
72 return block_count; | 71 return block_count; |
76 #ifndef NULL | 75 #ifndef NULL |
77 #define NULL ((void *)0) | 76 #define NULL ((void *)0) |
78 #endif | 77 #endif |
79 | 78 |
80 struct Partition { | 79 struct Partition { |
81 int valid; | 80 int valid; |
82 char VolumeDesc[128]; | 81 char VolumeDesc[128]; |
83 uint16_t Flags; | 82 uint16_t Flags; |
84 uint16_t Number; | 83 uint16_t Number; |
85 char Contents[32]; | 84 char Contents[32]; |
86 uint32_t AccessType; | 85 uint32_t AccessType; |
87 uint32_t Start; | 86 uint32_t Start; |
88 uint32_t Length; | 87 uint32_t Length; |
89 }; | 88 }; |
90 | 89 |
91 struct AD { | 90 struct AD { |
92 uint32_t Location; | 91 uint32_t Location; |
93 uint32_t Length; | 92 uint32_t Length; |
94 uint8_t Flags; | 93 uint8_t Flags; |
95 uint16_t Partition; | 94 uint16_t Partition; |
96 }; | 95 }; |
97 | 96 |
98 struct extent_ad { | 97 struct extent_ad { |
99 uint32_t location; | 98 uint32_t location; |
100 uint32_t length; | 99 uint32_t length; |
143 } UDFCacheType; | 142 } UDFCacheType; |
144 | 143 |
145 void FreeUDFCache(void *cache) | 144 void FreeUDFCache(void *cache) |
146 { | 145 { |
147 struct udf_cache *c = (struct udf_cache *)cache; | 146 struct udf_cache *c = (struct udf_cache *)cache; |
148 if(c == NULL) { | 147 if(c == NULL) |
149 return; | 148 return; |
150 } | 149 |
151 if(c->lbs) { | 150 if(c->lbs) { |
152 int n; | 151 int n; |
153 for(n = 0; n < c->lb_num; n++) | 152 for(n = 0; n < c->lb_num; n++) |
154 free(c->lbs[n].data_base); | 153 free(c->lbs[n].data_base); |
155 free(c->lbs); | 154 free(c->lbs); |
165 uint32_t nr, void *data) | 164 uint32_t nr, void *data) |
166 { | 165 { |
167 int n; | 166 int n; |
168 struct udf_cache *c; | 167 struct udf_cache *c; |
169 | 168 |
170 if(DVDUDFCacheLevel(device, -1) <= 0) { | 169 if(DVDUDFCacheLevel(device, -1) <= 0) |
171 return 0; | 170 return 0; |
172 } | 171 |
173 | |
174 c = (struct udf_cache *)GetUDFCacheHandle(device); | 172 c = (struct udf_cache *)GetUDFCacheHandle(device); |
175 | 173 |
176 if(c == NULL) { | 174 if(c == NULL) |
177 return 0; | 175 return 0; |
178 } | 176 |
179 | |
180 switch(type) { | 177 switch(type) { |
181 case AVDPCache: | 178 case AVDPCache: |
182 if(c->avdp_valid) { | 179 if(c->avdp_valid) { |
183 *(struct avdp_t *)data = c->avdp; | 180 *(struct avdp_t *)data = c->avdp; |
184 return 1; | 181 return 1; |
185 } | 182 } |
186 break; | 183 break; |
187 case PVDCache: | 184 case PVDCache: |
188 if(c->pvd_valid) { | 185 if(c->pvd_valid) { |
189 *(struct pvd_t *)data = c->pvd; | 186 *(struct pvd_t *)data = c->pvd; |
190 return 1; | 187 return 1; |
191 } | 188 } |
192 break; | 189 break; |
193 case PartitionCache: | 190 case PartitionCache: |
194 if(c->partition_valid) { | 191 if(c->partition_valid) { |
195 *(struct Partition *)data = c->partition; | 192 *(struct Partition *)data = c->partition; |
196 return 1; | 193 return 1; |
219 } | 216 } |
220 break; | 217 break; |
221 default: | 218 default: |
222 break; | 219 break; |
223 } | 220 } |
224 | 221 |
225 return 0; | 222 return 0; |
226 } | 223 } |
227 | 224 |
228 static int SetUDFCache(dvd_reader_t *device, UDFCacheType type, | 225 static int SetUDFCache(dvd_reader_t *device, UDFCacheType type, |
229 uint32_t nr, void *data) | 226 uint32_t nr, void *data) |
234 if(DVDUDFCacheLevel(device, -1) <= 0) { | 231 if(DVDUDFCacheLevel(device, -1) <= 0) { |
235 return 0; | 232 return 0; |
236 } | 233 } |
237 | 234 |
238 c = (struct udf_cache *)GetUDFCacheHandle(device); | 235 c = (struct udf_cache *)GetUDFCacheHandle(device); |
239 | 236 |
240 if(c == NULL) { | 237 if(c == NULL) { |
241 c = calloc(1, sizeof(struct udf_cache)); | 238 c = calloc(1, sizeof(struct udf_cache)); |
242 /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */ | 239 /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */ |
243 if(c == NULL) { | 240 if(c == NULL) { |
244 return 0; | 241 return 0; |
245 } | 242 } |
246 SetUDFCacheHandle(device, c); | 243 SetUDFCacheHandle(device, c); |
247 } | 244 } |
248 | 245 |
249 | 246 |
250 switch(type) { | 247 switch(type) { |
251 case AVDPCache: | 248 case AVDPCache: |
252 c->avdp = *(struct avdp_t *)data; | 249 c->avdp = *(struct avdp_t *)data; |
253 c->avdp_valid = 1; | 250 c->avdp_valid = 1; |
254 break; | 251 break; |
276 } | 273 } |
277 c->lb_num++; | 274 c->lb_num++; |
278 c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf)); | 275 c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf)); |
279 /* | 276 /* |
280 fprintf(stderr, "realloc lb: %d * %d = %d\n", | 277 fprintf(stderr, "realloc lb: %d * %d = %d\n", |
281 c->lb_num, sizeof(struct lbudf), | 278 c->lb_num, sizeof(struct lbudf), |
282 c->lb_num * sizeof(struct lbudf)); | 279 c->lb_num * sizeof(struct lbudf)); |
283 */ | 280 */ |
284 if(c->lbs == NULL) { | 281 if(c->lbs == NULL) { |
285 c->lb_num = 0; | 282 c->lb_num = 0; |
286 return 0; | 283 return 0; |
287 } | 284 } |
300 } | 297 } |
301 c->map_num++; | 298 c->map_num++; |
302 c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap)); | 299 c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap)); |
303 /* | 300 /* |
304 fprintf(stderr, "realloc maps: %d * %d = %d\n", | 301 fprintf(stderr, "realloc maps: %d * %d = %d\n", |
305 c->map_num, sizeof(struct icbmap), | 302 c->map_num, sizeof(struct icbmap), |
306 c->map_num * sizeof(struct icbmap)); | 303 c->map_num * sizeof(struct icbmap)); |
307 */ | 304 */ |
308 if(c->maps == NULL) { | 305 if(c->maps == NULL) { |
309 c->map_num = 0; | 306 c->map_num = 0; |
310 return 0; | 307 return 0; |
311 } | 308 } |
313 c->maps[n].lbn = nr; | 310 c->maps[n].lbn = nr; |
314 break; | 311 break; |
315 default: | 312 default: |
316 return 0; | 313 return 0; |
317 } | 314 } |
318 | 315 |
319 return 1; | 316 return 1; |
320 } | 317 } |
321 | 318 |
322 | 319 |
323 /* For direct data access, LSB first */ | 320 /* For direct data access, LSB first */ |
434 uint16_t flags; | 431 uint16_t flags; |
435 uint32_t L_EA, L_AD; | 432 uint32_t L_EA, L_AD; |
436 unsigned int p; | 433 unsigned int p; |
437 | 434 |
438 UDFICB( &data[ 16 ], FileType, &flags ); | 435 UDFICB( &data[ 16 ], FileType, &flags ); |
439 | 436 |
440 /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ | 437 /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ |
441 ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ | 438 ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ |
442 ad->Flags = 0; | 439 ad->Flags = 0; |
443 ad->Location = 0; /* what should we put here? */ | 440 ad->Location = 0; /* what should we put here? */ |
444 ad->Partition = partition->Number; /* use number of current partition */ | 441 ad->Partition = partition->Number; /* use number of current partition */ |
548 int found = 0; | 545 int found = 0; |
549 int in_cache = 0; | 546 int in_cache = 0; |
550 | 547 |
551 /* Scan dir for ICB of file */ | 548 /* Scan dir for ICB of file */ |
552 lbnum = partition->Start + Dir.Location; | 549 lbnum = partition->Start + Dir.Location; |
553 | 550 |
554 if(DVDUDFCacheLevel(device, -1) > 0) { | 551 if(DVDUDFCacheLevel(device, -1) > 0) { |
555 /* caching */ | 552 /* caching */ |
556 | 553 |
557 if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { | 554 if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { |
558 dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; | 555 dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; |
559 if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) { | 556 if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) { |
560 return 0; | 557 return 0; |
561 } | 558 } |
578 SetUDFCache(device, LBUDFCache, lbnum, data); | 575 SetUDFCache(device, LBUDFCache, lbnum, data); |
579 } | 576 } |
580 } else { | 577 } else { |
581 in_cache = 1; | 578 in_cache = 1; |
582 } | 579 } |
583 | 580 |
584 if(cached_dir == NULL) { | 581 if(cached_dir == NULL) |
585 return 0; | 582 return 0; |
586 } | 583 |
587 | |
588 p = 0; | 584 p = 0; |
589 | 585 |
590 while( p < Dir.Length ) { | 586 while( p < Dir.Length ) { |
591 UDFDescriptor( &cached_dir[ p ], &TagID ); | 587 UDFDescriptor( &cached_dir[ p ], &TagID ); |
592 if( TagID == 257 ) { | 588 if( TagID == 257 ) { |
593 p += UDFFileIdentifier( &cached_dir[ p ], &filechar, | 589 p += UDFFileIdentifier( &cached_dir[ p ], &filechar, |
594 filename, &tmpICB ); | 590 filename, &tmpICB ); |
595 if(cache_file_info && !in_cache) { | 591 if(cache_file_info && !in_cache) { |
596 uint8_t tmpFiletype; | 592 uint8_t tmpFiletype; |
597 struct AD tmpFile; | 593 struct AD tmpFile; |
598 | 594 |
599 if( !strcasecmp( FileName, filename ) ) { | 595 if( !strcasecmp( FileName, filename ) ) { |
600 *FileICB = tmpICB; | 596 *FileICB = tmpICB; |
601 found = 1; | 597 found = 1; |
602 | 598 |
603 } | 599 } |
604 UDFMapICB(device, tmpICB, &tmpFiletype, | 600 UDFMapICB(device, tmpICB, &tmpFiletype, |
605 partition, &tmpFile); | 601 partition, &tmpFile); |
606 } else { | 602 } else { |
607 if( !strcasecmp( FileName, filename ) ) { | 603 if( !strcasecmp( FileName, filename ) ) { |
614 return 1; | 610 return 1; |
615 } | 611 } |
616 return 0; | 612 return 0; |
617 } | 613 } |
618 } | 614 } |
619 if(cache_file_info && (!in_cache) && found) { | 615 if(cache_file_info && (!in_cache) && found) |
620 return 1; | 616 return 1; |
621 } | |
622 return 0; | 617 return 0; |
623 } | 618 } |
624 | 619 |
625 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { | 620 if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) |
626 return 0; | 621 return 0; |
627 } | |
628 | 622 |
629 p = 0; | 623 p = 0; |
630 while( p < Dir.Length ) { | 624 while( p < Dir.Length ) { |
631 if( p > DVD_VIDEO_LB_LEN ) { | 625 if( p > DVD_VIDEO_LB_LEN ) { |
632 ++lbnum; | 626 ++lbnum; |
660 uint32_t lbnum, MVDS_location, MVDS_length; | 654 uint32_t lbnum, MVDS_location, MVDS_length; |
661 uint16_t TagID; | 655 uint16_t TagID; |
662 uint32_t lastsector; | 656 uint32_t lastsector; |
663 int terminate; | 657 int terminate; |
664 struct avdp_t; | 658 struct avdp_t; |
665 | 659 |
666 if(GetUDFCache(device, AVDPCache, 0, avdp)) { | 660 if(GetUDFCache(device, AVDPCache, 0, avdp)) |
667 return 1; | 661 return 1; |
668 } | |
669 | 662 |
670 /* Find Anchor */ | 663 /* Find Anchor */ |
671 lastsector = 0; | 664 lastsector = 0; |
672 lbnum = 256; /* Try #1, prime anchor */ | 665 lbnum = 256; /* Try #1, prime anchor */ |
673 terminate = 0; | 666 terminate = 0; |
674 | 667 |
675 for(;;) { | 668 for(;;) { |
676 if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { | 669 if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { |
677 UDFDescriptor( Anchor, &TagID ); | 670 UDFDescriptor( Anchor, &TagID ); |
678 } else { | 671 } else { |
679 TagID = 0; | 672 TagID = 0; |
680 } | 673 } |
681 if (TagID != 2) { | 674 if (TagID != 2) { |
682 /* Not an anchor */ | 675 /* Not an anchor */ |
683 if( terminate ) return 0; /* Final try failed */ | 676 if( terminate ) return 0; /* Final try failed */ |
684 | 677 |
685 if( lastsector ) { | 678 if( lastsector ) { |
686 | 679 |
687 /* We already found the last sector. Try #3, alternative | 680 /* We already found the last sector. Try #3, alternative |
688 * backup anchor. If that fails, don't try again. | 681 * backup anchor. If that fails, don't try again. |
689 */ | 682 */ |
706 } | 699 } |
707 /* Main volume descriptor */ | 700 /* Main volume descriptor */ |
708 UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); | 701 UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); |
709 avdp->mvds.location = MVDS_location; | 702 avdp->mvds.location = MVDS_location; |
710 avdp->mvds.length = MVDS_length; | 703 avdp->mvds.length = MVDS_length; |
711 | 704 |
712 /* Backup volume descriptor */ | 705 /* Backup volume descriptor */ |
713 UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); | 706 UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); |
714 avdp->rvds.location = MVDS_location; | 707 avdp->rvds.location = MVDS_location; |
715 avdp->rvds.length = MVDS_length; | 708 avdp->rvds.length = MVDS_length; |
716 | 709 |
717 SetUDFCache(device, AVDPCache, 0, avdp); | 710 SetUDFCache(device, AVDPCache, 0, avdp); |
718 | 711 |
719 return 1; | 712 return 1; |
720 } | 713 } |
721 | 714 |
722 /** | 715 /** |
723 * Looks for partition on the disc. Returns 1 if partition found, 0 on error. | 716 * Looks for partition on the disc. Returns 1 if partition found, 0 on error. |
732 uint32_t lbnum, MVDS_location, MVDS_length; | 725 uint32_t lbnum, MVDS_location, MVDS_length; |
733 uint16_t TagID; | 726 uint16_t TagID; |
734 int i, volvalid; | 727 int i, volvalid; |
735 struct avdp_t avdp; | 728 struct avdp_t avdp; |
736 | 729 |
737 | 730 if(!UDFGetAVDP(device, &avdp)) |
738 if(!UDFGetAVDP(device, &avdp)) { | |
739 return 0; | 731 return 0; |
740 } | |
741 | 732 |
742 /* Main volume descriptor */ | 733 /* Main volume descriptor */ |
743 MVDS_location = avdp.mvds.location; | 734 MVDS_location = avdp.mvds.location; |
744 MVDS_length = avdp.mvds.length; | 735 MVDS_length = avdp.mvds.length; |
745 | 736 |
765 part->valid = ( partnum == part->Number ); | 756 part->valid = ( partnum == part->Number ); |
766 } else if( ( TagID == 6 ) && ( !volvalid ) ) { | 757 } else if( ( TagID == 6 ) && ( !volvalid ) ) { |
767 /* Logical Volume Descriptor */ | 758 /* Logical Volume Descriptor */ |
768 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { | 759 if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { |
769 /* TODO: sector size wrong! */ | 760 /* TODO: sector size wrong! */ |
770 } else { | 761 } else |
771 volvalid = 1; | 762 volvalid = 1; |
772 } | |
773 } | 763 } |
774 | 764 |
775 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) | 765 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) |
776 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) | 766 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
777 && ( ( !part->valid ) || ( !volvalid ) ) ); | 767 && ( ( !part->valid ) || ( !volvalid ) ) ); |
802 | 792 |
803 *filesize = 0; | 793 *filesize = 0; |
804 tokenline[0] = '\0'; | 794 tokenline[0] = '\0'; |
805 strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1); | 795 strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1); |
806 | 796 |
807 | |
808 if(!(GetUDFCache(device, PartitionCache, 0, &partition) && | 797 if(!(GetUDFCache(device, PartitionCache, 0, &partition) && |
809 GetUDFCache(device, RootICBCache, 0, &RootICB))) { | 798 GetUDFCache(device, RootICBCache, 0, &RootICB))) { |
810 /* Find partition, 0 is the standard location for DVD Video.*/ | 799 /* Find partition, 0 is the standard location for DVD Video.*/ |
811 if( !UDFFindPartition( device, 0, &partition ) ) return 0; | 800 if( !UDFFindPartition( device, 0, &partition ) ) return 0; |
812 SetUDFCache(device, PartitionCache, 0, &partition); | 801 SetUDFCache(device, PartitionCache, 0, &partition); |
813 | 802 |
814 /* Find root dir ICB */ | 803 /* Find root dir ICB */ |
815 lbnum = partition.Start; | 804 lbnum = partition.Start; |
816 do { | 805 do { |
817 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) { | 806 if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) |
818 TagID = 0; | 807 TagID = 0; |
819 } else { | 808 else |
820 UDFDescriptor( LogBlock, &TagID ); | 809 UDFDescriptor( LogBlock, &TagID ); |
821 } | |
822 | 810 |
823 /* File Set Descriptor */ | 811 /* File Set Descriptor */ |
824 if( TagID == 256 ) { /* File Set Descriptor */ | 812 if( TagID == 256 ) /* File Set Descriptor */ |
825 UDFLongAD( &LogBlock[ 400 ], &RootICB ); | 813 UDFLongAD( &LogBlock[ 400 ], &RootICB ); |
826 } | |
827 } while( ( lbnum < partition.Start + partition.Length ) | 814 } while( ( lbnum < partition.Start + partition.Length ) |
828 && ( TagID != 8 ) && ( TagID != 256 ) ); | 815 && ( TagID != 8 ) && ( TagID != 256 ) ); |
829 | 816 |
830 /* Sanity checks. */ | 817 /* Sanity checks. */ |
831 if( TagID != 256 ) return 0; | 818 if( TagID != 256 ) return 0; |
839 | 826 |
840 { | 827 { |
841 int cache_file_info = 0; | 828 int cache_file_info = 0; |
842 /* Tokenize filepath */ | 829 /* Tokenize filepath */ |
843 token = strtok(tokenline, "/"); | 830 token = strtok(tokenline, "/"); |
844 | |
845 while( token != NULL ) { | 831 while( token != NULL ) { |
846 | |
847 if( !UDFScanDir( device, File, token, &partition, &ICB, | 832 if( !UDFScanDir( device, File, token, &partition, &ICB, |
848 cache_file_info)) { | 833 cache_file_info)) |
849 return 0; | 834 return 0; |
850 } | 835 if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) |
851 if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) { | 836 return 0; |
852 return 0; | 837 if(!strcmp(token, "VIDEO_TS")) |
853 } | |
854 if(!strcmp(token, "VIDEO_TS")) { | |
855 cache_file_info = 1; | 838 cache_file_info = 1; |
856 } | 839 token = strtok( NULL, "/" ); |
857 token = strtok( NULL, "/" ); | |
858 } | 840 } |
859 } | 841 } |
860 | 842 |
861 /* Sanity check. */ | 843 /* Sanity check. */ |
862 if( File.Partition != 0 ) return 0; | 844 if( File.Partition != 0 ) return 0; |
863 | |
864 *filesize = File.Length; | 845 *filesize = File.Length; |
865 /* Hack to not return partition.Start for empty files. */ | 846 /* Hack to not return partition.Start for empty files. */ |
866 if( !File.Location ) | 847 if( !File.Location ) |
867 return 0; | 848 return 0; |
868 else | 849 else |
888 int desc_found = 0; | 869 int desc_found = 0; |
889 /* Find Anchor */ | 870 /* Find Anchor */ |
890 lastsector = 0; | 871 lastsector = 0; |
891 lbnum = 256; /* Try #1, prime anchor */ | 872 lbnum = 256; /* Try #1, prime anchor */ |
892 terminate = 0; | 873 terminate = 0; |
893 if(bufsize < DVD_VIDEO_LB_LEN) { | 874 if(bufsize < DVD_VIDEO_LB_LEN) |
894 return 0; | 875 return 0; |
895 } | 876 |
896 | 877 if(!UDFGetAVDP(device, &avdp)) |
897 if(!UDFGetAVDP(device, &avdp)) { | 878 return 0; |
898 return 0; | |
899 } | |
900 | 879 |
901 /* Main volume descriptor */ | 880 /* Main volume descriptor */ |
902 MVDS_location = avdp.mvds.location; | 881 MVDS_location = avdp.mvds.location; |
903 MVDS_length = avdp.mvds.length; | 882 MVDS_length = avdp.mvds.length; |
904 | |
905 i = 1; | 883 i = 1; |
906 do { | 884 do { |
907 /* Find Descriptor */ | 885 /* Find Descriptor */ |
908 lbnum = MVDS_location; | 886 lbnum = MVDS_location; |
909 do { | 887 do { |
910 | 888 if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) |
911 if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) { | 889 TagID = 0; |
912 TagID = 0; | 890 else |
913 } else { | 891 UDFDescriptor( descriptor, &TagID ); |
914 UDFDescriptor( descriptor, &TagID ); | 892 if( (TagID == id) && ( !desc_found ) ) |
915 } | 893 /* Descriptor */ |
916 | 894 desc_found = 1; |
917 if( (TagID == id) && ( !desc_found ) ) { | |
918 /* Descriptor */ | |
919 desc_found = 1; | |
920 } | |
921 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) | 895 } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) |
922 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) | 896 / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) |
923 && ( !desc_found) ); | 897 && ( !desc_found) ); |
924 | 898 |
925 if( !desc_found ) { | 899 if( !desc_found ) { |
926 /* Backup volume descriptor */ | 900 /* Backup volume descriptor */ |
927 MVDS_location = avdp.rvds.location; | 901 MVDS_location = avdp.rvds.location; |
928 MVDS_length = avdp.rvds.length; | 902 MVDS_length = avdp.rvds.length; |
929 } | 903 } |
930 } while( i-- && ( !desc_found ) ); | 904 } while( i-- && ( !desc_found ) ); |
931 | 905 |
932 return desc_found; | 906 return desc_found; |
933 } | 907 } |
934 | 908 |
935 | 909 |
936 static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd) | 910 static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd) |
937 { | 911 { |
938 uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048]; | 912 uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048]; |
939 uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048); | 913 uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048); |
940 | 914 if(GetUDFCache(device, PVDCache, 0, pvd)) |
941 if(GetUDFCache(device, PVDCache, 0, pvd)) { | |
942 return 1; | 915 return 1; |
943 } | 916 |
944 | 917 if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) |
945 if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) { | 918 return 0; |
946 return 0; | 919 |
947 } | |
948 | |
949 memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32); | 920 memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32); |
950 memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128); | 921 memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128); |
951 SetUDFCache(device, PVDCache, 0, pvd); | 922 SetUDFCache(device, PVDCache, 0, pvd); |
952 | |
953 return 1; | 923 return 1; |
954 } | 924 } |
955 | 925 |
956 /** | 926 /** |
957 * Gets the Volume Identifier string, in 8bit unicode (latin-1) | 927 * Gets the Volume Identifier string, in 8bit unicode (latin-1) |
964 { | 934 { |
965 struct pvd_t pvd; | 935 struct pvd_t pvd; |
966 unsigned int volid_len; | 936 unsigned int volid_len; |
967 | 937 |
968 /* get primary volume descriptor */ | 938 /* get primary volume descriptor */ |
969 if(!UDFGetPVD(device, &pvd)) { | 939 if(!UDFGetPVD(device, &pvd)) |
970 return 0; | 940 return 0; |
971 } | |
972 | 941 |
973 volid_len = pvd.VolumeIdentifier[31]; | 942 volid_len = pvd.VolumeIdentifier[31]; |
974 if(volid_len > 31) { | 943 if(volid_len > 31) |
975 /* this field is only 32 bytes something is wrong */ | 944 /* this field is only 32 bytes something is wrong */ |
976 volid_len = 31; | 945 volid_len = 31; |
977 } | 946 if(volid_size > volid_len) |
978 if(volid_size > volid_len) { | |
979 volid_size = volid_len; | 947 volid_size = volid_len; |
980 } | |
981 Unicodedecode(pvd.VolumeIdentifier, volid_size, volid); | 948 Unicodedecode(pvd.VolumeIdentifier, volid_size, volid); |
982 | |
983 return volid_len; | 949 return volid_len; |
984 } | 950 } |
985 | 951 |
986 /** | 952 /** |
987 * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) | 953 * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) |
996 unsigned int volsetid_size) | 962 unsigned int volsetid_size) |
997 { | 963 { |
998 struct pvd_t pvd; | 964 struct pvd_t pvd; |
999 | 965 |
1000 /* get primary volume descriptor */ | 966 /* get primary volume descriptor */ |
1001 if(!UDFGetPVD(device, &pvd)) { | 967 if(!UDFGetPVD(device, &pvd)) |
1002 return 0; | 968 return 0; |
1003 } | 969 |
1004 | 970 |
1005 | 971 if(volsetid_size > 128) |
1006 if(volsetid_size > 128) { | |
1007 volsetid_size = 128; | 972 volsetid_size = 128; |
1008 } | 973 |
1009 | |
1010 memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size); | 974 memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size); |
1011 | |
1012 return 128; | 975 return 128; |
1013 } | 976 } |