parent
da15bba025
commit
bbdb40ff0f
107
libburn/drive.c
107
libburn/drive.c
@ -25,20 +25,28 @@ static int drivetop = -1;
|
||||
|
||||
int burn_drive_is_open(struct burn_drive *d);
|
||||
|
||||
void burn_drive_free(void)
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/* splitting former burn_drive_free() (which freed all, into two calls) */
|
||||
void burn_drive_free(struct burn_drive *d)
|
||||
{
|
||||
if (d->global_index == -1)
|
||||
return;
|
||||
/* ts A60822 : close open fds before forgetting them */
|
||||
if (burn_drive_is_open(d))
|
||||
close(d->fd);
|
||||
free((void *) d->idata);
|
||||
free((void *) d->mdata);
|
||||
free((void *) d->toc_entry);
|
||||
free(d->devname);
|
||||
d->global_index = -1;
|
||||
}
|
||||
|
||||
void burn_drive_free_all(void)
|
||||
{
|
||||
int i;
|
||||
struct burn_drive *d;
|
||||
|
||||
for (i = 0; i < drivetop + 1; i++) {
|
||||
d = &drive_array[i];
|
||||
if (burn_drive_is_open(d))
|
||||
close(d->fd);
|
||||
free((void *)d->idata);
|
||||
free((void *)d->mdata);
|
||||
free((void *)d->toc_entry);
|
||||
free(d->devname);
|
||||
}
|
||||
for (i = 0; i < drivetop + 1; i++)
|
||||
burn_drive_free(&(drive_array[i]));
|
||||
drivetop = -1;
|
||||
memset(drive_array, 0, sizeof(drive_array));
|
||||
}
|
||||
@ -86,6 +94,10 @@ int burn_drive_grab(struct burn_drive *d, int le)
|
||||
|
||||
struct burn_drive *burn_drive_register(struct burn_drive *d)
|
||||
{
|
||||
#ifdef Libburn_ticket_62_re_register_is_possiblE
|
||||
int i;
|
||||
#endif
|
||||
|
||||
d->block_types[0] = 0;
|
||||
d->block_types[1] = 0;
|
||||
d->block_types[2] = 0;
|
||||
@ -100,9 +112,33 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
||||
d->toc_entry = NULL;
|
||||
d->disc = NULL;
|
||||
d->erasable = 0;
|
||||
|
||||
#ifdef Libburn_ticket_62_re_register_is_possiblE
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/* Not yet accepted because no use case seen yet */
|
||||
|
||||
/* This is supposed to find an already freed drive struct among
|
||||
all the the ones that have been used before */
|
||||
for (i = 0; i < drivetop + 1; i++)
|
||||
if (drive_array[i].global_index == -1)
|
||||
break;
|
||||
d->global_index = i;
|
||||
memcpy(&drive_array[i], d, sizeof(struct burn_drive));
|
||||
pthread_mutex_init(&drive_array[i].access_lock, NULL);
|
||||
if (drivetop < i)
|
||||
drivetop = i;
|
||||
return &(drive_array[i]);
|
||||
|
||||
#else /* Libburn_ticket_62_re_register_is_possiblE */
|
||||
/* old A60904 : */
|
||||
/* Still active by default */
|
||||
|
||||
memcpy(&drive_array[drivetop + 1], d, sizeof(struct burn_drive));
|
||||
pthread_mutex_init(&drive_array[drivetop + 1].access_lock, NULL);
|
||||
return &drive_array[++drivetop];
|
||||
|
||||
#endif /* ! Libburn_ticket_62_re_register_is_possiblE */
|
||||
|
||||
}
|
||||
|
||||
void burn_drive_release(struct burn_drive *d, int le)
|
||||
@ -138,6 +174,11 @@ void burn_wait_all(void)
|
||||
finished = 1;
|
||||
d = drive_array;
|
||||
for (i = burn_drive_count(); i > 0; --i, ++d) {
|
||||
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
if (d->global_index==-1)
|
||||
continue;
|
||||
|
||||
assert(d->released);
|
||||
}
|
||||
if (!finished)
|
||||
@ -284,10 +325,13 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
unsigned int *n_drives)
|
||||
{
|
||||
/* state vars for the scan process */
|
||||
static int scanning = 0, scanned, found;
|
||||
static unsigned num_scanned, count;
|
||||
/* ts A60904 : did set some default values to feel comfortable */
|
||||
static int scanning = 0, scanned = 0, found = 0;
|
||||
static unsigned num_scanned = 0, count = 0;
|
||||
unsigned int i;
|
||||
#ifdef Libburn_ticket_62_enable_redundant_asserT
|
||||
struct burn_drive *d;
|
||||
#endif
|
||||
|
||||
assert(burn_running);
|
||||
|
||||
@ -298,10 +342,14 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
before checking for the released
|
||||
state */
|
||||
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/* this is redundant with what is done in burn_wait_all() */
|
||||
#ifdef Libburn_ticket_62_enable_redundant_asserT
|
||||
d = drive_array;
|
||||
count = burn_drive_count();
|
||||
for (i = 0; i < count; ++i, ++d)
|
||||
assert(d->released == 1);
|
||||
#endif /* Libburn_ticket_62_enable_redundant_asserT */
|
||||
|
||||
/* refresh the lib's drives */
|
||||
sg_enumerate();
|
||||
@ -337,10 +385,27 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
return 0;
|
||||
}
|
||||
|
||||
void burn_drive_info_free(struct burn_drive_info *info)
|
||||
|
||||
void burn_drive_info_free(struct burn_drive_info drive_infos[])
|
||||
{
|
||||
free(info);
|
||||
burn_drive_free();
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/* clarifying the meaning and the identity of the victim */
|
||||
|
||||
/* ts A60904 : This looks a bit weird.
|
||||
burn_drive_info is not the manager of burn_drive but only its
|
||||
spokesperson. To my knowlege drive_infos from burn_drive_scan()
|
||||
are not memorized globally. */
|
||||
if(drive_infos != NULL) /* and this NULL test is deadly necessary */
|
||||
free((void *) drive_infos);
|
||||
|
||||
burn_drive_free_all();
|
||||
}
|
||||
|
||||
/* Experimental API call */
|
||||
int burn_drive_info_forget(struct burn_drive_info *info)
|
||||
{
|
||||
burn_drive_free(info->drive);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct burn_disc *burn_drive_get_disc(struct burn_drive *d)
|
||||
@ -433,7 +498,7 @@ int burn_drive_is_open(struct burn_drive *d)
|
||||
/* ts A60823 */
|
||||
/** Aquire a drive with known persistent address.
|
||||
*/
|
||||
int burn_drive_scan_and_grab(struct burn_drive_info *drives[], char* adr,
|
||||
int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
|
||||
int load)
|
||||
{
|
||||
unsigned int n_drives;
|
||||
@ -441,19 +506,19 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drives[], char* adr,
|
||||
|
||||
burn_drive_clear_whitelist();
|
||||
burn_drive_add_whitelist(adr);
|
||||
while (!burn_drive_scan(drives, &n_drives));
|
||||
while (!burn_drive_scan(drive_infos, &n_drives));
|
||||
if (n_drives <= 0)
|
||||
return 0;
|
||||
if (load) {
|
||||
/* RIP-14.5 + LITE-ON 48125S produce a false status
|
||||
if tray was unloaded */
|
||||
/* Therefore the first grab is just for loading */
|
||||
ret= burn_drive_grab(drives[0]->drive, 1);
|
||||
ret= burn_drive_grab(drive_infos[0]->drive, 1);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
burn_drive_release(drives[0]->drive,0);
|
||||
burn_drive_release(drive_infos[0]->drive,0);
|
||||
}
|
||||
ret = burn_drive_grab(drives[0]->drive, load);
|
||||
ret = burn_drive_grab(drive_infos[0]->drive, load);
|
||||
if (ret != 1)
|
||||
return -1;
|
||||
return 1;
|
||||
|
@ -42,7 +42,8 @@ int burn_sector_length_write(struct burn_drive *d);
|
||||
int burn_track_control(struct burn_drive *d, int);
|
||||
void burn_write_empty_sector(int fd);
|
||||
void burn_write_empty_subcode(int fd);
|
||||
void burn_drive_free(void);
|
||||
void burn_drive_free(struct burn_drive *d);
|
||||
void burn_drive_free_all(void);
|
||||
|
||||
int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
unsigned int *n_drives);
|
||||
|
@ -46,7 +46,8 @@ void burn_finish(void)
|
||||
|
||||
burn_wait_all();
|
||||
|
||||
burn_drive_free();
|
||||
/* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */
|
||||
burn_drive_free_all();
|
||||
|
||||
burn_running = 0;
|
||||
}
|
||||
|
@ -479,6 +479,7 @@ struct burn_message* burn_get_message(void);
|
||||
/** Frees a burn_message structure */
|
||||
void burn_message_free(struct burn_message *msg);
|
||||
|
||||
|
||||
/* ts A60823 */
|
||||
/** Aquire a drive with known persistent address.This is the sysadmin friendly
|
||||
way to open one drive and to leave all others untouched. It bundles
|
||||
@ -493,8 +494,8 @@ void burn_message_free(struct burn_message *msg);
|
||||
burn_drive_scan().
|
||||
You may start a new libburn session and should then use the function
|
||||
described here with an address obtained after burn_drive_scan() via
|
||||
a call of burn_drive_get_adr(&(drives[driveno]), adr) .
|
||||
@param drives On success returns a one element array with the drive
|
||||
a call of burn_drive_get_adr(&(drive_infos[driveno]), adr) .
|
||||
@param drive_infos On success returns a one element array with the drive
|
||||
(cdrom/burner). Thus use with driveno 0 only. On failure
|
||||
the array has no valid elements at all.
|
||||
The returned array should be freed via burn_drive_info_free()
|
||||
@ -509,46 +510,63 @@ void burn_message_free(struct burn_message *msg);
|
||||
tray door, etc).
|
||||
@return 1 = success , 0 = drive not found , -1 = other error
|
||||
*/
|
||||
int burn_drive_scan_and_grab(struct burn_drive_info *drives[], char* adr,
|
||||
int load);
|
||||
int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[],
|
||||
char* adr, int load);
|
||||
|
||||
|
||||
/* ts A51221 */
|
||||
/** Maximum number of particularly permissible drive addresses */
|
||||
#define BURN_DRIVE_WHITELIST_LEN 255
|
||||
/** Add a device to the list of permissible drives. As soon as some entry is in
|
||||
the whitelist all non-listed drives are banned from enumeration.
|
||||
the whitelist all non-listed drives are banned from scanning.
|
||||
@return 1 success, <=0 failure
|
||||
*/
|
||||
int burn_drive_add_whitelist(char *device_address);
|
||||
/** Remove all drives from whitelist. This enables all possible drives. */
|
||||
void burn_drive_clear_whitelist(void);
|
||||
|
||||
|
||||
/** Scans for drives. This function MUST be called until it returns nonzero.
|
||||
No drives can be in use when this is called or it will assert.
|
||||
All drive pointers are invalidated by using this function. Do NOT store
|
||||
drive pointers across calls to this function or death AND pain will ensue.
|
||||
When the app is done with the burn_drive_info array, it must be freed with
|
||||
burn_drive_info_free()
|
||||
@param drives Returns an array of drives (cdroms/burners). The returned
|
||||
array should be freed when it is no longer needed, and
|
||||
before calling this function again to rescan.
|
||||
@param n_drives Returns the number of hardware drives in @c drives.
|
||||
After this call all drives depicted by the returned array are subject
|
||||
to eventual (O_EXCL) locking. See burn_preset_device_open(). This state
|
||||
ends either with burn_drive_info_forget() or with burn_drive_release().
|
||||
It is unfriendly to other processes on the system to hold drives locked
|
||||
which one does not definitely plan to use soon.
|
||||
@param drive_infos Returns an array of drive info items (cdroms/burners).
|
||||
The returned array must be freed by burn_drive_info_free()
|
||||
before burn_finish(), and also before calling this function
|
||||
burn_drive_scan() again.
|
||||
@param n_drives Returns the number of drive items in drive_infos.
|
||||
@return Zero while scanning is not complete; non-zero when it is finished.
|
||||
*/
|
||||
int burn_drive_scan(struct burn_drive_info *drives[],
|
||||
int burn_drive_scan(struct burn_drive_info *drive_infos[],
|
||||
unsigned int *n_drives);
|
||||
|
||||
/** Frees a burn_drive_info array returned by burn_drive_scan
|
||||
@param info The array to free
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/** EXPERIMENTAL: DO NOT USE IN PRODUCTION YET. DO NOT RELY ON PERSISTENCE YET.
|
||||
Release memory about and any exclusive locks on a single drive
|
||||
and become unable to inquire or grab it.
|
||||
@param drive_info pointer to a single element out of the array
|
||||
obtained from burn_drive_scan() : &(drive_infos[driveno])
|
||||
@return 1 on success, <=0 on failure
|
||||
*/
|
||||
void burn_drive_info_free(struct burn_drive_info *info);
|
||||
int burn_drive_info_forget(struct burn_drive_info *drive_info);
|
||||
|
||||
|
||||
/** Frees a burn_drive_info array returned by burn_drive_scan
|
||||
*/
|
||||
void burn_drive_info_free(struct burn_drive_info drive_infos[]);
|
||||
|
||||
|
||||
/* ts A60823 */
|
||||
/** Maximum length+1 to expect with a persistent drive address string */
|
||||
#define BURN_DRIVE_ADR_LEN 1024
|
||||
|
||||
/** Inquire the persistent address of the given drive.
|
||||
@param drive The drive to inquire. Usually some &(drives[driveno])
|
||||
@param drive The drive to inquire. Usually some &(drive_infos[driveno])
|
||||
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN
|
||||
characters size. The persistent address gets copied to it.
|
||||
*/
|
||||
@ -556,23 +574,25 @@ int burn_drive_get_adr(struct burn_drive_info *drive, char adr[]);
|
||||
|
||||
|
||||
/** Grab a drive. This must be done before the drive can be used (for reading,
|
||||
writing, etc). It may be neccesary to call this function more than once
|
||||
to grab a drive. See burn_grab for details.
|
||||
writing, etc).
|
||||
@param drive The drive to grab. This is found in a returned
|
||||
burn_drive_info struct.
|
||||
@param load Nonzero to make the drive attempt to load a disc (close its
|
||||
tray door, etc).
|
||||
@return 1 if the drive has been grabbed, else 0
|
||||
@return 1 if it was possible to grab the drive, else 0
|
||||
*/
|
||||
int burn_drive_grab(struct burn_drive *drive, int load);
|
||||
|
||||
|
||||
/** Release a drive. This should not be done until the drive is no longer
|
||||
busy (see burn_drive_get_status).
|
||||
busy (see burn_drive_get_status). The drive is (O_EXCL) unlocked
|
||||
afterwards.
|
||||
@param drive The drive to release.
|
||||
@param eject Nonzero to make the drive eject the disc in it.
|
||||
*/
|
||||
void burn_drive_release(struct burn_drive *drive, int eject);
|
||||
|
||||
|
||||
/** Returns what kind of disc a drive is holding. This function may need to be
|
||||
called more than once to get a proper status from it. See burn_status
|
||||
for details.
|
||||
|
@ -89,6 +89,8 @@ struct scsi_mode_data
|
||||
int underrun_proof;
|
||||
};
|
||||
|
||||
|
||||
/** Gets initialized in enumerate_common() and burn_drive_register() */
|
||||
struct burn_drive
|
||||
{
|
||||
int host;
|
||||
@ -98,6 +100,13 @@ struct burn_drive
|
||||
char *devname;
|
||||
int fd;
|
||||
|
||||
/* ts A60904 : ticket 62, contribution by elmom */
|
||||
/**
|
||||
Tells the index in scanned burn_drive_info array.
|
||||
-1 if fallen victim to burn_drive_info_forget()
|
||||
*/
|
||||
int global_index;
|
||||
|
||||
pthread_mutex_t access_lock;
|
||||
|
||||
enum burn_disc_status status;
|
||||
|
Loading…
Reference in New Issue
Block a user