From e3a5e16cbb5679105134e15400340b3cf82c9279 Mon Sep 17 00:00:00 2001 From: "R. Bernstein" Date: Wed, 3 Feb 2010 21:43:05 -0500 Subject: [PATCH] mmc.h: TEST_UNIT_READY MMC command opcode device.h: Add DRIVER_OP_MMC_SENSE to driver_return_code_t. win32_ioctl.c: work around MS bug where buffer sizes are 0 or 1. Set return code status if sense data passed back. Translate bad parameter MS Windows error into a driver_return_code_t error. test/driver/mmc.c: Reinstate old logic now that the MS Windows driver has been made to work more like other drivers and copes with some of the MS Windows causing failure here. --- include/cdio/device.h | 730 ++++++++++++++++------------- include/cdio/mmc.h | 2 + lib/driver/MSWindows/win32_ioctl.c | 36 +- test/driver/mmc.c | 23 +- 4 files changed, 437 insertions(+), 354 deletions(-) diff --git a/include/cdio/device.h b/include/cdio/device.h index cc84e79a..ab755675 100644 --- a/include/cdio/device.h +++ b/include/cdio/device.h @@ -1,7 +1,7 @@ /* -*- c -*- - $Id: device.h,v 1.39 2008/03/28 01:28:50 rocky Exp $ - Copyright (C) 2005, 2006, 2008, 2009 Rocky Bernstein + Copyright (C) 2005, 2006, 2008, 2009, 2010 Rocky Bernstein + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,8 @@ along with this program. If not, see . */ -/** \file device.h +/** + * \file device.h * * \brief C header for driver- or device-related libcdio * calls. ("device" includes CD-image reading devices). @@ -29,12 +30,12 @@ extern "C" { #endif /* __cplusplus */ - /*! The type of an drive capability bit mask. See below for values*/ + /** The type of an drive capability bit mask. See below for values*/ typedef uint32_t cdio_drive_read_cap_t; typedef uint32_t cdio_drive_write_cap_t; typedef uint32_t cdio_drive_misc_cap_t; - /*! + /** \brief Drive capability bits returned by cdio_get_drive_cap() NOTE: Setting a bit here means the presence of a capability. */ @@ -60,7 +61,7 @@ extern "C" { i.e a CD file image */ } cdio_drive_cap_misc_t; - /*! Reading masks.. */ + /** Reading masks.. */ typedef enum { CDIO_DRIVE_CAP_READ_AUDIO = 0x00001, /**< drive can play CD audio */ CDIO_DRIVE_CAP_READ_CD_DA = 0x00002, /**< drive can read CD-DA */ @@ -80,7 +81,7 @@ extern "C" { CDIO_DRIVE_CAP_READ_ISRC = 0x08000 /**< can read ISRC */ } cdio_drive_cap_read_t; - /*! Writing masks.. */ + /** Writing masks.. */ typedef enum { CDIO_DRIVE_CAP_WRITE_CD_R = 0x00001, /**< drive can write CD-R */ CDIO_DRIVE_CAP_WRITE_CD_RW = 0x00002, /**< drive can write CD-RW */ @@ -106,7 +107,7 @@ extern "C" { /**< Has some sort of DVD or CD writing ability */ } cdio_drive_cap_write_t; -/*! Size of fields returned by an INQUIRY command */ +/** Size of fields returned by an INQUIRY command */ typedef enum { CDIO_MMC_HW_VENDOR_LEN = 8, /**< length of vendor field */ CDIO_MMC_HW_MODEL_LEN = 16, /**< length of model field */ @@ -114,7 +115,7 @@ extern "C" { } cdio_mmc_hw_len_t; - /*! \brief Structure to return CD vendor, model, and revision-level + /** \brief Structure to return CD vendor, model, and revision-level strings obtained via the INQUIRY command */ typedef struct cdio_hwinfo { @@ -133,7 +134,8 @@ extern "C" { } cdio_src_category_mask_t; - /** The driver_id_t enumerations may be used to tag a specific driver + /** + * The driver_id_t enumerations may be used to tag a specific driver * that is opened or is desired to be opened. Note that this is * different than what is available on a given host. * @@ -167,71 +169,80 @@ extern "C" { DRIVER_DEVICE /**< Is really a set of the above; should come last */ } driver_id_t; - /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in - order of preference) array of drivers. + /** + A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in + order of preference) array of drivers. */ extern const driver_id_t cdio_drivers[]; - /** A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in + + /** + A null-terminated (that is DRIVER_UNKNOWN-terminated) ordered (in order of preference) array of device drivers. */ extern const driver_id_t cdio_device_drivers[]; - /** There will generally be only one hardware for a given - build/platform from the list above. You can use the variable - below to determine which you've got. If the build doesn't make an - hardware driver, then the value will be DRIVER_UNKNOWN. + /** + There will generally be only one hardware for a given + build/platform from the list above. You can use the variable + below to determine which you've got. If the build doesn't make an + hardware driver, then the value will be DRIVER_UNKNOWN. */ extern const driver_id_t cdio_os_driver; -/** Those are deprecated; use cdio_drivers or cdio_device_drivers to - iterate over all drivers or only the device drivers. - Make sure what's listed for CDIO_MIN_DRIVER is the last - enumeration in driver_id_t. Since we have a bogus (but useful) 0th - entry above we don't have to add one. -*/ + /** + Those are deprecated; use cdio_drivers or cdio_device_drivers to + iterate over all drivers or only the device drivers. + Make sure what's listed for CDIO_MIN_DRIVER is the last + enumeration in driver_id_t. Since we have a bogus (but useful) 0th + entry above we don't have to add one. + */ #define CDIO_MIN_DRIVER DRIVER_AIX #define CDIO_MIN_DEVICE_DRIVER CDIO_MIN_DRIVER #define CDIO_MAX_DRIVER DRIVER_NRG #define CDIO_MAX_DEVICE_DRIVER DRIVER_WIN32 - /** The following are status codes for completion of a given cdio - operation. By design 0 is successful completion and -1 is error - completion. This is compatable with ioctl so those routines that - call ioctl can just pass the value the get back (cast as this - enum). Also, by using negative numbers for errors, the - enumeration values below can be used in places where a positive - value is expected when things complete successfully. For example, - get_blocksize returns the blocksize, but on error uses the error - codes below. So note that this enumeration is often cast to an - integer. C seems to tolerate this. + /** + The following are status codes for completion of a given cdio + operation. By design 0 is successful completion and -1 is error + completion. This is compatable with ioctl so those routines that + call ioctl can just pass the value the get back (cast as this + enum). Also, by using negative numbers for errors, the + enumeration values below can be used in places where a positive + value is expected when things complete successfully. For example, + get_blocksize returns the blocksize, but on error uses the error + codes below. So note that this enumeration is often cast to an + integer. C seems to tolerate this. */ typedef enum { - DRIVER_OP_SUCCESS = 0, /**< in cases where an int is returned, - like cdio_set_speed, more the negative - return codes are for errors and the - positive ones for success. */ - DRIVER_OP_ERROR = -1, /**< operation returned an error */ - DRIVER_OP_UNSUPPORTED = -2, /**< returned when a particular driver - doesn't support a particular operation. - For example an image driver which doesn't - really "eject" a CD. - */ - DRIVER_OP_UNINIT = -3, /**< returned when a particular driver - hasn't been initialized or a null - pointer has been passed. - */ - DRIVER_OP_NOT_PERMITTED = -4, /**< Operation not permitted. - For example might be a permission - problem. - */ - DRIVER_OP_BAD_PARAMETER = -5, /**< Bad parameter passed */ - DRIVER_OP_BAD_POINTER = -6, /**< Bad pointer to memory area */ - DRIVER_OP_NO_DRIVER = -7, /**< Operaton called on a driver - not available on this OS */ + DRIVER_OP_SUCCESS = 0, /**< in cases where an int is + returned, like cdio_set_speed, + more the negative return codes are + for errors and the positive ones + for success. */ + DRIVER_OP_ERROR = -1, /**< operation returned an error */ + DRIVER_OP_UNSUPPORTED = -2, /**< returned when a particular driver + doesn't support a particular operation. + For example an image driver which doesn't + really "eject" a CD. + */ + DRIVER_OP_UNINIT = -3, /**< returned when a particular driver + hasn't been initialized or a null + pointer has been passed. + */ + DRIVER_OP_NOT_PERMITTED = -4, /**< Operation not permitted. + For example might be a permission + problem. + */ + DRIVER_OP_BAD_PARAMETER = -5, /**< Bad parameter passed */ + DRIVER_OP_BAD_POINTER = -6, /**< Bad pointer to memory area */ + DRIVER_OP_NO_DRIVER = -7, /**< Operation called on a driver + not available on this OS */ + DRIVER_OP_MMC_SENSE_DATA = -8, /**< MMC operation returned sense data, + but no other error above recorded. */ } driver_return_code_t; - /*! + /** Close media tray in CD drive if there is a routine to do so. @param psz_drive the name of CD-ROM to be closed. If NULL, we will @@ -243,13 +254,13 @@ extern "C" { driver_return_code_t cdio_close_tray (const char *psz_drive, /*in/out*/ driver_id_t *p_driver_id); - /*! + /** @param drc the return code you want interpreted. @return the string information about drc */ const char *cdio_driver_errmsg(driver_return_code_t drc); - /*! + /** Eject media in CD drive if there is a routine to do so. @param p_cdio the CD object to be acted upon. @@ -257,7 +268,7 @@ extern "C" { */ driver_return_code_t cdio_eject_media (CdIo_t **p_cdio); - /*! + /** Eject media in CD drive if there is a routine to do so. @param psz_drive the name of the device to be acted upon. @@ -265,7 +276,7 @@ extern "C" { */ driver_return_code_t cdio_eject_media_drive (const char *psz_drive); - /*! + /** Free device list returned by cdio_get_devices or cdio_get_devices_with_cap. @@ -277,7 +288,7 @@ extern "C" { */ void cdio_free_device_list (char * device_list[]); - /*! + /** Get the default CD device. if p_cdio is NULL (we haven't initialized a specific device driver), then find a suitable one and return the default device for that. @@ -292,7 +303,7 @@ extern "C" { */ char * cdio_get_default_device (const CdIo_t *p_cdio); - /*! + /** Return a string containing the default CD device if none is specified. if p_driver_id is DRIVER_UNKNOWN or DRIVER_DEVICE then find a suitable one set the default device for that. @@ -301,7 +312,7 @@ extern "C" { */ char * cdio_get_default_device_driver (/*in/out*/ driver_id_t *p_driver_id); - /*! Return an array of device names. If you want a specific + /** Return an array of device names. If you want a specific devices for a driver, give that device. If you want hardware devices, give DRIVER_DEVICE and if you want all possible devices, image drivers and hardware drivers give DRIVER_UNKNOWN. @@ -314,114 +325,115 @@ extern "C" { */ char ** cdio_get_devices (driver_id_t driver_id); - /*! - Get an array of device names in search_devices that have at least - the capabilities listed by the capabities parameter. If - search_devices is NULL, then we'll search all possible CD drives. + /** + Get an array of device names in search_devices that have at least + the capabilities listed by the capabities parameter. If + search_devices is NULL, then we'll search all possible CD drives. - Capabilities have two parts to them, a "filesystem" part and an - "analysis" part. + Capabilities have two parts to them, a "filesystem" part and an + "analysis" part. + + The filesystem part is mutually exclusive. For example either the + filesystem is at most one of the High-Sierra, UFS, or HFS, + ISO9660, fileystems. Valid combinations of say HFS and ISO9660 + are specified as a separate "filesystem". + + Capabilities on the other hand are not mutually exclusive. For + example a filesystem may have none, either, or both of the XA or + Rock-Ridge extension properties. + + If "b_any" is set false then every capability listed in the + analysis portion of capabilities (i.e. not the basic filesystem) + must be satisified. If no analysis capabilities are specified, + that's a match. - The filesystem part is mutually exclusive. For example either the - filesystem is at most one of the High-Sierra, UFS, or HFS, ISO9660, - fileystems. Valid combinations of say HFS and ISO9660 are - specified as a separate "filesystem". - - Capabilities on the other hand are not mutually exclusive. For example - a filesystem may have none, either, or both of the XA or Rock-Ridge - extension properties. - - If "b_any" is set false then every capability listed in the - analysis portion of capabilities (i.e. not the basic filesystem) - must be satisified. If no analysis capabilities are specified, - that's a match. - - If "b_any" is set true, then if any of the analysis capabilities - matches, we call that a success. - - In either case, in the filesystem portion different filesystem - either specify 0 to match any filesystem or the specific - filesystem type. - - To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL. - - @return the array of device names or NULL if we couldn't get a - default device. It is also possible to return a non NULL but - after dereferencing the the value is NULL. This also means nothing - was found. + If "b_any" is set true, then if any of the analysis capabilities + matches, we call that a success. + + In either case, in the filesystem portion different filesystem + either specify 0 to match any filesystem or the specific + filesystem type. + + To find a CD-drive of any type, use the mask CDIO_FS_MATCH_ALL. + + @return the array of device names or NULL if we couldn't get a + default device. It is also possible to return a non NULL but + after dereferencing the the value is NULL. This also means nothing + was found. */ char ** cdio_get_devices_with_cap (/*in*/ char *ppsz_search_devices[], cdio_fs_anal_t capabilities, bool b_any); - /*! - Like cdio_get_devices_with_cap but we return the driver we found - as well. This is because often one wants to search for kind of drive - and then *open* it afterwards. Giving the driver back facilitates this, - and speeds things up for libcdio as well. + /** + Like cdio_get_devices_with_cap but we return the driver we found + as well. This is because often one wants to search for kind of drive + and then *open* it afterwards. Giving the driver back facilitates this, + and speeds things up for libcdio as well. */ char ** cdio_get_devices_with_cap_ret (/*in*/ char* ppsz_search_devices[], cdio_fs_anal_t capabilities, bool b_any, /*out*/ driver_id_t *p_driver_id); - /*! Like cdio_get_devices, but we may change the p_driver_id if we - were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because - often one wants to get a drive name and then *open* it - afterwards. Giving the driver back facilitates this, and speeds - things up for libcdio as well. + /** + Like cdio_get_devices, but we may change the p_driver_id if we + were given DRIVER_DEVICE or DRIVER_UNKNOWN. This is because often + one wants to get a drive name and then *open* it + afterwards. Giving the driver back facilitates this, and speeds + things up for libcdio as well. */ char ** cdio_get_devices_ret (/*in/out*/ driver_id_t *p_driver_id); - /*! - Get the what kind of device we've got. - - @param p_cdio the CD object queried - @param p_read_cap pointer to return read capabilities - @param p_write_cap pointer to return write capabilities - @param p_misc_cap pointer to return miscellaneous other capabilities - - In some situations of drivers or OS's we can't find a CD device if - there is no media in it. In this situation capabilities will show up as - NULL even though there isa hardware CD-ROM. + /** + Get the what kind of device we've got. + + @param p_cdio the CD object queried + @param p_read_cap pointer to return read capabilities + @param p_write_cap pointer to return write capabilities + @param p_misc_cap pointer to return miscellaneous other capabilities + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it. In this situation capabilities will show up as + NULL even though there isa hardware CD-ROM. */ void cdio_get_drive_cap (const CdIo_t *p_cdio, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap); - /*! - Get the drive capabilities for a specified device. - - Return a list of device capabilities. - - In some situations of drivers or OS's we can't find a CD device if - there is no media in it. In this situation capabilities will show up as - NULL even though there isa hardware CD-ROM. + /** + Get the drive capabilities for a specified device. + + Return a list of device capabilities. + + In some situations of drivers or OS's we can't find a CD device if + there is no media in it. In this situation capabilities will show up as + NULL even though there isa hardware CD-ROM. */ void cdio_get_drive_cap_dev (const char *device, cdio_drive_read_cap_t *p_read_cap, cdio_drive_write_cap_t *p_write_cap, cdio_drive_misc_cap_t *p_misc_cap); - /*! - Get a string containing the name of the driver in use. - - @return a string with driver name or NULL if CdIo_t is NULL (we - haven't initialized a specific device. + /** + Get a string containing the name of the driver in use. + + @return a string with driver name or NULL if CdIo_t is NULL (we + haven't initialized a specific device. */ const char * cdio_get_driver_name (const CdIo_t *p_cdio); - /*! - Get the driver id. - if CdIo_t is NULL (we haven't initialized a specific device driver), - then return DRIVER_UNKNOWN. - - @return the driver id.. + /** + Get the driver id. + if CdIo_t is NULL (we haven't initialized a specific device driver), + then return DRIVER_UNKNOWN. + + @return the driver id.. */ driver_id_t cdio_get_driver_id (const CdIo_t *p_cdio); - /*! + /** Get the CD-ROM hardware info via a SCSI MMC INQUIRY command. False is returned if we had an error getting the information. */ @@ -429,16 +441,17 @@ extern "C" { /*out*/ cdio_hwinfo_t *p_hw_info ); - /*! Get the LSN of the first track of the last session of - on the CD. - - @param p_cdio the CD object to be acted upon. - @param i_last_session pointer to the session number to be returned. + /** + Get the LSN of the first track of the last session of + on the CD. + + @param p_cdio the CD object to be acted upon. + @param i_last_session pointer to the session number to be returned. */ driver_return_code_t cdio_get_last_session (CdIo_t *p_cdio, /*out*/ lsn_t *i_last_session); - /*! + /** Find out if media has changed since the last call. @param p_cdio the CD object to be acted upon. @return 1 if media has changed since last call, 0 if not. Error @@ -446,21 +459,21 @@ extern "C" { */ int cdio_get_media_changed(CdIo_t *p_cdio); - /*! True if CD-ROM understand ATAPI commands. */ + /** True if CD-ROM understand ATAPI commands. */ bool_3way_t cdio_have_atapi (CdIo_t *p_cdio); - /*! Like cdio_have_xxx but uses an enumeration instead. */ + /** Like cdio_have_xxx but uses an enumeration instead. */ bool cdio_have_driver (driver_id_t driver_id); - /* - Free any resources associated with p_cdio. Call this when done using p_cdio - and using CD reading/control operations. + /** + Free any resources associated with p_cdio. Call this when done + using p_cdio and using CD reading/control operations. @param p_cdio the CD object to eliminated. */ void cdio_destroy (CdIo_t *p_cdio); - /*! + /** Get a string decribing driver_id. @param driver_id the driver you want the description for @@ -468,122 +481,136 @@ extern "C" { */ const char *cdio_driver_describe (driver_id_t driver_id); - /*! Sets up to read from place specified by psz_source and + /** + Sets up to read from place specified by psz_source and driver_id. This or cdio_open_* should be called before using any other routine, except cdio_init or any routine that accesses the - CD-ROM drive by name. cdio_open will call cdio_init, if that hasn't - been done previously. - + CD-ROM drive by name. cdio_open will call cdio_init, if that + hasn't been done previously. + @return the cdio object or NULL on error or no device. If NULL is given as the source, we'll use the default driver device. */ CdIo_t * cdio_open (const char *psz_source, driver_id_t driver_id); - /*! Sets up to read from place specified by psz_source, driver_id - and access mode. This or cdio_open* should be called before using - any other routine, except cdio_init or any routine that accesses - the CD-ROM drive by name. This will call cdio_init, if that - hasn't been done previously. - + /** + Sets up to read from place specified by psz_source, driver_id and + access mode. This or cdio_open* should be called before using any + other routine, except cdio_init or any routine that accesses the + CD-ROM drive by name. This will call cdio_init, if that hasn't + been done previously. + If NULL is given as the source, we'll use the default driver device. - + @return the cdio object or NULL on error or no device. */ CdIo_t * cdio_open_am (const char *psz_source, driver_id_t driver_id, const char *psz_access_mode); - /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or - .cue file - + /** + Set up BIN/CUE CD disk-image for reading. Source is the .bin or + .cue file + @return the cdio object or NULL on error or no device. */ CdIo_t * cdio_open_bincue (const char *psz_cue_name); - /*! Set up BIN/CUE CD disk-image for reading. Source is the .bin or - .cue file - + /** + Set up BIN/CUE CD disk-image for reading. Source is the .bin or + .cue file + @return the cdio object or NULL on error or no device.. */ CdIo_t * cdio_open_am_bincue (const char *psz_cue_name, const char *psz_access_mode); - /*! Set up cdrdao CD disk-image for reading. Source is the .toc file - + /** + Set up cdrdao CD disk-image for reading. Source is the .toc file + @return the cdio object or NULL on error or no device. */ CdIo_t * cdio_open_cdrdao (const char *psz_toc_name); - /*! Set up cdrdao CD disk-image for reading. Source is the .toc file - + /** + Set up cdrdao CD disk-image for reading. Source is the .toc file + @return the cdio object or NULL on error or no device.. - */ + */ CdIo_t * cdio_open_am_cdrdao (const char *psz_toc_name, const char *psz_access_mode); - /*! Return a string containing the default CUE file that would - be used when none is specified. - + /** + Return a string containing the default CUE file that would + be used when none is specified. + @return the cdio object or NULL on error or no device. - */ + */ char * cdio_get_default_device_bincue(void); char **cdio_get_devices_bincue(void); - /*! @return string containing the default CUE file that would be - used when none is specified. NULL is returned on error or there - is no device. + /** + @return string containing the default CUE file that would be + used when none is specified. NULL is returned on error or there + is no device. */ char * cdio_get_default_device_cdrdao(void); char **cdio_get_devices_cdrdao(void); - /*! Set up CD-ROM for reading. The device_name is - the some sort of device name. - + /** + Set up CD-ROM for reading. The device_name is + the some sort of device name. + @return the cdio object for subsequent operations. NULL on error or there is no driver for a some sort of hardware CD-ROM. - */ + */ CdIo_t * cdio_open_cd (const char *device_name); - /*! Set up CD-ROM for reading. The device_name is - the some sort of device name. - + /** + Set up CD-ROM for reading. The device_name is + the some sort of device name. + @return the cdio object for subsequent operations. NULL on error or there is no driver for a some sort of hardware CD-ROM. - */ + */ CdIo_t * cdio_open_am_cd (const char *psz_device, const char *psz_access_mode); - /*! CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file - + /** + CDRWIN BIN/CUE CD disc-image routines. Source is the .cue file + @return the cdio object for subsequent operations. NULL on error. */ CdIo_t * cdio_open_cue (const char *cue_name); - /*! Set up CD-ROM for reading using the AIX driver. The device_name is - the some sort of device name. - + /** + Set up CD-ROM for reading using the AIX driver. The device_name is + the some sort of device name. + @return the cdio object for subsequent operations. NULL on error or there is no AIX driver. - + @see cdio_open */ CdIo_t * cdio_open_am_aix (const char *psz_source, const char *psz_access_mode); - /*! Set up CD-ROM for reading using the AIX driver. The device_name is - the some sort of device name. - + /** + Set up CD-ROM for reading using the AIX driver. The device_name is + the some sort of device name. + @return the cdio object for subsequent operations. NULL on error or there is no AIX driver. - + @see cdio_open */ CdIo_t * cdio_open_aix (const char *psz_source); - /*! Return a string containing the default device name that the - AIX driver would use when none is specified. + /** + Return a string containing the default device name that the AIX + driver would use when none is specified. @return the cdio object for subsequent operations. NULL on error or there is no AIX driver. @@ -592,17 +619,19 @@ extern "C" { */ char * cdio_get_default_device_aix(void); - /*! Return a list of all of the CD-ROM devices that the AIX driver - can find. + /** + Return a list of all of the CD-ROM devices that the AIX driver + can find. - In some situations of drivers or OS's we can't find a CD device if - there is no media in it and it is possible for this routine to return - NULL even though there may be a hardware CD-ROM. + In some situations of drivers or OS's we can't find a CD device + if there is no media in it and it is possible for this routine to + return NULL even though there may be a hardware CD-ROM. */ char **cdio_get_devices_aix(void); - /*! Set up CD-ROM for reading using the BSDI driver. The device_name is - the some sort of device name. + /** + Set up CD-ROM for reading using the BSDI driver. The device_name + is the some sort of device name. @param psz_source the name of the device to open @return the cdio object for subsequent operations. @@ -612,8 +641,9 @@ extern "C" { */ CdIo_t * cdio_open_bsdi (const char *psz_source); - /*! Set up CD-ROM for reading using the BSDI driver. The device_name is - the some sort of device name. + /** + Set up CD-ROM for reading using the BSDI driver. The device_name + is the some sort of device name. @return the cdio object for subsequent operations. NULL on error or there is no BSDI driver. @@ -623,8 +653,9 @@ extern "C" { CdIo_t * cdio_open_am_bsdi (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - BSDI driver would use when none is specified. + /** + Return a string containing the default device name that the BSDI + driver would use when none is specified. @return the cdio object for subsequent operations. NULL on error or there is no BSDI driver. @@ -633,17 +664,19 @@ extern "C" { */ char * cdio_get_default_device_bsdi(void); - /*! Return a list of all of the CD-ROM devices that the BSDI driver - can find. + /** + Return a list of all of the CD-ROM devices that the BSDI driver + can find. - In some situations of drivers or OS's we can't find a CD device if - there is no media in it and it is possible for this routine to return - NULL even though there may be a hardware CD-ROM. + In some situations of drivers or OS's we can't find a CD device + if there is no media in it and it is possible for this routine to + return NULL even though there may be a hardware CD-ROM. */ char **cdio_get_devices_bsdi(void); - /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is - the some sort of device name. + /** + Set up CD-ROM for reading using the FreeBSD driver. The + device_name is the some sort of device name. NULL is returned on error or there is no FreeBSD driver. @@ -651,8 +684,9 @@ extern "C" { */ CdIo_t * cdio_open_freebsd (const char *paz_psz_source); - /*! Set up CD-ROM for reading using the FreeBSD driver. The device_name is - the some sort of device name. + /** + Set up CD-ROM for reading using the FreeBSD driver. The + device_name is the some sort of device name. NULL is returned on error or there is no FreeBSD driver. @@ -661,20 +695,23 @@ extern "C" { CdIo_t * cdio_open_am_freebsd (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - FreeBSD driver would use when none is specified. + /** + Return a string containing the default device name that the + FreeBSD driver would use when none is specified. NULL is returned on error or there is no CD-ROM device. */ char * cdio_get_default_device_freebsd(void); - /*! Return a list of all of the CD-ROM devices that the FreeBSD driver - can find. + /** + Return a list of all of the CD-ROM devices that the FreeBSD + driver can find. */ char **cdio_get_devices_freebsd(void); - /*! Set up CD-ROM for reading using the GNU/Linux driver. The device_name is - the some sort of device name. + /** + Set up CD-ROM for reading using the GNU/Linux driver. The + device_name is the some sort of device name. @return the cdio object for subsequent operations. NULL on error or there is no GNU/Linux driver. @@ -685,8 +722,9 @@ extern "C" { */ CdIo_t * cdio_open_linux (const char *psz_source); - /*! Set up CD-ROM for reading using the GNU/Linux driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the GNU/Linux driver. The + device_name is the some sort of device name. @return the cdio object for subsequent operations. NULL on error or there is no GNU/Linux driver. @@ -694,9 +732,10 @@ extern "C" { CdIo_t * cdio_open_am_linux (const char *psz_source, const char *access_mode); - /*! Return a string containing the default device name that the - GNU/Linux driver would use when none is specified. A scan is made - for CD-ROM drives with CDs in them. + /** + Return a string containing the default device name that the + GNU/Linux driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. NULL is returned on error or there is no CD-ROM device. @@ -708,21 +747,24 @@ extern "C" { */ char * cdio_get_default_device_linux(void); - /*! Return a list of all of the CD-ROM devices that the GNU/Linux driver - can find. + /** + Return a list of all of the CD-ROM devices that the GNU/Linux + driver can find. */ char **cdio_get_devices_linux(void); - /*! Set up CD-ROM for reading using the Sun Solaris driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Sun Solaris driver. The + device_name is the some sort of device name. @return the cdio object for subsequent operations. NULL on error or there is no Solaris driver. */ CdIo_t * cdio_open_solaris (const char *psz_source); - /*! Set up CD-ROM for reading using the Sun Solaris driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Sun Solaris driver. The + device_name is the some sort of device name. @return the cdio object for subsequent operations. NULL on error or there is no Solaris driver. @@ -730,9 +772,10 @@ extern "C" { CdIo_t * cdio_open_am_solaris (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - Solaris driver would use when none is specified. A scan is made - for CD-ROM drives with CDs in them. + /** + Return a string containing the default device name that the + Solaris driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. NULL is returned on error or there is no CD-ROM device. @@ -744,13 +787,15 @@ extern "C" { */ char * cdio_get_default_device_solaris(void); - /*! Return a list of all of the CD-ROM devices that the Solaris driver - can find. + /** + Return a list of all of the CD-ROM devices that the Solaris + driver can find. */ char **cdio_get_devices_solaris(void); - /*! Set up CD-ROM for reading using the Apple OSX driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Apple OSX driver. The + device_name is the some sort of device name. NULL is returned on error or there is no OSX driver. @@ -762,8 +807,9 @@ extern "C" { */ CdIo_t * cdio_open_osx (const char *psz_source); - /*! Set up CD-ROM for reading using the Apple OSX driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Apple OSX driver. The + device_name is the some sort of device name. NULL is returned on error or there is no OSX driver. @@ -772,9 +818,10 @@ extern "C" { CdIo_t * cdio_open_am_osx (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - OSX driver would use when none is specified. A scan is made - for CD-ROM drives with CDs in them. + /** + Return a string containing the default device name that the OSX + driver would use when none is specified. A scan is made for + CD-ROM drives with CDs in them. In some situations of drivers or OS's we can't find a CD device if there is no media in it and it is possible for this routine to return @@ -782,13 +829,15 @@ extern "C" { */ char * cdio_get_default_device_osx(void); - /*! Return a list of all of the CD-ROM devices that the OSX driver - can find. + /** + Return a list of all of the CD-ROM devices that the OSX driver + can find. */ char **cdio_get_devices_osx(void); - /*! Set up CD-ROM for reading using the Microsoft Windows driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Microsoft Windows driver. The + device_name is the some sort of device name. In some situations of drivers or OS's we can't find a CD device if there is no media in it and it is possible for this routine to return @@ -796,21 +845,23 @@ extern "C" { */ CdIo_t * cdio_open_win32 (const char *psz_source); - /*! Set up CD-ROM for reading using the Microsoft Windows driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Microsoft Windows driver. The + device_name is the some sort of device name. NULL is returned on error or there is no Microsof Windows driver. */ CdIo_t * cdio_open_am_win32 (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - Win32 driver would use when none is specified. A scan is made - for CD-ROM drives with CDs in them. + /** + Return a string containing the default device name that the + Win32 driver would use when none is specified. A scan is made + for CD-ROM drives with CDs in them. - In some situations of drivers or OS's we can't find a CD device if - there is no media in it and it is possible for this routine to return - NULL even though there may be a hardware CD-ROM. + In some situations of drivers or OS's we can't find a CD device + if there is no media in it and it is possible for this routine to + return NULL even though there may be a hardware CD-ROM. @see cdio_open_cd, cdio_open */ @@ -818,8 +869,9 @@ extern "C" { char **cdio_get_devices_win32(void); - /*! Set up CD-ROM for reading using the IBM OS/2 driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the IBM OS/2 driver. The + device_name is the some sort of device name. NULL is returned on error or there is no OS/2 driver. @@ -831,8 +883,9 @@ extern "C" { */ CdIo_t * cdio_open_os2 (const char *psz_source); - /*! Set up CD-ROM for reading using the IBM OS/2 driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the IBM OS/2 driver. The + device_name is the some sort of device name. NULL is returned on error or there is no OS/2 driver. @@ -841,66 +894,71 @@ extern "C" { CdIo_t * cdio_open_am_os2 (const char *psz_source, const char *psz_access_mode); - /*! Return a string containing the default device name that the - OS/2 driver would use when none is specified. A scan is made - for CD-ROM drives with CDs in them. + /** + Return a string containing the default device name that the OS/2 + driver would use when none is specified. A scan is made for + CD-ROM drives with CDs in them. - In some situations of drivers or OS's we can't find a CD device if - there is no media in it and it is possible for this routine to return - NULL even though there may be a hardware CD-ROM. + In some situations of drivers or OS's we can't find a CD device + if there is no media in it and it is possible for this routine to + return NULL even though there may be a hardware CD-ROM. */ char * cdio_get_default_device_os2(void); - /*! Return a list of all of the CD-ROM devices that the OS/2 driver + /** +Return a list of all of the CD-ROM devices that the OS/2 driver can find. */ char **cdio_get_devices_os2(void); - /*! Set up CD-ROM for reading using the Nero driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Nero driver. The device_name + is the some sort of device name. @return true on success; NULL on error or there is no Nero driver. */ CdIo_t * cdio_open_nrg (const char *psz_source); - /*! Set up CD-ROM for reading using the Nero driver. The - device_name is the some sort of device name. + /** + Set up CD-ROM for reading using the Nero driver. The device_name + is the some sort of device name. @return true on success; NULL on error or there is no Nero driver. */ CdIo_t * cdio_open_am_nrg (const char *psz_source, const char *psz_access_mode); - /*! Get a string containing the default device name that the NRG - driver would use when none is specified. A scan is made for NRG - disk images in the current directory. + /** + Get a string containing the default device name that the NRG + driver would use when none is specified. A scan is made for NRG + disk images in the current directory. - @return string containing the default device. NULL on error or - there is no CD-ROM device. + @return string containing the default device. NULL on error or + there is no CD-ROM device. */ char * cdio_get_default_device_nrg(void); char **cdio_get_devices_nrg(void); - /*! + /** - Determine if bin_name is the bin file part of a CDRWIN CD disk image. - - @param bin_name location of presumed CDRWIN bin image file. - @return the corresponding CUE file if bin_name is a BIN file or - NULL if not a BIN file. + Determine if bin_name is the bin file part of a CDRWIN CD disk image. + + @param bin_name location of presumed CDRWIN bin image file. + @return the corresponding CUE file if bin_name is a BIN file or + NULL if not a BIN file. */ char *cdio_is_binfile(const char *bin_name); - /*! - Determine if cue_name is the cue sheet for a CDRWIN CD disk image. - - @return corresponding BIN file if cue_name is a CDRWIN cue file or - NULL if not a CUE file. + /** + Determine if cue_name is the cue sheet for a CDRWIN CD disk image. + + @return corresponding BIN file if cue_name is a CDRWIN cue file or + NULL if not a CUE file. */ char *cdio_is_cuefile(const char *cue_name); - /*! + /** Determine if psg_nrg is a Nero CD disc image. @param psz_nrg location of presumed NRG image file. @@ -909,70 +967,72 @@ extern "C" { */ bool cdio_is_nrg(const char *psz_nrg); - /*! - Determine if psz_toc is a TOC file for a cdrdao CD disc image. - - @param psz_toc location of presumed TOC image file. - @return true if toc_name is a cdrdao TOC file or false - if not a TOC file. + /** + Determine if psz_toc is a TOC file for a cdrdao CD disc image. + + @param psz_toc location of presumed TOC image file. + @return true if toc_name is a cdrdao TOC file or false + if not a TOC file. */ bool cdio_is_tocfile(const char *psz_toc); - /*! - Determine if psz_source refers to a real hardware CD-ROM. - - @param psz_source location name of object - @param driver_id driver for reading object. Use DRIVER_UNKNOWN if you - don't know what driver to use. - @return true if psz_source is a device; If false is returned we - could have a CD disk image. + /** + Determine if psz_source refers to a real hardware CD-ROM. + + @param psz_source location name of object + @param driver_id driver for reading object. Use DRIVER_UNKNOWN if you + don't know what driver to use. + @return true if psz_source is a device; If false is returned we + could have a CD disk image. */ bool cdio_is_device(const char *psz_source, driver_id_t driver_id); - /*! + /** Set the blocksize for subsequent reads. */ driver_return_code_t cdio_set_blocksize ( const CdIo_t *p_cdio, int i_blocksize ); - /*! - Set the drive speed. + /** + Set the drive speed. + + @param p_cdio CD structure set by cdio_open(). - @param p_cdio CD structure set by cdio_open(). - @param i_drive_speed speed in CD-ROM speed units. Note this - not Kbs as would be used in the MMC spec or - in mmc_set_speed(). To convert CD-ROM speed units - to Kbs, multiply the number by 176 (for raw data) - and by 150 (for filesystem data). On many CD-ROM - drives, specifying a value too large will result - in using the fastest speed. + @param i_drive_speed speed in CD-ROM speed units. Note this not + Kbs as would be used in the MMC spec or in + mmc_set_speed(). To convert CD-ROM speed + units to Kbs, multiply the number by 176 (for + raw data) and by 150 (for filesystem + data). On many CD-ROM drives, specifying a + value too large will result in using the + fastest speed. @see mmc_set_speed and mmc_set_drive_speed */ driver_return_code_t cdio_set_speed ( const CdIo_t *p_cdio, int i_drive_speed ); - /*! - Get the value associatied with key. - - @param p_cdio the CD object queried - @param key the key to retrieve - @return the value associatd with "key" or NULL if p_cdio is NULL - or "key" does not exist. + /** + Get the value associatied with key. + + @param p_cdio the CD object queried + @param key the key to retrieve + @return the value associatd with "key" or NULL if p_cdio is NULL + or "key" does not exist. */ const char * cdio_get_arg (const CdIo_t *p_cdio, const char key[]); - /*! - Set the arg "key" with "value" in "p_cdio". - - @param p_cdio the CD object to set - @param key the key to set - @param value the value to assocaiate with key + /** + Set the arg "key" with "value" in "p_cdio". + + @param p_cdio the CD object to set + @param key the key to set + @param value the value to assocaiate with key */ driver_return_code_t cdio_set_arg (CdIo_t *p_cdio, const char key[], const char value[]); - /*! + /** Initialize CD Reading and control routines. Should be called first. */ bool cdio_init(void); @@ -981,11 +1041,11 @@ extern "C" { } #endif /* __cplusplus */ -/** The below variables are trickery to force the above enum symbol - values to be recorded in debug symbol tables. They are used to - allow one to refer to the enumeration value names in the typedefs - above in a debugger and debugger expressions. -*/ +/** + The below variables are trickery to force the above enum symbol + values to be recorded in debug symbol tables. They are used to + allow one to refer to the enumeration value names in the typedefs + above in a debugger and debugger expressions. */ extern cdio_drive_cap_misc_t debug_cdio_drive_cap_misc; extern cdio_drive_cap_read_t debug_cdio_drive_cap_read_t; extern cdio_drive_cap_write_t debug_drive_cap_write_t; diff --git a/include/cdio/mmc.h b/include/cdio/mmc.h index dd9b4215..16a98e15 100644 --- a/include/cdio/mmc.h +++ b/include/cdio/mmc.h @@ -113,6 +113,8 @@ extern "C" { */ typedef enum { + CDIO_MMC_TEST_UNIT_READY = 0x00, /**< Request drive + information. */ CDIO_MMC_GPCMD_INQUIRY = 0x12, /**< Request drive information. */ CDIO_MMC_GPCMD_MODE_SELECT_6 = 0x15, /**< Select medium diff --git a/lib/driver/MSWindows/win32_ioctl.c b/lib/driver/MSWindows/win32_ioctl.c index daee9a8c..10d93206 100644 --- a/lib/driver/MSWindows/win32_ioctl.c +++ b/lib/driver/MSWindows/win32_ioctl.c @@ -453,6 +453,8 @@ run_mmc_cmd_win32ioctl( void *p_user_data, BOOL b_success; DWORD dw_bytes_returned; + char dummy_buf[2]; /* Used if we can't use p_buf. See below. */ + int rc = DRIVER_OP_SUCCESS; memset(&swb, 0, sizeof(swb)); @@ -467,8 +469,20 @@ run_mmc_cmd_win32ioctl( void *p_user_data, (SCSI_MMC_DATA_READ == e_direction) ? SCSI_IOCTL_DATA_IN : (SCSI_MMC_DATA_WRITE == e_direction) ? SCSI_IOCTL_DATA_OUT : SCSI_IOCTL_DATA_UNSPECIFIED; - swb.sptd.DataBuffer = p_buf; - swb.sptd.DataTransferLength= i_buf; + + /* MS Windows seems to flip out of the size of the buffer is 0 or + 1. For the 1 byte case see: BUG: SCSI Pass Through Fails with + Invalid User Buffer Error http://support.microsoft.com/kb/259573 + So in those cases we will provide our own. + */ + if (i_buf <= 1) { + swb.sptd.DataBuffer = &dummy_buf; + swb.sptd.DataTransferLength = 2; + } else { + swb.sptd.DataBuffer = p_buf; + swb.sptd.DataTransferLength = i_buf; + } + swb.sptd.TimeOutValue = msecs2secs(i_timeout_ms); swb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, SenseBuf); @@ -485,9 +499,18 @@ run_mmc_cmd_win32ioctl( void *p_user_data, &dw_bytes_returned, NULL); + if (i_buf == 1) memcpy(p_buf, &dummy_buf[0], 1); + if ( 0 == b_success ) { - windows_error(CDIO_LOG_INFO, GetLastError()); - return DRIVER_OP_ERROR; + long int last_error = GetLastError(); + windows_error(CDIO_LOG_INFO, last_error); + switch (last_error) { + case 87: + rc = DRIVER_OP_BAD_PARAMETER; + break; + default: + rc = DRIVER_OP_ERROR; + } } /* Record SCSI sense reply for API call mmc_last_cmd_sense(). @@ -500,9 +523,10 @@ run_mmc_cmd_win32ioctl( void *p_user_data, sense_size = sizeof(swb.SenseBuf); memcpy((void *) p_env->gen.scsi_mmc_sense, &swb.SenseBuf, sense_size); p_env->gen.scsi_mmc_sense_valid = sense_size; + if (DRIVER_OP_SUCCESS == rc) + rc = DRIVER_OP_MMC_SENSE_DATA; } - - return DRIVER_OP_SUCCESS; + return rc; } #else int diff --git a/test/driver/mmc.c b/test/driver/mmc.c index d2e6c1b2..f983e6f1 100644 --- a/test/driver/mmc.c +++ b/test/driver/mmc.c @@ -146,21 +146,21 @@ tmmc_test_unit_ready(CdIo_t *p_cdio, { int i_status; mmc_cdb_t cdb = {{0, }}; - char buf[2]; /* just to have an address to pass to mmc_run_cmd() */ + char buf[1]; /* just to have an address to pass to mmc_run_cmd() */ memset(cdb.field, 0, 6); - cdb.field[0] = 0x00; /* TEST UNIT READY, SPC-3 6.33 */ + cdb.field[0] = CDIO_MMC_TEST_UNIT_READY; /* SPC-3 6.33 */ if (flag & 1) fprintf(stderr, "tmmc_test_unit_ready ... "); - i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 2, buf); + i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 0, buf); return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply, flag & 1); } -/* OBTRUSIVE , PHYSICAL EFFECT , DANGER OF HUMAN INJURY */ +/* OBTRUSIVE. PHYSICAL EFFECT: DANGER OF HUMAN INJURY */ /* @param flag bit0= verbose bit1= Asynchronous operation bit2= Load (else Eject) @@ -188,7 +188,7 @@ tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail, } -/* BARELY OBTRUSIVE, MIGHT SPOIL BURN RUNS */ +/* BARELY OBTRUSIVE: MIGHT SPOIL BURN RUNS */ /* Fetch a mode page or a part of it from the drive. @param alloc_len The number of bytes to be requested from the drive and to be copied into parameter buf. @@ -241,7 +241,8 @@ tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18], } -/* OBTRUSIVE, SPOILS BURN RUNS , might return minor failure with -ROM drives */ +/* OBTRUSIVE. SPOILS BURN RUNS and might return minor failure with + -ROM drives */ /* Send a mode page to the drive. @param buf Contains the payload bytes. The first 8 shall be a Mode Parameter Header as of SPC-3 7.4.3, table 240. @@ -622,7 +623,6 @@ tmmc_test(char *drive_path, int flag) drive_path, scsi_tuple); -#if 0 /* Test availability of sense reply in case of unready drive. E.g. if the tray is already ejected. */ @@ -633,35 +633,32 @@ tmmc_test(char *drive_path, int flag) sense_avail); {ret = 2; goto ex;} } -#endif /* Cause sense reply failure by requesting inappropriate mode page 3Eh */ ret = tmmc_mode_sense(p_cdio, &sense_avail, sense, 0x3e, 0, alloc_len, buf, &buf_fill, !!verbose); - if (sense_avail < 18) { + if (ret != 0 && sense_avail < 18) { fprintf(stderr, "Error: An illegal command yields only %d sense bytes. Expected >= 18.\n", sense_avail); {ret = 2; goto ex;} } -#if 0 /* Test availability of sense reply in case of unready drive. E.g. if the tray is already ejected. */ ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense, !!verbose); - if (sense_avail < 18) { + if (ret != 0 && sense_avail < 18) { fprintf(stderr, "Error: Drive not ready. Only %d sense bytes. Expected >= 18.\n", sense_avail); {ret = 2; goto ex;} } -#endif /* Cause sense reply failure by requesting inappropriate mode page 3Eh */ ret = tmmc_mode_sense(p_cdio, &sense_avail, sense, 0x3e, 0, alloc_len, buf, &buf_fill, !!verbose); - if (sense_avail < 18) { + if (ret != 0 && sense_avail < 18) { fprintf(stderr, "Error: Deliberately illegal command yields only %d sense bytes. Expected >= 18.\n", sense_avail);