KNI_RETURNTYPE_OBJECT
KNIDECL(com_sun_midp_security_Permissions_loadGroupList)
{
    int lines, i1;
    void* array;

    KNI_StartHandles(2);
    KNI_DeclareHandle(groups);
    KNI_DeclareHandle(tmpString);
    
    lines = permissions_load_group_list(&array);
    if (lines > 0) {
        char** list = (char**)array;
        SNI_NewArray(SNI_STRING_ARRAY,  lines, groups);
        if (KNI_IsNullHandle(groups))
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
        else
            for (i1 = 0; i1 < lines; i1++) {
                KNI_NewStringUTF(list[i1], tmpString);
                KNI_SetObjectArrayElement(groups, (jint)i1, tmpString);
            }
        permissions_dealloc(array);
    } else
        KNI_ReleaseHandle(groups); /* set object to NULL */

    KNI_EndHandlesAndReturnObject(groups);
}
Esempio n. 2
0
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(KNITest_newStringArray) {
    jint len = KNI_GetParameterAsInt(1);
    KNI_StartHandles(1);
    KNI_DeclareHandle(newStrArray);
    SNI_NewArray(SNI_STRING_ARRAY, len, newStrArray);
    KNI_EndHandlesAndReturnObject(newStrArray);
}
Esempio n. 3
0
/* This is called by the last active TextFieldLFImpl to retrieve
 * the contents of the native editor, which was saved by
 * MIDPWindow.disableAndSyncNativeEditor() into a malloc'ed buffer above.
 * See disableAndSyncNativeEditor above for more info.
 */
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(javax_microedition_lcdui_TextFieldLFImpl_mallocToJavaChars) {
    int strLen = KNI_GetParameterAsInt(2);
    jchar *tmp = (jchar*)KNI_GetParameterAsInt(1);

    KNI_StartHandles(1);
    KNI_DeclareHandle(chars);
#if 0
    SNI_NewArray(SNI_CHAR_ARRAY, strLen, chars);
    if (!KNI_IsNullHandle(chars)) {
        memcpy(JavaCharArray(chars), tmp, strLen*sizeof(jchar));
    }
#endif
    midpFree((void*)tmp);
    KNI_EndHandlesAndReturnObject(chars);
}
KNI_RETURNTYPE_OBJECT
KNIDECL(com_sun_midp_security_Permissions_loadGroupPermissions)
{
    int lines, i1;
	unsigned int str_len;
    void *array;
    jchar jbuff[64];
    char  group_name[64];

    KNI_StartHandles(3);
    KNI_DeclareHandle(members);
    KNI_DeclareHandle(tmpString);
    KNI_DeclareHandle(group);

    KNI_GetParameterAsObject(1, group);
    if (!KNI_IsNullHandle(group)) {
        str_len = KNI_GetStringLength(group);
        if (str_len <= sizeof(group_name)-1) {
            KNI_GetStringRegion(group, 0, str_len, jbuff);
            jchar_to_char(jbuff, group_name, str_len);
            lines = permissions_load_group_permissions(&array, group_name);
            if (lines > 0) {
                char **list = (char**)array;
                SNI_NewArray(SNI_STRING_ARRAY,  lines, members);
                if (KNI_IsNullHandle(members))
                    KNI_ThrowNew(midpOutOfMemoryError, NULL);
                else
                    for (i1 = 0; i1 < lines; i1++) {
                        KNI_NewStringUTF(list[i1], tmpString);
                        KNI_SetObjectArrayElement(members, (jint)i1,
                                                            tmpString);
                    }
                permissions_dealloc(array);
            } else
                KNI_ReleaseHandle(members);  /* set object to NULL */
        }
    } else
        KNI_ThrowNew(midpNullPointerException, "null group parameter");


    KNI_EndHandlesAndReturnObject(members);
}
Esempio n. 5
0
/* Return the content of the editor in a Java string. */
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(javax_microedition_lcdui_TextFieldLFImpl_getNativeEditorContent) {
    KNI_StartHandles(1);
    KNI_DeclareHandle(chars);
#if 0
    if (editBoxShown) {
        int strLen = GetWindowTextLength(hwndTextActive);
        jchar *tmp = (jchar*)midpMalloc((strLen + 1) * sizeof(jchar));
        if (tmp) {
            GetWindowText(hwndTextActive, (LPTSTR)tmp, strLen+1); /* 0-terminated */
            SNI_NewArray(SNI_CHAR_ARRAY, strLen, chars);
            if (!KNI_IsNullHandle(chars)) {
                memcpy(JavaCharArray(chars), tmp, strLen*sizeof(jchar));
            }
            midpFree((void*)tmp);
        }
    }
#endif
    KNI_EndHandlesAndReturnObject(chars);
}
Esempio n. 6
0
/**
 * public static native int[] getFreedRendezvousPoints();
 *
 * Returns an array of freed rendezvous points. Resets the list to empty after
 * it's called.
 */
