Esempio n. 1
0
static int UDFFileEntry( uint8_t *data, uint8_t *FileType,
                         struct Partition *partition, struct AD *ad )
{
  uint16_t flags;
  uint32_t L_EA, L_AD;
  unsigned int p;

  UDFICB( &data[ 16 ], FileType, &flags );

  /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */
  ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */
  ad->Flags = 0;
  ad->Location = 0; /* what should we put here?  */
  ad->Partition = partition->Number; /* use number of current partition */

  L_EA = GETN4( 168 );
  L_AD = GETN4( 172 );

  if (176 + L_EA + L_AD > DVD_VIDEO_LB_LEN)
    return 0;

  p = 176 + L_EA;
  while( p < 176 + L_EA + L_AD ) {
    switch( flags & 0x0007 ) {
    case 0:
      UDFShortAD( &data[ p ], ad, partition );
      p += 8;
      break;
    case 1:
      UDFLongAD( &data[ p ], ad );
      p += 16;
      break;
    case 2:
      UDFExtAD( &data[ p ], ad );
      p += 20;
      break;
    case 3:
      switch( L_AD ) {
      case 8:
        UDFShortAD( &data[ p ], ad, partition );
        break;
      case 16:
        UDFLongAD( &data[ p ], ad );
        break;
      case 20:
        UDFExtAD( &data[ p ], ad );
        break;
      }
      p += L_AD;
      break;
    default:
      p += L_AD;
      break;
    }
  }
  return 0;
}
Esempio n. 2
0
static int UDFAD( quint8 *ptr, quint32 len, struct FileAD *fad)
{
  struct AD *ad;

  if (fad->num_AD  >= UDF_MAX_AD_CHAINS)
    return len;

  ad =  &fad->AD_chain[fad->num_AD];
  ad->Partition = fad->Partition;
  ad->Flags     = 0;
  fad->num_AD++;

  switch( fad->Flags & 0x0007 ) {
    case 0:
      UDFShortAD( ptr, ad );
      return 8;
    case 1:
      UDFLongAD( ptr, ad );
      return 16;
    case 2:
      UDFExtAD( ptr, ad );
      return 20;
    case 3:
      switch( len ) {
        case 8:
          UDFShortAD( ptr, ad );
          break;
        case 16:
          UDFLongAD( ptr,  ad );
          break;
        case 20:
          UDFExtAD( ptr, ad );
          break;
      }
      break;
    default:
      break;
  }

  return len;
}
Esempio n. 3
0
static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics,
                              char *FileName, struct AD *FileICB )
{
  uint8_t L_FI;
  uint16_t L_IU;

  *FileCharacteristics = GETN1(18);
  L_FI = GETN1(19);
  UDFLongAD(&data[20], FileICB);
  L_IU = GETN2(36);
  if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName);
  else FileName[0] = '\0';
  return 4 * ((38 + L_FI + L_IU + 3) / 4);
}
Esempio n. 4
0
static int UDFExtFileEntry(uint8_t *data, struct Partition *partition, struct AD *ad)
{
	int nRet = -1;
	uint8_t FileType;
	uint16_t TagID;
	uint16_t flags;
	uint32_t L_EA, L_AD;
	unsigned int p;

	UDFDescriptor( data, &TagID );
	if (TagID != 266)
	{
		//printf("Not ExtFileEntry!!!\n");
		return nRet;
	}
	UDFICB( &data[ 16 ], &FileType, &flags );

	ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */
	ad->Flags = 0;
	ad->Location = 0; /* what should we put here?  */
	ad->Partition = partition->Number; /* use number of current partition */

	L_EA = GETN4( 208 );
	L_AD = GETN4( 212 );

	if (216 + L_EA + L_AD > DVD_VIDEO_LB_LEN)
		return nRet;

	p = 216 + L_EA;
	while( p < 216 + L_EA + L_AD ) {
		switch( flags & 0x0007 ) {
			case 0:
				UDFShortAD( &data[ p ], ad, partition );
				p += 8;
				break;
			case 1:
				UDFLongAD( &data[ p ], ad );
				p += 16;
				break;
			default:
				p += L_AD;
				break;
		}
	}

	return nRet;
}
Esempio n. 5
0
uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
                      uint32_t *filesize )
{
  uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
  uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048);
  uint32_t lbnum;
  uint16_t TagID;
  struct Partition partition;
  struct AD RootICB, File, ICB;
  char tokenline[ MAX_UDF_FILE_NAME_LEN ];
  char *token;
  uint8_t filetype;

  *filesize = 0;
  tokenline[0] = '\0';
  strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1);
  memset(&ICB, 0, sizeof(ICB));

  if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
       GetUDFCache(device, RootICBCache, 0, &RootICB))) {
    /* Find partition, 0 is the standard location for DVD Video.*/
    if( !UDFFindPartition( device, 0, &partition ) ) return 0;
    SetUDFCache(device, PartitionCache, 0, &partition);

    /* Find root dir ICB */
    lbnum = partition.Start;
    do {
      if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 )
        TagID = 0;
      else
        UDFDescriptor( LogBlock, &TagID );

      /* File Set Descriptor */
      if( TagID == 256 )  /* File Set Descriptor */
        UDFLongAD( &LogBlock[ 400 ], &RootICB );
    } while( ( lbnum < partition.Start + partition.Length )
             && ( TagID != 8 ) && ( TagID != 256 ) );

    /* Sanity checks. */
    if( TagID != 256 )
      return 0;
    if( RootICB.Partition != 0 )
      return 0;
    SetUDFCache(device, RootICBCache, 0, &RootICB);
  }

  /* Find root dir */
  if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) )
    return 0;
  if( filetype != 4 )
    return 0;  /* Root dir should be dir */
  {
    int cache_file_info = 0;
    /* Tokenize filepath */
    token = strtok(tokenline, "/");

    while( token != NULL ) {
      if( !UDFScanDir( device, File, token, &partition, &ICB,
                       cache_file_info))
        return 0;
      if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) )
        return 0;
      if(!strcmp(token, "VIDEO_TS"))
        cache_file_info = 1;
      token = strtok( NULL, "/" );
    }
  }

  /* Sanity check. */
  if( File.Partition != 0 )
    return 0;
  *filesize = File.Length;
  /* Hack to not return partition.Start for empty files. */
  if( !File.Location )
    return 0;
  else
    return partition.Start + File.Location;
}
Esempio n. 6
0
static int UDFExtFileEntry( uint8_t *data, uint8_t *FileType,
                         struct Partition *partition, struct AD *ad )
{
  uint16_t flags;
  uint32_t L_EA, L_AD;
  unsigned int p;
  struct AD temp_ad;
  int is_init = 0;

