Пример #1
0
/*!
  Set "long" time in format used in ISO 9660 primary volume descriptor
  from a Unix time structure. timezone is given as an offset
  correction in minutes.
*/
void
iso9660_set_ltime_with_timezone(const struct tm *p_tm,
                                int time_zone,
                                /*out*/ iso9660_ltime_t *pvd_date)
{
  char *_pvd_date = (char *) pvd_date;

  memset (_pvd_date, (int) '0', 16);
  pvd_date->lt_gmtoff = (iso712_t) 0; /* Start out with time zone GMT. */

  if (!p_tm) return;

  snprintf(_pvd_date, 17,
           "%4.4d%2.2d%2.2d" "%2.2d%2.2d%2.2d" "%2.2d",
           p_tm->tm_year + 1900, p_tm->tm_mon + 1, p_tm->tm_mday,
           p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec,
           0 /* 1/100 secs */ );

  /* Set time zone in 15-minute interval encoding. */
  pvd_date->lt_gmtoff -= (time_zone / 15);
  if (pvd_date->lt_gmtoff < -48 ) {

    cdio_warn ("Converted ISO 9660 timezone %d is less than -48. Adjusted",
               (int) pvd_date->lt_gmtoff);
    pvd_date->lt_gmtoff = -48;
  } else if (pvd_date->lt_gmtoff > 52) {
    cdio_warn ("Converted ISO 9660 timezone %d is over 52. Adjusted",
               (int) pvd_date->lt_gmtoff);
    pvd_date->lt_gmtoff = 52;
  }
}
Пример #2
0
/*!
  Set time in format used in ISO 9660 directory index record
  from a Unix time structure. */
void
iso9660_set_dtime (const struct tm *p_tm, /*out*/ iso9660_dtime_t *p_idr_date)
{
  memset (p_idr_date, 0, 7);

  if (!p_tm) return;

  p_idr_date->dt_year   = p_tm->tm_year;
  p_idr_date->dt_month  = p_tm->tm_mon + 1;
  p_idr_date->dt_day    = p_tm->tm_mday;
  p_idr_date->dt_hour   = p_tm->tm_hour;
  p_idr_date->dt_minute = p_tm->tm_min;
  p_idr_date->dt_second = p_tm->tm_sec;

#ifdef HAVE_TM_GMTOFF
  /* The ISO 9660 timezone is in the range -48..+52 and each unit
     represents a 15-minute interval. */
  p_idr_date->dt_gmtoff = p_tm->tm_gmtoff / (15 * 60);

  if (p_tm->tm_isdst) p_idr_date->dt_gmtoff -= 4;

  if (p_idr_date->dt_gmtoff < -48 ) {
    
    cdio_warn ("Converted ISO 9660 timezone %d is less than -48. Adjusted", 
               p_idr_date->dt_gmtoff);
    p_idr_date->dt_gmtoff = -48;
  } else if (p_idr_date->dt_gmtoff > 52) {
    cdio_warn ("Converted ISO 9660 timezone %d is over 52. Adjusted", 
               p_idr_date->dt_gmtoff);
    p_idr_date->dt_gmtoff = 52;
  }
#else 
  p_idr_date->dt_gmtoff = 0;
#endif
}
Пример #3
0
/*!
  Set time in format used in ISO 9660 directory index record
  from a Unix time structure. timezone is given as an offset
  correction in minutes.
*/
void
iso9660_set_dtime_with_timezone (const struct tm *p_tm,
                                 int time_zone,
                                 /*out*/ iso9660_dtime_t *p_idr_date)
{
  memset (p_idr_date, 0, 7);

  if (!p_tm) return;

  p_idr_date->dt_year   = p_tm->tm_year;
  p_idr_date->dt_month  = p_tm->tm_mon + 1;
  p_idr_date->dt_day    = p_tm->tm_mday;
  p_idr_date->dt_hour   = p_tm->tm_hour;
  p_idr_date->dt_minute = p_tm->tm_min;
  p_idr_date->dt_second = p_tm->tm_sec;

  /* The ISO 9660 timezone is in the range -48..+52 and each unit
     represents a 15-minute interval. */
  p_idr_date->dt_gmtoff = time_zone / 15;

  if (p_idr_date->dt_gmtoff < -48 ) {

    cdio_warn ("Converted ISO 9660 timezone %d is less than -48. Adjusted",
               p_idr_date->dt_gmtoff);
    p_idr_date->dt_gmtoff = -48;
  } else if (p_idr_date->dt_gmtoff > 52) {
    cdio_warn ("Converted ISO 9660 timezone %d is over 52. Adjusted",
               p_idr_date->dt_gmtoff);
    p_idr_date->dt_gmtoff = 52;
  }
}
Пример #4
0
/*!
  Initialize CD device.
 */