KNIEXPORT KNI_RETURNTYPE_OBJECT
Java_com_sun_midp_links_Utils_getFreedRendezvousPoints(void)
{
    int i;
    KNI_StartHandles(1);
    KNI_DeclareHandle(arrayReturn);

    SNI_NewArray(SNI_INT_ARRAY, freeptr, arrayReturn);

    /*
     * Use SetRawArrayRegion? Maybe assumes too many things about
     * int sizes.
     */
    for (i = 0; i < freeptr; i++) {
        KNI_SetIntArrayElement(arrayReturn, i, (jint)freelog[i]);
    }
    freeptr = 0;

    KNI_EndHandlesAndReturnObject(arrayReturn);
}
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(com_sun_midp_chameleon_skins_resources_LoadedSkinData_readIntArray) {
    int arrayLength;
    int totalBytes;

    KNI_StartHandles(1);
    KNI_DeclareHandle(returnArray);

    do {
        /*
         * First, read array length
         */
        ENSURE_SKIN_DATA_AVAILABILITY(sizeof(jint));
        memcpy((void*)&arrayLength, (void*)gsSkinFileDataPos, sizeof(jint));
        gsSkinFileDataPos += sizeof(jint);

        /*
         * Then create array
         */
        totalBytes = arrayLength * sizeof(jint);
        ENSURE_SKIN_DATA_AVAILABILITY(totalBytes);

        SNI_NewArray(SNI_INT_ARRAY, arrayLength, returnArray);
        if (KNI_IsNullHandle(returnArray)) {
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
            break;
        }

        /*
         * And finally read data into it
         */
        KNI_SetRawArrayRegion(returnArray, 0, totalBytes, (jbyte*)gsSkinFileDataPos);
        gsSkinFileDataPos += totalBytes;

    } while (0);

    KNI_EndHandlesAndReturnObject(returnArray);
}
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(com_sun_midp_chameleon_skins_resources_LoadedSkinData_readByteArray) {
    int arrayLength = KNI_GetParameterAsInt(1);

    KNI_StartHandles(1);
    KNI_DeclareHandle(returnArray);

    do {
        ENSURE_SKIN_DATA_AVAILABILITY(arrayLength);

        SNI_NewArray(SNI_BYTE_ARRAY, arrayLength, returnArray);
        if (KNI_IsNullHandle(returnArray)) {
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
            break;
        }

        KNI_SetRawArrayRegion(returnArray, 0, arrayLength, (jbyte*)gsSkinFileDataPos);
        gsSkinFileDataPos += arrayLength;

    } while (0);

    KNI_EndHandlesAndReturnObject(returnArray);
}
KNIEXPORT KNI_RETURNTYPE_OBJECT
KNIDECL(com_sun_midp_chameleon_skins_resources_LoadedSkinData_readStringArray) {
    int arrayLength;
    int i;

    KNI_StartHandles(2);
    KNI_DeclareHandle(returnArray);
    KNI_DeclareHandle(stringHandle);

    do {
        /*
         * First, read array length
         */
        ENSURE_SKIN_DATA_AVAILABILITY(sizeof(jint));
        memcpy((void*)&arrayLength, (void*)gsSkinFileDataPos, sizeof(jint));
        gsSkinFileDataPos += sizeof(jint);


        /*
         * Then create array
         */
        SNI_NewArray(SNI_STRING_ARRAY, arrayLength, returnArray);
        if (KNI_IsNullHandle(returnArray)) {
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
            break;
        }

        /*
         * And finally populate it with strings
         */
        for (i = 0; i < arrayLength; ++i) {
            unsigned char dataLength;
            unsigned char encoding;

            /* read data length */
            ENSURE_SKIN_DATA_AVAILABILITY(sizeof(char));
            dataLength = *((unsigned char*)gsSkinFileDataPos);
            gsSkinFileDataPos += 1;

            /* read encoding */
            ENSURE_SKIN_DATA_AVAILABILITY(sizeof(char));
            encoding = *((unsigned char*)gsSkinFileDataPos);
            gsSkinFileDataPos += 1;

            ENSURE_SKIN_DATA_AVAILABILITY(dataLength * sizeof(char));

            if (encoding == STRING_ENCODING_USASCII) {    
                int j;

                /* 
                 * In case of USASCII encoding, each byte of 
                 * string data corresponds to one string char
                 */
                int stringLength = dataLength;

                /* use gKNIBuffer for storing string chars */
                jchar* stringChars = (jchar*)gKNIBuffer;
                
                /* 
                 * Safety measure to prevent gKNIBuffer overflow 
                 * (which should never happens unless something is broken) 
                 */
                if (stringLength > (int)(KNI_BUFFER_SIZE/sizeof(jchar))) {
                    stringLength = (int)(KNI_BUFFER_SIZE/sizeof(jchar));
                    REPORT_WARN(LC_HIGHUI, 
                            "gKNIBuffer is too small for skin string");
                }

                /* fill string chars array */
                for (j = 0; j < stringLength; ++j) {
                    stringChars[j] = gsSkinFileDataPos[j];
                }

                /* and create string from it */
                KNI_NewString(stringChars, stringLength, stringHandle);
            } else if (encoding == STRING_ENCODING_UTF8) {
                KNI_NewStringUTF((char*)gsSkinFileDataPos, stringHandle);
            } else {
                KNI_ThrowNew(midpIllegalStateException, 
                        "Illegal skin string encoding");
                break;
            }
            
            KNI_SetObjectArrayElement(returnArray, i, stringHandle);

            gsSkinFileDataPos += dataLength;
        }

    } while (0);

    KNI_EndHandlesAndReturnObject(returnArray);
}
Esempio n. 10
0
/**
 * Load Java ImageData instance with image data in RAW format.
 * Image data is provided either in native buffer, or in Java
 * byte array. Java array is used with more priority.
 *
 * @param imageData Java ImageData object to be loaded with image data
 * @param nativeBuffer pointer to native buffer with raw image data,
 *          this parameter is alternative to javaBuffer
 * @param javaBuffer Java byte array with raw image data,
 *          this parameter is alternative to nativeBuffer
 * @param offset offset of the raw image data in the buffer
 * @param length length of the raw image data in the buffer
 *          starting from the offset
 *
 * @return KNI_TRUE in the case ImageData is successfully loaded with
 *    raw image data, otherwise KNI_FALSE.
 */
