522 lines
13 KiB
C
522 lines
13 KiB
C
/*
|
|
* Burn.c
|
|
*
|
|
* Copyright (c) 2007 Vreixo Formoso
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
* See COPYING file for details.
|
|
*/
|
|
|
|
#include "org_pykix_libburnia_libburn_Burn.h"
|
|
#include "BindingsUtil.h"
|
|
|
|
#include "libburn.h"
|
|
|
|
static struct burn_drive_info *drive_infos = NULL;
|
|
|
|
static int java_libburn_signal_handler(void *handle, int signum, int flag);
|
|
static int java_libburn_pacifier_func(void *handle, int patience, int elapsed);
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_initialize
|
|
* Signature: ()I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1initialize
|
|
(
|
|
JNIEnv *env, jclass cls
|
|
)
|
|
{
|
|
return burn_initialize();
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_finish
|
|
* Signature: ()V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1finish
|
|
(
|
|
JNIEnv *env, jclass cls
|
|
)
|
|
{
|
|
if ( drive_infos != NULL ) {
|
|
/* if we have a drive array, it must be freed before finish */
|
|
burn_drive_info_free(drive_infos);
|
|
}
|
|
burn_finish();
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_preset_device_open
|
|
* Signature: (III)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1preset_1device_1open
|
|
( JNIEnv *env, jclass cls, jint exclusive, jint blocking, jint abort)
|
|
{
|
|
burn_preset_device_open(exclusive, blocking, abort);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_allow_untested_profiles
|
|
* Signature: (Z)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1allow_1untested_1profiles
|
|
(
|
|
JNIEnv *env, jclass cls, jboolean yes
|
|
)
|
|
{
|
|
burn_allow_untested_profiles(yes);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_scan
|
|
* Signature: ()[Lorg/pykix/libburnia/libburn/DriveInfo;
|
|
*/
|
|
JNIEXPORT jobjectArray JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1scan
|
|
(
|
|
JNIEnv *env, jclass cls
|
|
)
|
|
{
|
|
unsigned int n_drives;
|
|
static jclass driveInfoCls = NULL;
|
|
static jmethodID cid = NULL;
|
|
jobjectArray result;
|
|
int i;
|
|
|
|
if ( drive_infos != NULL ) {
|
|
/* if we already have a drive array, it must be freed before scan again */
|
|
burn_drive_info_free(drive_infos);
|
|
}
|
|
|
|
while ( !burn_drive_scan(&drive_infos, &n_drives) ) {
|
|
usleep(1002);
|
|
}
|
|
|
|
if ( n_drives <= 0 ) {
|
|
return NULL;
|
|
}
|
|
|
|
if ( driveInfoCls == NULL ) {
|
|
driveInfoCls = java_libburn_find_class(env, "org/pykix/libburnia/libburn/DriveInfo");
|
|
if ( driveInfoCls == NULL ) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if ( cid == NULL ) {
|
|
cid = (*env)->GetMethodID(env, driveInfoCls, "<init>",
|
|
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZZZZZZIIIIIJ)V");
|
|
if (cid == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
}
|
|
|
|
result = (*env)->NewObjectArray(env, n_drives, driveInfoCls, NULL);
|
|
|
|
for ( i = 0; i < n_drives; ++i ) {
|
|
|
|
struct burn_drive_info* drive = &(drive_infos[i]);
|
|
|
|
jstring vendor = (*env)->NewStringUTF(env, drive->vendor);
|
|
jstring product = (*env)->NewStringUTF(env, drive->product);
|
|
jstring revision = (*env)->NewStringUTF(env, drive->revision);
|
|
jstring location = (*env)->NewStringUTF(env, drive->location);
|
|
|
|
jobject jdrive = (*env)->NewObject(env, driveInfoCls, cid, (jlong) drive, vendor, product,
|
|
revision, location, drive->read_dvdram, drive->read_dvdr, drive->read_dvdrom,
|
|
drive->read_cdr, drive->read_cdrw, drive->write_dvdram,
|
|
drive->write_dvdr, drive->write_cdr, drive->write_cdrw,
|
|
drive->write_simulate, drive->c2_errors, drive->buffer_size,
|
|
drive->tao_block_types, drive->sao_block_types, drive->raw_block_types,
|
|
drive->packet_block_types, drive->drive);
|
|
|
|
if (jdrive == NULL) {
|
|
return NULL; /* out of memory error thrown */
|
|
}
|
|
|
|
(*env)->SetObjectArrayElement(env, result, i, jdrive);
|
|
(*env)->DeleteLocalRef(env, vendor);
|
|
(*env)->DeleteLocalRef(env, product);
|
|
(*env)->DeleteLocalRef(env, revision);
|
|
(*env)->DeleteLocalRef(env, location);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_scan_and_grab
|
|
* Signature: (Ljava/lang/String;Z)Lorg/pykix/libburnia/libburn/DriveInfo;
|
|
*/
|
|
JNIEXPORT jobject JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1scan_1and_1grab
|
|
(
|
|
JNIEnv *env, jclass cls, jstring adr, jboolean load
|
|
)
|
|
{
|
|
|
|
const char* cadr;
|
|
static jclass driveInfoCls = NULL;
|
|
static jmethodID cid = NULL;
|
|
|
|
if ( drive_infos != NULL ) {
|
|
/* if we already have a drive array, it must be freed before scan again */
|
|
burn_drive_info_free(drive_infos);
|
|
}
|
|
|
|
cadr = (*env)->GetStringUTFChars(env, adr, NULL);
|
|
if ( cadr == NULL ) {
|
|
return NULL; /* OutOfMemoryError already thrown */
|
|
}
|
|
|
|
if ( burn_drive_scan_and_grab(&drive_infos, (char *)cadr, load) != 1 ) {
|
|
(*env)->ReleaseStringUTFChars(env, adr, cadr);
|
|
return NULL;
|
|
}
|
|
|
|
if ( driveInfoCls == NULL ) {
|
|
driveInfoCls = java_libburn_find_class(env, "org/pykix/libburnia/libburn/DriveInfo");
|
|
if ( driveInfoCls == NULL ) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if ( cid == NULL ) {
|
|
cid = (*env)->GetMethodID(env, driveInfoCls, "<init>",
|
|
"(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZZZZZZZZZIIIIIJ)V");
|
|
if (cid == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
}
|
|
|
|
struct burn_drive_info* drive = &(drive_infos[0]);
|
|
|
|
jstring vendor = (*env)->NewStringUTF(env, drive->vendor);
|
|
jstring product = (*env)->NewStringUTF(env, drive->product);
|
|
jstring revision = (*env)->NewStringUTF(env, drive->revision);
|
|
jstring location = (*env)->NewStringUTF(env, drive->location);
|
|
|
|
jobject jdrive = (*env)->NewObject(env, driveInfoCls, cid, (jlong) drive, vendor, product,
|
|
revision, location, drive->read_dvdram, drive->read_dvdr, drive->read_dvdrom,
|
|
drive->read_cdr, drive->read_cdrw, drive->write_dvdram,
|
|
drive->write_dvdr, drive->write_cdr, drive->write_cdrw,
|
|
drive->write_simulate, drive->c2_errors, drive->buffer_size,
|
|
drive->tao_block_types, drive->sao_block_types, drive->raw_block_types,
|
|
drive->packet_block_types, drive->drive);
|
|
|
|
(*env)->DeleteLocalRef(env, vendor);
|
|
(*env)->DeleteLocalRef(env, product);
|
|
(*env)->DeleteLocalRef(env, revision);
|
|
(*env)->DeleteLocalRef(env, location);
|
|
(*env)->ReleaseStringUTFChars(env, adr, cadr);
|
|
|
|
return jdrive;
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_add_whitelist
|
|
* Signature: (Ljava/lang/String;)I
|
|
*/
|
|
JNIEXPORT jint JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1add_1whitelist
|
|
(
|
|
JNIEnv *env, jclass cls, jstring adr
|
|
)
|
|
{
|
|
const char* cadr;
|
|
int res;
|
|
|
|
cadr = (*env)->GetStringUTFChars(env, adr, NULL);
|
|
if ( cadr == NULL ) {
|
|
return -1; /* OutOfMemoryError already thrown */
|
|
}
|
|
|
|
res = burn_drive_add_whitelist( (char *) adr);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, adr, cadr);
|
|
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_clear_whitelist
|
|
* Signature: ()V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1clear_1whitelist
|
|
(
|
|
JNIEnv *env, jclass cls
|
|
)
|
|
{
|
|
burn_drive_clear_whitelist();
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_set_verbosity
|
|
* Signature: (I)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1set_1verbosity
|
|
(
|
|
JNIEnv *env, jclass cls, jint level
|
|
)
|
|
{
|
|
burn_set_verbosity(level);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_is_enumerable_adr
|
|
* Signature: (Ljava/lang/String;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1is_1enumerable_1adr
|
|
(
|
|
JNIEnv *env, jclass cls, jstring adr
|
|
)
|
|
{
|
|
const char* cadr;
|
|
int res;
|
|
|
|
cadr = (*env)->GetStringUTFChars(env, adr, NULL);
|
|
if ( cadr == NULL ) {
|
|
return 0; /* OutOfMemoryError already thrown */
|
|
}
|
|
|
|
res = burn_drive_is_enumerable_adr( (char *) adr);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, adr, cadr);
|
|
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_drive_convert_fs_adr
|
|
* Signature: (Ljava/lang/String;)Ljava/lang/String;
|
|
*/
|
|
JNIEXPORT jstring JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1drive_1convert_1fs_1adr
|
|
(
|
|
JNIEnv *env, jclass cls, jstring path
|
|
)
|
|
{
|
|
const char* cpath;
|
|
char adr[BURN_DRIVE_ADR_LEN];
|
|
|
|
cpath = (*env)->GetStringUTFChars(env, path, NULL);
|
|
if ( cpath == NULL ) {
|
|
return NULL; /* OutOfMemoryError already thrown */
|
|
}
|
|
|
|
if ( burn_drive_convert_fs_adr( (char *) cpath, adr) != 1) {
|
|
(*env)->ReleaseStringUTFChars(env, path, cpath);
|
|
return NULL;
|
|
}
|
|
|
|
(*env)->ReleaseStringUTFChars(env, path, cpath);
|
|
|
|
return (*env)->NewStringUTF(env, adr);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_abort_def
|
|
* Signature: (ILjava/lang/String;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1abort_1def
|
|
(
|
|
JNIEnv *env, jclass cls, jint patience, jstring msg
|
|
)
|
|
{
|
|
const char *message;
|
|
int res;
|
|
|
|
message = (*env)->GetStringUTFChars(env, msg, NULL);
|
|
if ( message == NULL ) {
|
|
return 0; /* OutOfMemoryError already thrown */
|
|
}
|
|
|
|
res = burn_abort(patience, burn_abort_pacifier, (void *) message);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, msg, message);
|
|
|
|
if ( res < 0 ) {
|
|
java_libburn_throw_burn_exception(env, "Can't abort");
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_abort_java
|
|
* Signature: (ILorg/pykix/libburnia/libburn/Burn$AbortHandler;)Z
|
|
*/
|
|
JNIEXPORT jboolean JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1abort_1java
|
|
(
|
|
JNIEnv *env, jclass cls, jint patience, jobject handler
|
|
)
|
|
{
|
|
|
|
int res = burn_abort(patience, java_libburn_pacifier_func, (void *) handler);
|
|
|
|
if ( res < 0 ) {
|
|
java_libburn_throw_burn_exception(env, "Can't abort");
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static int java_libburn_pacifier_func
|
|
(
|
|
void *handle, int patience, int elapsed
|
|
)
|
|
{
|
|
/* call back to java */
|
|
JNIEnv *env;
|
|
jclass handlerCls;
|
|
|
|
env = java_libburn_get_env();
|
|
|
|
if ( env == NULL ) {
|
|
perror("Ups, can't call back to abort java pacifier.\n");
|
|
return -1;
|
|
}
|
|
|
|
handlerCls = (*env)->FindClass(env, "org/pykix/libburnia/libburn/Burn$AbortHandler");
|
|
if ( handlerCls == NULL ) {
|
|
perror("Ups, java handler not found.\n");
|
|
return -1;
|
|
}
|
|
|
|
jmethodID mid = (*env)->GetMethodID(env, handlerCls, "abortPacifier", "(II)I");
|
|
if ( mid == NULL ) {
|
|
perror("Ups, method not found.\n");
|
|
return -1;
|
|
}
|
|
return (*env)->CallIntMethod(env, (jobject) handle, mid, patience, elapsed);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_set_signal_handling
|
|
* Signature: (Lorg/pykix/libburnia/libburn/Burn$SignalHandler;I)V
|
|
*/
|
|
JNIEXPORT void JNICALL Java_org_pykix_libburnia_libburn_Burn_burn_1set_1signal_1handling
|
|
(
|
|
JNIEnv *env, jclass cls, jobject handler, jint mode
|
|
)
|
|
{
|
|
jobject sh =(*env)->NewGlobalRef(env, handler);
|
|
burn_set_signal_handling( sh, java_libburn_signal_handler, mode);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_set_default_signal_handling
|
|
* Signature: (Ljava/lang/String;I)V
|
|
*/
|
|
JNIEXPORT void JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1set_1default_1signal_1handling
|
|
(
|
|
JNIEnv *env, jclass cls, jstring msg, jint mode
|
|
)
|
|
{
|
|
const char *message = NULL;
|
|
|
|
if (msg != NULL) {
|
|
message = (*env)->GetStringUTFChars(env, msg, NULL);
|
|
if ( message == NULL ) {
|
|
return; /* OutOfMemoryError already thrown */
|
|
}
|
|
}
|
|
|
|
burn_set_signal_handling((void *) message, NULL, mode);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, msg, message);
|
|
}
|
|
|
|
static int java_libburn_signal_handler(void *handle, int signum, int flag)
|
|
{
|
|
/* call back to java */
|
|
JNIEnv *env;
|
|
jclass handlerCls;
|
|
|
|
env = java_libburn_get_env();
|
|
|
|
if ( env == NULL ) {
|
|
perror("Ups, can't call back to java handler, just aborting... please wait\n");
|
|
burn_abort(5, NULL, NULL);
|
|
return -1;
|
|
}
|
|
|
|
handlerCls = (*env)->FindClass(env, "org/pykix/libburnia/libburn/Burn$SignalHandler");
|
|
if ( handlerCls == NULL ) {
|
|
perror("Ups, java handler not found, just aborting... please wait\n");
|
|
burn_abort(5, NULL, NULL);
|
|
return -1;
|
|
}
|
|
|
|
jmethodID mid = (*env)->GetMethodID(env, handlerCls, "handleSignal", "(II)I");
|
|
if ( mid == NULL ) {
|
|
perror("Ups, method not found, just aborting... please wait\n");
|
|
burn_abort(5, NULL, NULL);
|
|
return -1;
|
|
}
|
|
return (*env)->CallIntMethod(env, (jobject) handle, mid, signum, flag);
|
|
}
|
|
|
|
/*
|
|
* Class: org_pykix_libburnia_libburn_Burn
|
|
* Method: burn_version
|
|
* Signature: ()Lorg/pykix/libburnia/libburn/Burn$Version;
|
|
*/
|
|
JNIEXPORT jobject JNICALL
|
|
Java_org_pykix_libburnia_libburn_Burn_burn_1version
|
|
(
|
|
JNIEnv *env, jclass cls
|
|
)
|
|
{
|
|
int major;
|
|
int minor;
|
|
int micro;
|
|
static jclass versionCls = NULL;
|
|
static jmethodID cid = NULL;
|
|
|
|
if ( versionCls == NULL ) {
|
|
versionCls = java_libburn_find_class(env, "org/pykix/libburnia/libburn/Burn$Version");
|
|
if ( versionCls == NULL ) {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if ( cid == NULL ) {
|
|
cid = (*env)->GetMethodID(env, versionCls, "<init>", "(III)V");
|
|
if (cid == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
}
|
|
|
|
burn_version(&major, &minor, µ);
|
|
|
|
return (*env)->NewObject(env, versionCls, cid, major, minor, micro);
|
|
}
|
|
|