/* * 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, "", "(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, "", "(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, "", "(III)V"); if (cid == NULL) { return NULL; /* exception thrown */ } } burn_version(&major, &minor, µ); return (*env)->NewObject(env, versionCls, cid, major, minor, micro); }