bool
cdio_generic_init (void *user_data, int open_flags)
{
  generic_img_private_t *p_env = user_data;
  if (p_env->init) {
    cdio_warn ("init called more than once");
    return false;
  }

  p_env->fd = open (p_env->source_name, open_flags, 0);

  if (p_env->fd < 0)
    {
      cdio_warn ("open (%s): %s", p_env->source_name, strerror (errno));
      return false;
    }

  p_env->init = true;
  p_env->toc_init = false;
  p_env->cdtext  = NULL;
  p_env->scsi_tuple  = NULL;
  p_env->b_cdtext_error = false;
  p_env->u_joliet_level = 0;  /* Assume no Joliet extensions initally */
  return true;
}
Пример #5
0
/**
  Attempts to read up to count bytes from UDF directory entry
  p_udf_dirent into the buffer starting at buf. buf should be a
  multiple of UDF_BLOCKSIZE bytes. Reading continues after the point
  at which we last read or from the beginning the first time.

  If count is zero, read() returns zero and has no other results. If
  count is greater than SSIZE_MAX, the result is unspecified.

  It is the caller's responsibility to ensure that count is less
  than the number of blocks recorded via p_udf_dirent.

  If there is an error, cast the result to driver_return_code_t for 
  the specific error code.
*/
ssize_t
udf_read_block(const udf_dirent_t *p_udf_dirent, void * buf, size_t count)
{
  if (count == 0) return 0;
  else {
    driver_return_code_t ret;
    uint32_t i_max_size=0;
    udf_t *p_udf = p_udf_dirent->p_udf;
    lba_t i_lba = offset_to_lba(p_udf_dirent, p_udf->i_position, &i_lba, 
				&i_max_size);
    if (i_lba != CDIO_INVALID_LBA) {
      uint32_t i_max_blocks = CEILING(i_max_size, UDF_BLOCKSIZE);
      if ( i_max_blocks < count ) {
	  cdio_warn("read count %u is larger than %u extent size.",
		  (unsigned int)count, i_max_blocks);
	  cdio_warn("read count truncated to %u", (unsigned int)count);
	  count = i_max_blocks;
      }
      ret = udf_read_sectors(p_udf, buf, i_lba, count);
      if (DRIVER_OP_SUCCESS == ret) {
	ssize_t i_read_len = MIN(i_max_size, count * UDF_BLOCKSIZE);
	p_udf->i_position += i_read_len;
	return i_read_len;
      }
      return ret;
    } else {
      return DRIVER_OP_ERROR;
    }
  }
}
Пример #6
0
bool
init_freebsd_cam (_img_private_t *p_env)
{
  char pass[100];
  
  p_env->cam=NULL;
  memset (&p_env->ccb, 0, sizeof(p_env->ccb));
  p_env->ccb.ccb_h.func_code = XPT_GDEVLIST;

  if (-1 == p_env->gen.fd) 
    p_env->gen.fd = open (p_env->device, O_RDONLY, 0);

  if (p_env->gen.fd < 0)
    {
      cdio_warn ("open (%s): %s", p_env->device, strerror (errno));
      return false;
    }

  (void)ioctl(p_env->gen.fd, CDIOCALLOW);

  if (ioctl (p_env->gen.fd, CAMGETPASSTHRU, &p_env->ccb) < 0)
    {
      cdio_warn ("open: %s", strerror (errno));
      return false;
    }
  sprintf (pass,"/dev/%.15s%u",
	   p_env->ccb.cgdl.periph_name,
	   p_env->ccb.cgdl.unit_number);
  p_env->cam = cam_open_pass (pass,O_RDWR,NULL);
  if (!p_env->cam) return false;
  
  p_env->gen.init   = true;
  p_env->b_cam_init = true;
  return true;
}
Пример #7
0
static access_mode_t 
str_to_access_mode_win32(const char *psz_access_mode) 
{
  const access_mode_t default_access_mode = 
    WIN_NT ? _AM_IOCTL : _AM_ASPI;

  if (NULL==psz_access_mode) return default_access_mode;
  
  if (!strcmp(psz_access_mode, "ioctl"))
    return _AM_IOCTL;
  else if (!strcmp(psz_access_mode, "ASPI")) {
#ifdef _XBOX
    cdio_warn ("XBOX doesn't support access type: %s. Default used instead.", 
	       psz_access_mode);
    return default_access_mode;
#else 
    return _AM_ASPI;
#endif    
  } else if (!strcmp(psz_access_mode, "MMC_RDWR")) {
    return _AM_MMC_RDWR;
  } else if (!strcmp(psz_access_mode, "MMC_RDWR_EXCL")) {
    return _AM_MMC_RDWR_EXCL;
  } else {
    cdio_warn ("unknown access type: %s. Default used instead.", 
	       psz_access_mode);
    return default_access_mode;
  }
}
Пример #8
0
/* Adjust the p_iso's i_datastart, i_byte_offset and i_framesize
   based on whether we find a frame header or not.
*/
static void
adjust_fuzzy_pvd( iso9660_t *p_iso )
{
  long int i_byte_offset;

  if (!p_iso) return;

  i_byte_offset = (ISO_PVD_SECTOR * p_iso->i_framesize)
    + p_iso->i_fuzzy_offset + p_iso->i_datastart;

  /* If we have a raw 2352-byte frame then we should expect to see a sync
     frame and a header.
   */
  if (CDIO_CD_FRAMESIZE_RAW == p_iso->i_framesize) {
    char buf[CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE];

    i_byte_offset -= CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE;

    if ( DRIVER_OP_SUCCESS != cdio_stream_seek (p_iso->stream, i_byte_offset,
						SEEK_SET) )
      return;
    if (sizeof(buf) == cdio_stream_read (p_iso->stream, buf, sizeof(buf), 1)) {
      /* Does the sector frame header suggest Mode 1 format? */
      if (!memcmp(CDIO_SECTOR_SYNC_HEADER, buf+CDIO_CD_SUBHEADER_SIZE,
		  CDIO_CD_SYNC_SIZE)) {
	if (buf[14+CDIO_CD_SUBHEADER_SIZE] != 0x16) {
	  cdio_warn ("Expecting the PVD sector header MSF to be 0x16, is: %x",
		     buf[14]);
	}
	if (buf[15+CDIO_CD_SUBHEADER_SIZE] != 0x1) {
	  cdio_warn ("Expecting the PVD sector mode to be Mode 1 is: %x",
		     buf[15]);
	}
	p_iso->b_mode2 = nope;
	p_iso->b_xa = nope;
      } else if (!memcmp(CDIO_SECTOR_SYNC_HEADER, buf, CDIO_CD_SYNC_SIZE)) {
	/* Frame header indicates Mode 2 Form 1*/
	if (buf[14] != 0x16) {
	  cdio_warn ("Expecting the PVD sector header MSF to be 0x16, is: %x",
		     buf[14]);
	}
	if (buf[15] != 0x2) {
	  cdio_warn ("Expecting the PVD sector mode to be Mode 2 is: %x",
		     buf[15]);
	}
	p_iso->b_mode2 = yep;
	/* Do do: check Mode 2 Form 2? */
      } else {
	  /* Has no frame header */
	  p_iso->i_framesize = M2RAW_SECTOR_SIZE;
	  p_iso->i_fuzzy_offset = (CDIO_CD_FRAMESIZE_RAW - M2RAW_SECTOR_SIZE)
	    * ISO_PVD_SECTOR + p_iso->i_fuzzy_offset + p_iso->i_datastart;
	  p_iso->i_datastart = 0;
	}
    }
  }


}
Пример #9
0
/*!
  Run a SCSI MMC command. 
 
  p_user_data   internal CD structure.
  i_timeout_ms  time in milliseconds we will wait for the command
                to complete. If this value is -1, use the default 
		time-out value.
  i_cdb	        Size of p_cdb
  p_cdb	        CDB bytes. 
  e_direction	direction the transfer is to go.
  i_buf	        Size of buffer
  p_buf	        Buffer for data, both sending and receiving

  Return 0 if no error.
 */