  memset((void *)&temp_ad, 0, sizeof(struct AD));
  UDFICB( &data[ 16 ], FileType, &flags );

  /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */
  //ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */
  ad->Length = 0;
  ad->Flags = 0;
  ad->Location = 0; /* what should we put here?  */
  ad->Partition = partition->Number; /* use number of current partition */

  L_EA = GETN4( 208 );
  L_AD = GETN4( 212 );

  if (216 + L_EA + L_AD > DVD_VIDEO_LB_LEN)
    return 0;

  p = 216 + L_EA;
  while( p < 216 + L_EA + L_AD ) {
    switch( flags & 0x0007 ) {
    case 0:
      UDFShortAD( &data[ p ], &temp_ad, partition );
      p += 8;
      break;
    case 1:
      UDFLongAD( &data[ p ], &temp_ad );
      p += 16;
      break;
    case 2:
      UDFExtAD( &data[ p ], &temp_ad );
      p += 20;
      break;
    case 3:
      switch( L_AD ) {
      case 8:
        UDFShortAD( &data[ p ], &temp_ad, partition );
        break;
      case 16:
        UDFLongAD( &data[ p ], &temp_ad );
        break;
      case 20:
        UDFExtAD( &data[ p ], &temp_ad );
        break;
      }
      p += L_AD;
      break;
    default:
      p += L_AD;
      break;
    }
	if (is_init == 0)
	{
		memcpy((void *)ad, (void *)&temp_ad, sizeof(struct AD));
		is_init = 1;
	} else {
		// only update file size
		ad->Length += temp_ad.Length;
	}
  }
  return 0;
}
Esempio n. 7
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;
}
Esempio n. 8
0
uint32_t BDUDFDirFile( UDF_DIR *device, const char *filename)
{
  uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ];
  uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048);
  uint32_t lbnum;
  uint16_t TagID;
  struct Partition partition;
  struct AD RootICB, File, ICB;
  char tokenline[ MAX_UDF_FILE_NAME_LEN ];
  char *token;
  uint8_t filetype;

  tokenline[0] = '\0';
  strncat(tokenline, filename, MAX_UDF_FILE_NAME_LEN - 1);
  memset(&ICB, 0, sizeof(struct AD));
  memset(&File, 0, sizeof(struct AD));
  memset(&RootICB, 0, sizeof(struct AD));
  memset(&partition, 0, sizeof(struct Partition));

  if(!(GetBDUDFCache(device->udf_data, PartitionCache, 0, &partition) &&
       GetBDUDFCache(device->udf_data, RootICBCache, 0, &RootICB))) {
    /* Find partition, 0 is the standard location for DVD Video.*/
    if( !UDFFindPartition( device->udf_data, 0, &partition ) )
	{
		UDFFreePartition(&partition);
		return 0;
	}

    /* Find root dir ICB */
    //lbnum = partition.Start;
  lbnum = UDFGetBlock(&partition, partition.vol.FSD.Partition, partition.vol.FSD.Location);
    do {
      if( DVDReadLBUDF( device->udf_data, lbnum++, 1, LogBlock, 0 ) <= 0 )
        TagID = 0;
      else
        UDFDescriptor( LogBlock, &TagID );

      /* File Set Descriptor */
      if( TagID == 256 )  /* File Set Descriptor */
	  {
        UDFLongAD( &LogBlock[ 400 ], &RootICB );
		partition.Number = RootICB.Partition;
	  }
    } while( ( lbnum < partition.Start + partition.Length )
             && ( TagID != 8 ) && ( TagID != 256 ) );

    SetUDFCache(device->udf_data, PartitionCache, 0, &partition);

    /* Sanity checks. */
    if( TagID != 256 )
      return 0;
    //if( RootICB.Partition != 0 )
    //  return 0;
    SetUDFCache(device->udf_data, RootICBCache, 0, &RootICB);
  }

  /* Find root dir */
  if( !UDFMapICB( device->udf_data, RootICB, &filetype, &partition, &File ) )
    return 0;
  if( filetype != 4 )
    return 0;  /* Root dir should be dir */
  {
    /* Tokenize filepath */
    token = strtok(tokenline, "/");

    while( token != NULL ) {
      if( !UDFScanDir( device->udf_data, File, token, &partition, &ICB, 0) )
        return 0;
	  //printf("icb: part: %u, block: %u\n", ICB.Partition, ICB.Location);
      if( !UDFMapICB( device->udf_data, ICB, &filetype, &partition, &File ) )
        return 0;
	  //printf("file: part: %u, block: %u\n", File.Partition, File.Location);
      token = strtok( NULL, "/" );
    }
	if( UDFCacheDir( device, File, &partition, &ICB) )
	{
		return 1;
	}
  }

  return 0;
}
Esempio n. 9
0
uint32_t UDFFindFile( dvd_reader_t *device, char *filename,
                      uint32_t *filesize )
{
  uint8_t *LogBlock;
  uint32_t lbnum;
  uint16_t TagID;
  struct Partition partition;
  struct AD RootICB, File, ICB;
  char tokenline[ MAX_UDF_FILE_NAME_LEN ];
  char *token;
  uint8_t filetype;
  
  if(filesize) {
    *filesize = 0;
  }
  tokenline[0] = '\0';
  strcat( tokenline, filename );

    
  if(!(GetUDFCache(device, PartitionCache, 0, &partition) &&
       GetUDFCache(device, RootICBCache, 0, &RootICB))) {
    /* Find partition, 0 is the standard location for DVD Video.*/
    if( !UDFFindPartition( device, 0, &partition ) ) {
      return 0;
    }
    SetUDFCache(device, PartitionCache, 0, &partition);
    
    LogBlock = dvdalign_lbmalloc(device, 1);
    if(!LogBlock) {
      return 0;
    }
    /* Find root dir ICB */
    lbnum = partition.Start;
    do {
      if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) {
        TagID = 0;
      } else {
        UDFDescriptor( LogBlock, &TagID );
      }

      /* File Set Descriptor */
      if( TagID == 256 ) {  // File Set Descriptor
        UDFLongAD( &LogBlock[ 400 ], &RootICB );
      }
    } while( ( lbnum < partition.Start + partition.Length )
             && ( TagID != 8 ) && ( TagID != 256 ) );

    dvdalign_lbfree(device, LogBlock);
      
    /* Sanity checks. */
    if( TagID != 256 ) {
      return 0;
    }
    if( RootICB.Partition != 0 ) {
      return 0;
    }
    SetUDFCache(device, RootICBCache, 0, &RootICB);
  }

  /* Find root dir */
  if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) {
    return 0;
  }
  if( filetype != 4 ) {
    return 0;  /* Root dir should be dir */
  }
  {
    int cache_file_info = 0;
    /* Tokenize filepath */
    token = strtok(tokenline, "/");
    
    while( token != NULL ) {
      
      if( !UDFScanDir( device, File, token, &partition, &ICB,
                       cache_file_info)) {
        return 0;
      }
      if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) {
        return 0;
      }
      if(!strcmp(token, "VIDEO_TS")) {
        cache_file_info = 1;
      }
      token = strtok( NULL, "/" );
    }
  } 

  /* Sanity check. */
  if( File.Partition != 0 ) {
    return 0;
  }

  if(filesize) {
    *filesize = File.Length;
  }
  /* Hack to not return partition.Start for empty files. */
  if( !File.Location ) {
    return 0;
  } else {
    return partition.Start + File.Location;
  }
}