예제 #1
0
/**
 * Reads the volume descriptor and checks the parameters.  Returns 0 on OK, 1
 * on error.
 */
static int UDFLogVolume( uint8_t *data, struct Volume *vol)
{
  uint32_t MT_L, N_PM, volume;
  uint32_t ii, type, length, pos;
  struct PartitionMaps *maps;
  volume = GETN4(16);
  Unicodedecode(&data[84], 128, vol->VolumeDesc);
  vol->BlockSize = GETN4(212);  /* should be 2048 */
  memset((void *)&vol->FSD, 0, sizeof(struct AD));
  UDFLongAD(&data[248], &vol->FSD);
  //printf("File Set Descriptor: block: %d, part: %d\n", vol->FSD.Location, vol->FSD.Partition);
  MT_L = GETN4(264);    /* should be 6 */
  N_PM = GETN4(268);    /* should be 1 */
  vol->MapNum = N_PM;
  if ((N_PM >= 1) && (vol->Maps == NULL))
  {
	  vol->Maps = (struct PartitionMaps *)calloc(1, sizeof(struct PartitionMaps) * N_PM);
  }
  UDFExtentAD( &data[432], &vol->Length, &vol->Location);
  //printf("location: %d, length: %d\n", vol->Location, vol->Length);
  pos = 440;
  for (ii = 0; ii < N_PM; ii++)
  {
	  maps = &vol->Maps[ii];
	  type = GETN1(pos);
	  length = GETN1(pos+1);
	  if (type == 1)
	  {
		  maps->MapType = UDF_TYPE1_MAP15;
		  maps->VolSequenNum = GETN2(pos+2);
		  maps->PartitionNum = GETN2(pos+4);
	  }
	  else if (type == 2)
	  {
		  struct EntityIdentifier ident;
		  uint32_t version;
		  UDFEntIdentifier(&data[pos+4], &ident);
		  version = ((uint16_t)ident.indetifierSuffix[1] << 8) | (uint16_t)(ident.indetifierSuffix[0]);
		  //printf("identifier: '%s', version: %04x\n", ident.identifier, version);
		  if (strncmp(ident.identifier, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL)) == 0)
		  {
			  if (version < 0x0200)
				  maps->MapType = UDF_VIRTUAL_MAP15;
			  else
				  maps->MapType = UDF_VIRTUAL_MAP20;
		  }
		  else if (strncmp(ident.identifier, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE)) == 0)
		  {
			  maps->MapType = UDF_SPARABLE_MAP15;
		  }
		  else if (strncmp(ident.identifier, UDF_ID_METADATA, strlen(UDF_ID_METADATA)) == 0)
		  {
			  maps->MapType = UDF_METADATA_MAP25;
		  }

		  maps->VolSequenNum = GETN2(pos+36);
		  maps->PartitionNum = GETN2(pos+38);
		  maps->mdata.meta_file_loc = GETN4(pos+40);
		  maps->mdata.mirror_file_loc = GETN4(pos+44);
		  maps->mdata.bitmap_file_loc = GETN4(pos+48);
		  maps->mdata.alloc_unit_size = GETN4(pos+52);
		  maps->mdata.alig_unit_size = GETN2(pos+56);
		  maps->mdata.flags = data[pos+58];
		  //printf("meta_loc: %u, mirr_loc: %u, bit_loc: %u, alloc_unit: %u, alig_unit: %hu, flags: %hhu\n", maps->mdata.meta_file_loc, maps->mdata.mirror_file_loc, maps->mdata.bitmap_file_loc, maps->mdata.alloc_unit_size, maps->mdata.alig_unit_size, maps->mdata.flags);
	  }
	  //printf("Volume Sequence Number: %hu, Partition Number: %hu\n", maps->VolSequenNum, maps->PartitionNum);
	  pos += length;
  }
  //printf("volume: %d, MT_L: %d, N_PM: %d\n", volume, MT_L, N_PM);
  if (vol->BlockSize != DVD_VIDEO_LB_LEN) return 1;
  return 0;
}
예제 #2
0
static int UDFGetAVDP( dvd_reader_t *device,
                       struct avdp_t *avdp)
{
  uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ];
  uint8_t *Anchor = (uint8_t *)(((uintptr_t)Anchor_base & ~((uintptr_t)2047)) + 2048);
  uint32_t lbnum, MVDS_location, MVDS_length;
  uint16_t TagID;
  uint32_t lastsector;
  int terminate;
  struct avdp_t;

  if(GetUDFCache(device, AVDPCache, 0, avdp))
    return 1;

  /* Find Anchor */
  lastsector = 0;
  lbnum = 256;   /* Try #1, prime anchor */
  terminate = 0;

  for(;;) {
    if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
      UDFDescriptor( Anchor, &TagID );
    } else {
      TagID = 0;
    }
    if (TagID != 2) {
      /* Not an anchor */
      if( terminate ) return 0; /* Final try failed */

      if( lastsector ) {
        /* We already found the last sector.  Try #3, alternative
         * backup anchor.  If that fails, don't try again.
         */
        lbnum = lastsector;
        terminate = 1;
      } else {
        /* TODO: Find last sector of the disc (this is optional). */
        if( lastsector )
          /* Try #2, backup anchor */
          lbnum = lastsector - 256;
        else
          /* Unable to find last sector */
          return 0;
      }
    } else
      /* It's an anchor! We can leave */
      break;
  }
  /* Main volume descriptor */
  UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
  avdp->mvds.location = MVDS_location;
  avdp->mvds.length = MVDS_length;

  /* Backup volume descriptor */
  UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
  avdp->rvds.location = MVDS_location;
  avdp->rvds.length = MVDS_length;

  SetUDFCache(device, AVDPCache, 0, avdp);

  return 1;
}
예제 #3
0
파일: dvd_udf.c 프로젝트: Allba/showtime
static int UDFGetAVDP( dvd_reader_t *device,
                       struct avdp_t *avdp)
{
  uint8_t *Anchor;
  uint32_t lbnum, MVDS_location, MVDS_length;
  uint16_t TagID;
  uint32_t lastsector;
  int terminate;
  struct avdp_t; 
  
