legacy/experimental/java-libburnia/src/jni/libburn/Burn.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, &micro);
return (*env)->NewObject(env, versionCls, cid, major, minor, micro);
}