int
run_mmc_cmd_freebsd_cam( const void *p_user_data, unsigned int i_timeout_ms,
			 unsigned int i_cdb, const mmc_cdb_t *p_cdb, 
			 cdio_mmc_direction_t e_direction, 
			 unsigned int i_buf, /*in/out*/ void *p_buf )
{
  const _img_private_t *p_env = p_user_data;
  int   i_status;
  int direction = CAM_DEV_QFRZDIS;
  union ccb ccb;

  if (!p_env || !p_env->cam) return -2;
    
  memset(&ccb, 0, sizeof(ccb));

  ccb.ccb_h.path_id    = p_env->cam->path_id;
  ccb.ccb_h.target_id  = p_env->cam->target_id;
  ccb.ccb_h.target_lun = p_env->cam->target_lun;
  ccb.ccb_h.timeout    = i_timeout_ms;

  if (!i_buf)
    direction |= CAM_DIR_NONE;
  else
    direction |= (e_direction == SCSI_MMC_DATA_READ)?CAM_DIR_IN : CAM_DIR_OUT;

 
   memcpy(ccb.csio.cdb_io.cdb_bytes, p_cdb->field, i_cdb);
   ccb.csio.cdb_len =
     mmc_get_cmd_len(ccb.csio.cdb_io.cdb_bytes[0]);
   
  cam_fill_csio (&(ccb.csio), 1, NULL, 
		 direction | CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, p_buf, i_buf, 
 		 sizeof(ccb.csio.sense_data), ccb.csio.cdb_len, 30*1000);

  if (cam_send_ccb(p_env->cam, &ccb) < 0)
    {
      cdio_warn ("transport failed: %s", strerror(errno));
      return -1;
    }
  if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
    {
      return 0;
    }
  errno = EIO;
  i_status = ERRCODE(((unsigned char *)&ccb.csio.sense_data));
  if (i_status == 0)
    i_status = -1;
  else
    CREAM_ON_ERRNO(((unsigned char *)&ccb.csio.sense_data));
  cdio_warn ("transport failed: %d", i_status);
  return i_status;
}
Пример #10
0
/*!
  Return a string containing the default CD device if none is specified.
  if CdIo is NULL (we haven't initialized a specific device driver),
  then find a suitable one and return the default device for that.

  NULL is returned if we couldn't get a default device.
*/
char *
cdio_get_default_device_os2(void)
{
#ifdef HAVE_OS2_CDROM
  struct {
    USHORT us_drive_count;
    USHORT us_drive_first;
  } s_drive_letters;

  HFILE h_cd2;
  ULONG ul_action;
  ULONG ul_param_len;
  ULONG ul_data_len;
  char  sz_drive_str[ 3 ] = "X:";
  ULONG rc;

  rc = DosOpen((PSZ)"CD-ROM2$", &h_cd2, &ul_action, 0, FILE_NORMAL,
               OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
               OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE,
               NULL );

  if( rc )
  {
    cdio_warn("cdio_get_default_device_os2 : DosOpen(CD-ROM2$) = %ld\n", rc );

    return NULL;
  }

  rc = DosDevIOCtl(
          h_cd2, IOCTL_CDROMDISK2, CDROMDISK2_DRIVELETTERS,
          NULL, 0, &ul_param_len,
          &s_drive_letters, sizeof( s_drive_letters ), &ul_data_len );

  DosClose( h_cd2 );

  if( rc )
  {
    cdio_warn("cdio_get_default_device_os2 : DosDevIOCtl(DRIVELETTERS) = 0x%lx\n", rc );

    return NULL;
  }

  if( s_drive_letters.us_drive_count == 0 )
    return NULL;

  sz_drive_str[0] = 'A' + s_drive_letters.us_drive_first;

  return strdup( sz_drive_str );
#else
  return NULL;
#endif
}
Пример #11
0
/*!
  Set the volume of an audio CD.

  @param p_cdio the CD object to be acted upon.

*/
static driver_return_code_t
audio_set_volume_os2 ( void *p_user_data, cdio_audio_volume_t *p_volume)
{
  _img_private_t *p_env = p_user_data;

  struct {
    UCHAR auch_sign[4];
  } s_param = {{'C', 'D', '0', '1'}};

  struct {
    struct {
      BYTE  uc_in_ch;
      BYTE  uc_vol;
    } as_out_ch[4];
  } s_data;

  ULONG ul_param_len;
  ULONG ul_data_len;
  ULONG rc;
  int   i;

  /* first retrive current input ch. */
  rc = DosDevIOCtl(
          p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_GETCHANNEL,
          &s_param, sizeof( s_param ), &ul_param_len,
          &s_data, sizeof( s_data ), &ul_data_len );

  if( rc )
  {
    cdio_warn("audio_set_volume_os2 : DosDevIOCtl(GETCHANNEL) = 0x%lx\n", rc );

    return DRIVER_OP_ERROR;
  }

  for( i = 0; i < 4; i++ )
    s_data.as_out_ch[ i ].uc_vol = p_volume->level[ i ];

  /* now set volumes */
  rc = DosDevIOCtl(
          p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_SETCHANNELCTRL,
          &s_param, sizeof( s_param ), &ul_param_len,
          &s_data, sizeof( s_data ), &ul_data_len );

  if( rc )
  {
    cdio_warn("audio_set_volume_os2 : DosDevIOCtl(SETCHANNELCTRL) = 0x%lx\n", rc );

    return DRIVER_OP_ERROR;
  }

  return DRIVER_OP_SUCCESS;
}
Пример #12
0
CdioDataSource_t *
cdio_stdio_new(const char pathname[])
{
  CdioDataSource_t *new_obj = NULL;
  cdio_stream_io_functions funcs = { NULL, NULL, NULL, NULL, NULL, NULL };
  _UserData *ud = NULL;
  struct stat statbuf;
  
  if (stat (pathname, &statbuf) == -1) 
    {
      cdio_warn ("could not retrieve file info for `%s': %s", 
                 pathname, strerror (errno));
      return NULL;
    }

  ud = calloc (1, sizeof (_UserData));

  ud->pathname = strdup(pathname);
  ud->st_size  = statbuf.st_size; /* let's hope it doesn't change... */

  funcs.open   = _stdio_open;
  funcs.seek   = _stdio_seek;
  funcs.stat   = _stdio_stat;
  funcs.read   = _stdio_read;
  funcs.close  = _stdio_close;
  funcs.free   = _stdio_free;

  new_obj = cdio_stream_new(ud, &funcs);

  return new_obj;
}
Пример #13
0
static void cued_rip_epilogue(rip_context_t *rip)
{
    free(rip->mmcBuf);

#ifdef CUED_HAVE_PARANOIA

    if (ripUseParanoia) {
        rip->paranoiaCtlObj->read_audio = rip->save_read_paranoid;
        cdio_paranoia_free(rip->paranoiaRipObj);
        cdio_cddap_close_no_free_cdio(rip->paranoiaCtlObj);
    }

#endif // CUED_HAVE_PARANOIA

    if (rip->qSubChannelFileName && rip->qSubChannelFile != stdout) {
        fclose(rip->qSubChannelFile);
    }

    if (rip->crcFailure || rip->crcSuccess) {
        int totalCrcs = rip->crcSuccess + rip->crcFailure;

        if (rip->crcFailure * 100 / totalCrcs > 5) {
            cdio_warn("greater than 5 percent of Q sub-channel records failed CRC check (try --qsc-fq?)");
        }
        if (ripVerbose) {
            printf("progress: correctly read %d of %d Q sub-channel records\n", rip->crcSuccess, totalCrcs);
        }
    }
}
Пример #14
0
static bool
check_pvd (const iso9660_pvd_t *p_pvd) 
{
  if ( ISO_VD_PRIMARY != from_711(p_pvd->type) ) {
    cdio_warn ("unexpected PVD type %d", p_pvd->type);
    return false;
  }
  
  if (strncmp (p_pvd->id, ISO_STANDARD_ID, strlen (ISO_STANDARD_ID)))
    {
      cdio_warn ("unexpected ID encountered (expected `"
		ISO_STANDARD_ID "', got `%.5s'", p_pvd->id);
      return false;
    }
  return true;
}
Пример #15
0
/*!
  Set the key "arg" to "value" in source device.
*/
static int
set_arg_os2 (void *p_user_data, const char key[], const char value[])
{
  _img_private_t *p_env = p_user_data;

  if (!strcmp (key, "source"))
  {
    if (!value)
      return DRIVER_OP_ERROR;

    free (p_env->gen.source_name);
    p_env->gen.source_name = strdup (value);
  }
  else if (!strcmp (key, "access-mode"))
  {
    if (!strcmp(value, "OS2"))
      p_env->access_mode = _AM_OS2;
    else
      cdio_warn ("unknown access type: %s. ignored.", value);
  }
  else
    return DRIVER_OP_ERROR;

  return DRIVER_OP_SUCCESS;
}
Пример #16
0
/*!
  Return the media catalog number MCN.

  Note: string is malloc'd so caller should free() then returned
  string when done with it.

 */