static int gx_load_imagedata_from_raw_buffer(KNIDECLARGS kjobject imageData,
    unsigned char *nativeBuffer, kjobject javaBuffer,
    int offset, int length) {

    int imageSize;
    int pixelSize, alphaSize;
    int status = KNI_FALSE;
    gxutl_image_buffer_raw *rawBuffer = NULL;

    KNI_StartHandles(2);
    KNI_DeclareHandle(pixelData);
    KNI_DeclareHandle(alphaData);

    do {
        /** Check native and Java buffer parameters */
        if (!KNI_IsNullHandle(javaBuffer)) {
            if (nativeBuffer != NULL) {
                REPORT_ERROR(LC_LOWUI,
                    "Native and Java buffers should not be used together");
                break;
            }
            nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS
                javaBuffer, offset, length);
        }
        if (nativeBuffer == NULL) {
            REPORT_ERROR(LC_LOWUI,
                "Null raw image buffer is provided");
            break;
        }

        /** Check header */
        rawBuffer = (gxutl_image_buffer_raw *)(nativeBuffer + offset);
        if (memcmp(rawBuffer->header, gxutl_raw_header, 4) != 0) {
            REPORT_ERROR(LC_LOWUI, "Unexpected raw image type");
            break;
        }

        imageSize = rawBuffer->width * rawBuffer->height;
        pixelSize = sizeof(gxj_pixel_type) * imageSize;
        alphaSize = 0;
        if (rawBuffer->hasAlpha) {
            alphaSize = sizeof(gxj_alpha_type) * imageSize;
        }

        /** Check data array length */
        if ((unsigned int)length !=
            (offsetof(gxutl_image_buffer_raw, data)
                + pixelSize + alphaSize)) {
            REPORT_ERROR(LC_LOWUI, "Raw image is corrupted");
            break;
        }

        if (rawBuffer->hasAlpha) {
            /* Has alpha */
            SNI_NewArray(SNI_BYTE_ARRAY, alphaSize, alphaData);
            if (KNI_IsNullHandle(alphaData)) {
                KNI_ThrowNew(midpOutOfMemoryError, NULL);
                break;
            }
            /** Link the new array into ImageData to protect if from GC */
            midp_set_jobject_field(KNIPASSARGS imageData, "alphaData", "[B", alphaData);

            /** New array allocation could cause GC and buffer moving */
            if (!KNI_IsNullHandle(javaBuffer)) {
                nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS
                    javaBuffer, offset, length);
                rawBuffer = (gxutl_image_buffer_raw *)
                    (nativeBuffer + offset);
            }
            memcpy(JavaByteArray(alphaData),
                rawBuffer->data + pixelSize, alphaSize);
        }

        SNI_NewArray(SNI_BYTE_ARRAY, pixelSize, pixelData);
        if (KNI_IsNullHandle(pixelData)) {
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
            break;
        }
	    midp_set_jobject_field(KNIPASSARGS imageData, "pixelData", "[B", pixelData);

        /** New array allocation could cause GC and buffer moving */
        if (!KNI_IsNullHandle(javaBuffer)) {
            nativeBuffer = gx_get_java_byte_buffer(KNIPASSARGS
                javaBuffer, offset, length);
            rawBuffer = (gxutl_image_buffer_raw *)
                (nativeBuffer + offset);
        }
	    memcpy(JavaByteArray(pixelData), rawBuffer->data, pixelSize);

        GXAPI_GET_IMAGEDATA_PTR(imageData)->width =
            (jint)rawBuffer->width;
        GXAPI_GET_IMAGEDATA_PTR(imageData)->height =
            (jint)rawBuffer->height;
        status = KNI_TRUE;

    } while(0);

    KNI_EndHandles();
    return status;
}
/**
 * Decodes the given byte array into the <tt>ImageData</tt>.
 * <p>
 * Java declaration:
 * <pre>
 *     loadNative(Ljavax/microedition/lcdui/ImageDataFactory;[BII)Z
 * </pre>
 *
 * @param imageData the ImageData to load to
 * @param imageBytes A byte array containing the encoded PNG image data
 * @param offset The start of the image data within the byte array
 * @param length The length of the image data in the byte array
 *
 * @return true if able to decode
 */