  if(GetUDFCache(device, AVDPCache, 0, avdp)) {
    return 1;
  }
  
  /* Find Anchor */
  lastsector = 0;
  lbnum = 256;   /* Try #1, prime anchor */
  terminate = 0;
  
  Anchor = dvdalign_lbmalloc(device, 1);
  if(!Anchor) {
    return 0;
  }
  for(;;) {
    if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) {
      UDFDescriptor( Anchor, &TagID );
    } else {
      TagID = 0;
    }
    if (TagID != 2) {
      /* Not an anchor */
      if( terminate ) {
        dvdalign_lbfree(device, Anchor);
        errno = EMEDIUMTYPE;
        return 0; /* Final try failed */
      } 
      
      if( lastsector ) {
        /* We already found the last sector.  Try #3, alternative
         * backup anchor.  If that fails, don't try again.
         */
        lbnum = lastsector;
        terminate = 1;
      } else {
        /* TODO: Find last sector of the disc (this is optional). */
        if( lastsector ) {
          /* Try #2, backup anchor */
          lbnum = lastsector - 256;
        } else {
          /* Unable to find last sector */
          dvdalign_lbfree(device, Anchor);
          errno = EMEDIUMTYPE;
          return 0;
        }
      }
    } else {
      /* It's an anchor! We can leave */
      break;
    }
  }
  /* Main volume descriptor */
  UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location );
  avdp->mvds.location = MVDS_location;
  avdp->mvds.length = MVDS_length;
  
  /* Backup volume descriptor */
  UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location );
  avdp->rvds.location = MVDS_location;
  avdp->rvds.length = MVDS_length;
  
  SetUDFCache(device, AVDPCache, 0, avdp);
  
  dvdalign_lbfree(device, Anchor);
  return 1;
}