char *
get_mcn_win32ioctl (const _img_private_t *p_env) {

  DWORD dw_bytes_returned;
  SUB_Q_MEDIA_CATALOG_NUMBER mcn;
  CDROM_SUB_Q_DATA_FORMAT q_data_format;
  
  memset( &mcn, 0, sizeof(mcn) );
  
  q_data_format.Format = CDIO_SUBCHANNEL_MEDIA_CATALOG;

  /* MSDN info on CDROM_SUB_Q_DATA_FORMAT says if Format is set to 
     get MCN, track must be set 0.
   */
  q_data_format.Track=0; 
  
  if( ! DeviceIoControl( p_env->h_device_handle,
		       IOCTL_CDROM_READ_Q_CHANNEL,
		       &q_data_format, sizeof(q_data_format), 
		       &mcn, sizeof(mcn),
		       &dw_bytes_returned, NULL ) ) {
    cdio_warn( "could not read Q Channel at track %d", 1);
  } else if (mcn.Mcval) 
    return strdup(mcn.MediaCatalog);
  return NULL;
}
Пример #17
0
static driver_return_code_t
audio_stop_os2 (void *p_user_data)
{
  _img_private_t *p_env = p_user_data;

  struct {
    UCHAR auch_sign[4];
  } s_param = {{'C', 'D', '0', '1'}};

  ULONG ul_param_len;
  ULONG ul_data_len;
  ULONG rc;

  rc = DosDevIOCtl(
          p_env->h_cd, IOCTL_CDROMAUDIO, CDROMAUDIO_STOPAUDIO,
          &s_param, sizeof( s_param ), &ul_param_len,
          NULL, 0, &ul_data_len );

  if( rc )
  {
    cdio_warn("audio_stop_os2 : DosDevIOCtl(STOPAUDIO) = 0x%lx\n", rc );

    return DRIVER_OP_ERROR;
  }

  return DRIVER_OP_SUCCESS;
}
Пример #18
0
/*!
  Seek to a position i_start and then read i_blocks. Number of blocks read is
  returned. One normally expects the return to be equal to i_blocks.
*/
driver_return_code_t
udf_read_sectors (const udf_t *p_udf, void *ptr, lsn_t i_start,
		 long i_blocks)
{
  driver_return_code_t ret;
  long i_read;
  off_t i_byte_offset;

  if (!p_udf) return 0;
  /* Without the cast, i_start * UDF_BLOCKSIZE may be evaluated as 32 bit */
  i_byte_offset = ((off_t)i_start) * UDF_BLOCKSIZE;
  /* Since we're using SEEK_SET, the value must be positive */
  if (i_byte_offset < 0) {
    if (sizeof(off_t) <= 4)	/* probably missing LFS */
      cdio_warn("Large File Support is required to access streams of 2 GB or more");
    return DRIVER_OP_BAD_PARAMETER;
  }

  if (p_udf->b_stream) {
    ret = cdio_stream_seek (p_udf->stream, i_byte_offset, SEEK_SET);
    if (DRIVER_OP_SUCCESS != ret) return ret;
    i_read = cdio_stream_read (p_udf->stream, ptr, UDF_BLOCKSIZE, i_blocks);
    if (i_read) return DRIVER_OP_SUCCESS;
    return DRIVER_OP_ERROR;
  } else {
    return cdio_read_data_sectors(p_udf->cdio, ptr, i_start, UDF_BLOCKSIZE,
				  i_blocks);
  }
}
Пример #19
0
/*!
  Close tray on CD-ROM.

  @param p_user_data the CD object to be acted upon.

*/
driver_return_code_t
close_tray_os2 (const char *psz_os2_drive)
{
#ifdef HAVE_OS2_CDROM
  struct {
    BYTE uc_cmd_info;
    BYTE uc_drive;
  } s_param;

  ULONG ul_param_len;
  ULONG ul_data_len;
  ULONG rc;

  s_param.uc_cmd_info = 3;
  s_param.uc_drive    = toupper(psz_os2_drive[0]) - 'A';

  rc = DosDevIOCtl(
             ( HFILE )-1, IOCTL_DISK, DSK_UNLOCKEJECTMEDIA,
             &s_param, sizeof( s_param ), &ul_param_len,
             NULL, 0, &ul_data_len );

  if( rc && rc != 99 /* device in use */ )
  {
    cdio_warn("close_tray_os2 : DosDevIOCtl(UNLOCKEJECTMEDIA) = 0x%lx\n", rc );

    return DRIVER_OP_ERROR;
  }

  return DRIVER_OP_SUCCESS;
#else
  return DRIVER_OP_UNSUPPORTED;
#endif /* HAVE_OS2_CDROM */
}
Пример #20
0
/*!
  Eject media in CD-ROM drive. Return DRIVER_OP_SUCCESS if successful, 
  DRIVER_OP_ERROR on error.
 */