KNIEXPORT KNI_RETURNTYPE_BOOLEAN
KNIDECL(javax_microedition_lcdui_ImageDataFactory_loadNative) {
    int            length = KNI_GetParameterAsInt(4);
    int            offset = KNI_GetParameterAsInt(3);
    int            status = KNI_TRUE;
    unsigned char* srcBuffer = NULL;
    PIXEL* imgPixelData = NULL;
    ALPHA* imgAlphaData = NULL;
    java_imagedata* midpImageData = NULL;
	TBool generateMask = EFalse;

	KNI_StartHandles(4);
    KNI_DeclareHandle(pixelData);
    KNI_DeclareHandle(alphaData);
    KNI_DeclareHandle(inData);
    KNI_DeclareHandle(imageData);

    KNI_GetParameterAsObject(2, inData);
	KNI_GetParameterAsObject(1, imageData);
	midpImageData = IMGAPI_GET_IMAGEDATA_PTR(imageData);

    srcBuffer = (unsigned char *)JavaByteArray(inData);
	int byteArrayLength = KNI_GetArrayLength(inData);
	if (offset >= 0 && length >= 0 && offset + length <= byteArrayLength)
	{
		TPtrC8 sourceData(srcBuffer + offset, length);
		TInt width;
		TInt height;
		if (static_cast<MApplication*>(Dll::Tls())->InitializeDecoder(sourceData, width, height, generateMask) == KErrNone)
		{
			midpImageData->width = width;
			midpImageData->height = height;
		
			SNI_NewArray(SNI_BYTE_ARRAY, midpImageData->width * midpImageData->height * 2, pixelData);
			if (generateMask)
			{
				SNI_NewArray(SNI_BYTE_ARRAY, midpImageData->width * midpImageData->height, alphaData);
			}

			if (!KNI_IsNullHandle(pixelData) && (!KNI_IsNullHandle(alphaData) || !generateMask))
			{		
				if (generateMask)
				{
					imgAlphaData = (ALPHA*)JavaByteArray(alphaData);
				}

				midp_set_jobject_field(KNIPASSARGS imageData, "pixelData", "[B", pixelData);
				imgPixelData = (PIXEL*)JavaByteArray(pixelData);

				if (static_cast<MApplication*>(Dll::Tls())->DecodeImage((char*)imgPixelData, (char*)imgAlphaData) != KErrNone)
				{
					status = KNI_FALSE;
				}
				if (imgAlphaData)
				{
					midp_set_jobject_field(KNIPASSARGS imageData, "alphaData", "[B", alphaData);
				}
			}
            else
            {
                status = KNI_FALSE;
			}
        }
	}

	KNI_EndHandles();
    KNI_ReturnBoolean(status);
}
Esempio n. 12
0
/**
 * Copies the contents of fromMsg to the contents of toMsg. Both must be
 * instances of LinkMessage. The toLink object must be an instance of Link.
 * It's filled in if the contents of fromMsg are a Link.  Returns KNI_TRUE if
 * successful, otherwise KNI_FALSE.
 */