driver_return_code_t
eject_media_freebsd_ioctl (_img_private_t *p_env) 
{
  _img_private_t *p_obj = p_env;
  int ret=DRIVER_OP_ERROR;

  if (ioctl(p_obj->gen.fd, CDIOCALLOW) == -1) {
    cdio_warn("ioctl(fd, CDIOCALLOW) failed: %s\n", strerror(errno));
  } else if (ioctl(p_obj->gen.fd, CDIOCEJECT) == -1) {
    cdio_warn("ioctl(CDIOCEJECT) failed: %s\n", strerror(errno));
  } else {
    ret=DRIVER_OP_SUCCESS;;
  }

  return ret;
}
Пример #21
0
/*!
  Eject media.
 */
static driver_return_code_t
eject_media_os2 (void *p_user_data)
{
  _img_private_t *p_env = p_user_data;

  struct {
    BYTE uc_cmd_info;
    BYTE uc_drive;
  } s_param;

  ULONG ul_param_len;
  ULONG ul_data_len;
  ULONG rc;

  s_param.uc_cmd_info = 2;
  s_param.uc_drive    = p_env->uc_drive;

  rc = DosDevIOCtl(
             ( HFILE )-1, IOCTL_DISK, DSK_UNLOCKEJECTMEDIA,
             &s_param, sizeof( s_param ), &ul_param_len,
             NULL, 0, &ul_data_len );

  if( rc )
  {
    cdio_warn("eject_media_os2 : DosDevIOCtl(UNLOCKEJECTMEDIA) = 0x%lx\n", rc );

    return DRIVER_OP_ERROR;
  }

  return DRIVER_OP_SUCCESS;
}
Пример #22
0
/*!
   Return the size of the CD in logical block address (LBA) units.
 */
static lsn_t
get_disc_last_lsn_os2 (void *p_user_data)
{
  _img_private_t *p_env = p_user_data;

  struct {
    UCHAR auch_sign[4];
  } s_param = {{'C', 'D', '0', '1'}};

  ULONG ul_data_volume_size;
  ULONG ul_param_len;
  ULONG ul_data_len;
  ULONG rc;

  rc = DosDevIOCtl(
          p_env->h_cd, IOCTL_CDROMDISK, CDROMDISK_GETVOLUMESIZE,
          &s_param, sizeof( s_param ), &ul_param_len,
          &ul_data_volume_size, sizeof( ul_data_volume_size ), &ul_data_len );

  if( rc )
  {
    cdio_warn("get_disc_last_lsn_os2 : DosDevIOCtl(GETVOLUMESIZE) = 0x%lx\n", rc );

    return CDIO_INVALID_LSN;
  }

  return ul_data_volume_size;
}
Пример #23
0
void
cdio_lsn_to_msf (lsn_t lsn, msf_t *msf)
{
  int m, s, f;

  cdio_assert (msf != 0);

  if ( lsn >= -CDIO_PREGAP_SECTORS ){
    m    = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_MIN;
    lsn -= m * CDIO_CD_FRAMES_PER_MIN;
    s    = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_SEC;
    lsn -= s * CDIO_CD_FRAMES_PER_SEC;
    f    = lsn + CDIO_PREGAP_SECTORS;
  } else {
    m    = (lsn + CDIO_CD_MAX_LSN)     / CDIO_CD_FRAMES_PER_MIN;
    lsn -= m * (CDIO_CD_FRAMES_PER_MIN);
    s    = (lsn+CDIO_CD_MAX_LSN)       / CDIO_CD_FRAMES_PER_SEC;
    lsn -= s * CDIO_CD_FRAMES_PER_SEC;
    f    = lsn + CDIO_CD_MAX_LSN;
  }

  if (m > 6) {
    cdio_warn ("number of minutes (%d) truncated to 99.", m);
    m = 6;
  }

  msf->m = cdio_to_bcd8 (m);
  msf->s = cdio_to_bcd8 (s);
  msf->f = cdio_to_bcd8 (f);
}
Пример #24
0
/*!
  Set the arg "key" with "value" in the source device.
  Currently "source" and "access-mode" are valid keys.
  "source" sets the source device in I/O operations 
  "access-mode" sets the the method of CD access 

  0 is returned if no error was found, and nonzero if there as an error.
*/
static int
_cdio_set_arg (void *env, const char key[], const char value[])
{
  _img_private_t *_obj = env;

  if (!strcmp (key, "source"))
    {
      if (!value)
	return -2;

      free (_obj->gen.source_name);
      
      _obj->gen.source_name = strdup (value);
    }
  else if (!strcmp (key, "access-mode"))
    {
      if (!strcmp(value, "IOCTL"))
	_obj->access_mode = _AM_IOCTL;
      else if (!strcmp(value, "READ_CD"))
	_obj->access_mode = _AM_READ_CD;
      else if (!strcmp(value, "READ_10"))
	_obj->access_mode = _AM_READ_10;
      else {
	cdio_warn ("unknown access type: %s. ignored.", value);
      }
    }
  else 
    return -1;

  return 0;
}
Пример #25
0
void * /* list of char* -- caller must free it */
iso9660_fs_readdir (const CdIo *cdio, const char pathname[], bool is_mode2)
{
  iso9660_stat_t stat;

  cdio_assert (cdio != NULL);
  cdio_assert (pathname != NULL);

  if (iso9660_fs_stat (cdio, pathname, &stat, is_mode2))
    return NULL;

  if (stat.type != _STAT_DIR)
    return NULL;

  {
    unsigned offset = 0;
    uint8_t *_dirbuf = NULL;
    CdioList *retval = _cdio_list_new ();

    if (stat.size != ISO_BLOCKSIZE * stat.secsize)
      {
	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		   (unsigned) stat.size, 
		   (unsigned long int) ISO_BLOCKSIZE * stat.secsize);
      }

    _dirbuf = _cdio_malloc (stat.secsize * ISO_BLOCKSIZE);

    if (is_mode2) {
      if (cdio_read_mode2_sectors (cdio, _dirbuf, stat.lsn, false, 
				   stat.secsize))
	cdio_assert_not_reached ();
    } else {
      if (cdio_read_mode1_sectors (cdio, _dirbuf, stat.lsn, false,
				   stat.secsize))
	cdio_assert_not_reached ();
    }

    while (offset < (stat.secsize * ISO_BLOCKSIZE))
      {
	const iso9660_dir_t *idr = (void *) &_dirbuf[offset];

	if (!iso9660_get_dir_len(idr))
	  {
	    offset++;
	    continue;
	  }

	_cdio_list_append (retval, _idr2name (idr));

	offset += iso9660_get_dir_len(idr);
      }

    cdio_assert (offset == (stat.secsize * ISO_BLOCKSIZE));

    free (_dirbuf);
    return retval;
  }
}
Пример #26
0
/*! 
  Read pathname (a directory) and return a list of iso9660_stat_t
  of the files inside that. The caller must free the returned result.
*/
CdioList_t * 
iso9660_ifs_readdir (iso9660_t *p_iso, const char pathname[])
{
  iso9660_stat_t *p_stat;

  if (!p_iso)    return NULL;
  if (!pathname) return NULL;

  p_stat = iso9660_ifs_stat (p_iso, pathname);
  if (!p_stat)   return NULL;

  if (p_stat->type != _STAT_DIR) {
    free(p_stat);
    return NULL;
  }

  {
    long int ret;
    unsigned offset = 0;
    uint8_t *_dirbuf = NULL;
    CdioList_t *retval = _cdio_list_new ();

    if (p_stat->size != ISO_BLOCKSIZE * p_stat->secsize)
      {
	cdio_warn ("bad size for ISO9660 directory (%ud) should be (%lu)!",
		   (unsigned int) p_stat->size, 
		   (unsigned long int) ISO_BLOCKSIZE * p_stat->secsize);
      }

    _dirbuf = _cdio_malloc (p_stat->secsize * ISO_BLOCKSIZE);

    ret = iso9660_iso_seek_read (p_iso, _dirbuf, p_stat->lsn, p_stat->secsize);
    if (ret != ISO_BLOCKSIZE*p_stat->secsize) return NULL;
    
    while (offset < (p_stat->secsize * ISO_BLOCKSIZE))
      {
	iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
	iso9660_stat_t *p_iso9660_stat;
	
	if (!iso9660_get_dir_len(p_iso9660_dir))
	  {
	    offset++;
	    continue;
	  }

	p_iso9660_stat = _iso9660_dir_to_statbuf(p_iso9660_dir, true,
						 p_iso->i_joliet_level);
	_cdio_list_append (retval, p_iso9660_stat);

	offset += iso9660_get_dir_len(p_iso9660_dir);
      }

    cdio_assert (offset == (p_stat->secsize * ISO_BLOCKSIZE));

    free (_dirbuf);
    free (p_stat);
    return retval;
  }
}
Пример #27
0
/*!
  Read and cache the CD's Track Table of Contents and track info.
  Return false if unsuccessful;
*/
static bool
read_toc_freebsd (void *p_user_data)
{
  _img_private_t *p_env = p_user_data;
  track_t i, j;

  /* read TOC header */
  if ( ioctl(p_env->gen.fd, CDIOREADTOCHEADER, &p_env->tochdr) == -1 ) {
    cdio_warn("error in ioctl(CDIOREADTOCHEADER): %s\n", strerror(errno));
    return false;
  }

  p_env->gen.i_first_track = p_env->tochdr.starting_track;
  p_env->gen.i_tracks      = p_env->tochdr.ending_track -
    p_env->gen.i_first_track + 1;

  j=0;
  for (i=p_env->gen.i_first_track; i<=p_env->gen.i_tracks; i++, j++) {
    struct ioc_read_toc_single_entry *p_toc =
      &(p_env->tocent[i-p_env->gen.i_first_track]);
    p_toc->track = i;
    p_toc->address_format = CD_LBA_FORMAT;

    if ( ioctl(p_env->gen.fd, CDIOREADTOCENTRY, p_toc) ) {
      cdio_warn("%s %d: %s\n",
		 "error in ioctl CDROMREADTOCENTRY for track",
		 i, strerror(errno));
      return false;
    }

    set_track_flags(&(p_env->gen.track_flags[i]), p_toc->entry.control);

  }

  p_env->tocent[j].track          = CDIO_CDROM_LEADOUT_TRACK;
  p_env->tocent[j].address_format = CD_LBA_FORMAT;
  if ( ioctl(p_env->gen.fd, CDIOREADTOCENTRY, &(p_env->tocent[j]) ) ){
    cdio_warn("%s: %s\n",
	       "error in ioctl CDROMREADTOCENTRY for leadout track",
	       strerror(errno));
    return false;
  }

  p_env->gen.toc_init = true;
  return true;
}
Пример #28
0
/*!
  Initialization routine. This is the only thing that doesn't
  get called via a function pointer. In fact *we* are the
  ones to set that up.
 */