static jboolean
copy(jobject fromMsg, jobject toMsg, jobject toLink) {
    jboolean retval;

    KNI_StartHandles(6);
    KNI_DeclareHandle(byteArrayClass);
    KNI_DeclareHandle(stringClass);
    KNI_DeclareHandle(linkClass);
    KNI_DeclareHandle(fromContents);
    KNI_DeclareHandle(newString);
    KNI_DeclareHandle(newByteArray);

    KNI_FindClass("[B", byteArrayClass);
    KNI_FindClass("java/lang/String", stringClass);
    KNI_FindClass("com/sun/midp/links/Link", linkClass);
    getContents(fromMsg, fromContents);
    
    if (KNI_IsInstanceOf(fromContents, byteArrayClass)) {
        /* do a byte array copy */
        jint fromOffset;
        jint fromLength;

        getRange(fromMsg, &fromOffset, &fromLength);

        SNI_NewArray(SNI_BYTE_ARRAY, fromLength, newByteArray);
        if (KNI_IsNullHandle(newByteArray)) {
            retval = KNI_FALSE;
        } else {
            KNI_GetRawArrayRegion(fromContents, fromOffset, fromLength,
                SNI_GetRawArrayPointer(newByteArray));
            setContents(toMsg, newByteArray);
            setRange(toMsg, 0, fromLength);
            retval = KNI_TRUE;
        }
    } else if (KNI_IsInstanceOf(fromContents, stringClass)) {
        /* do a string copy */
        jchar *buf;
        jsize slen = KNI_GetStringLength(fromContents);

        SNI_NewArray(SNI_BYTE_ARRAY, slen*sizeof(jchar), newByteArray);

        if (KNI_IsNullHandle(newByteArray)) {
            retval = KNI_FALSE;
        } else {
            buf = SNI_GetRawArrayPointer(newByteArray);
            KNI_GetStringRegion(fromContents, 0, slen, buf);
            KNI_NewString(buf, slen, newString);
            setContents(toMsg, newString);
            retval = KNI_TRUE;
        }
    } else if (KNI_IsInstanceOf(fromContents, linkClass)) {
        /* copy the link */
        rendezvous *rp = getNativePointer(fromContents);
        setNativePointer(toLink, rp);
        rp_incref(rp);
        setContents(toMsg, toLink);
        retval = KNI_TRUE;
    } else {
        retval = KNI_FALSE;
    }

    KNI_EndHandles();
    return retval;
}
Esempio n. 13
0
/**
 * Performs reset of the card in the slot. This method must be called within
 * <tt>synchronize</tt> block with the Slot object.
 * <p>Java declaration:
 * <pre>
 * public native static byte[] reset0(Slot cardSlot) throws IOException;
 * </pre>
 * @param cardSlot Slot object
 * @return byte array with ATR
 * @exception NullPointerException if parameter is null
 * @exception IOException if any i/o troubles occured
 */