CdIo_t *
cdio_open_am_cdrdao (const char *psz_source_name, const char *psz_access_mode)
{
  if (psz_access_mode != NULL && strcmp(psz_access_mode, "image"))
    cdio_warn ("there is only one access mode, 'image' for cdrdao. Arg %s ignored",
	       psz_access_mode);
  return cdio_open_cdrdao(psz_source_name);
}
Пример #29
0
/*!
  Read the Primary Volume Descriptor for an ISO 9660 image.
  True is returned if read, and false if there was an error.
*/
bool 
iso9660_ifs_read_pvd (const iso9660_t *p_iso, /*out*/ iso9660_pvd_t *p_pvd)
{
  if (0 == iso9660_iso_seek_read (p_iso, p_pvd, ISO_PVD_SECTOR, 1)) {
    cdio_warn ("error reading PVD sector (%d)", ISO_PVD_SECTOR);
    return false;
  }
  return check_pvd(p_pvd);
}
Пример #30
0
/*!
  Initialization routine. This is the only thing that doesn't
  get called via a function pointer. In fact *we* are the
  ones to set that up.
 */
CdIo_t *
cdio_open_am_os2 (const char *psz_source_name, const char *psz_access_mode)
{

  if (psz_access_mode != NULL)
    cdio_warn ("there is only one access mode for OS/2. Arg %s ignored",
               psz_access_mode);
  return cdio_open_os2(psz_source_name);
}