KNIEXPORT KNI_RETURNTYPE_OBJECT 
Java_com_sun_midp_io_j2me_apdu_APDUManager_reset0() {
    MidpReentryData* info;
    void *context = NULL;
    JSR177_STATUSCODE status_code;
    CardSlot *card_slot;
    jsize atr_length;
    char *err_msg;
    // IMPL_NOTE: I assumed that maximum length of ATR is 256 bytes
    jbyte atr_buffer[256]; 
    
    KNI_StartHandles(2);
    KNI_DeclareHandle(slot_handle);
    KNI_DeclareHandle(atr_handle);
    
    info = (MidpReentryData*)SNI_GetReentryData(NULL);
    
    KNI_GetParameterAsObject(1, slot_handle);
    if (!KNI_IsNullHandle(slot_handle)) {
        card_slot = unhand(CardSlot,(slot_handle));
    } else {
        KNI_ThrowNew(midpNullPointerException, "Slot object is null");
        goto end;
    }
    
    atr_length = sizeof atr_buffer;
    
    if (info == NULL || info->status == SIGNAL_LOCK) {
        if (!card_slot->locked) {
            status_code = jsr177_lock();
            if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) {
                midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, NULL);
                goto end;
            }
            if (status_code != JSR177_STATUSCODE_OK) {
                goto err;
            }
            card_slot->locked = KNI_TRUE;
// Since this line slot is locked
            status_code = jsr177_select_slot(card_slot->slot);
            if (status_code != JSR177_STATUSCODE_OK) {
                goto err;
            }
        }
        status_code = jsr177_reset_start(atr_buffer, &atr_length, &context);
    } else {
        context = info->pResult;
        status_code = 
            jsr177_reset_finish(atr_buffer, &atr_length, context);
    }
    if (status_code == JSR177_STATUSCODE_WOULD_BLOCK) {
        midp_thread_wait(CARD_READER_DATA_SIGNAL, SIGNAL_RESET, context);
        goto end;
    }

    if (status_code != JSR177_STATUSCODE_OK) {
    err:
        if (jsr177_get_error((jbyte*)gKNIBuffer, KNI_BUFFER_SIZE)) {
            err_msg = gKNIBuffer;
        } else {
            err_msg = "reset0()";
        }
        KNI_ThrowNew(midpIOException, err_msg);
        if (card_slot->locked) {
            status_code = jsr177_unlock(); // ignore status_code
            card_slot->locked = KNI_FALSE;
            midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK);
        }
        goto end;
    }
    status_code = jsr177_is_sat(card_slot->slot, &card_slot->SIMPresent);
    if (status_code != JSR177_STATUSCODE_OK) {
        goto err;
    }
    
    card_slot->cardSessionId++;
    card_slot->powered = KNI_TRUE;
    card_slot->locked = KNI_FALSE;
    midp_thread_signal(CARD_READER_DATA_SIGNAL, SIGNAL_LOCK, SIGNAL_LOCK);
    status_code = jsr177_unlock();
    if (status_code != JSR177_STATUSCODE_OK) {
        goto err;
    }
    SNI_NewArray(SNI_BYTE_ARRAY, atr_length, atr_handle);
    memcpy(JavaByteArray(atr_handle), atr_buffer, atr_length);
end:
    KNI_EndHandlesAndReturnObject(atr_handle);
}