annotate jdk/src/share/native/sun/security/smartcardio/pcsc.c @ 23704:c174349fcd4b

8030114: [parfait] warnings from b119 for jdk.src.share.native.sun.security.smartcardio: JNI exception pending Summary: Fix pending exception errors found by parfait. Reviewed-by: vinnie
author valeriep
date Wed, 02 Apr 2014 12:19:11 +0000
parents 202f599c92aa
children 9f7652fb03b2
rev   line source
duke@2 1 /*
valeriep@23704 2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
duke@2 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@2 4 *
duke@2 5 * This code is free software; you can redistribute it and/or modify it
duke@2 6 * under the terms of the GNU General Public License version 2 only, as
ohair@5506 7 * published by the Free Software Foundation. Oracle designates this
duke@2 8 * particular file as subject to the "Classpath" exception as provided
ohair@5506 9 * by Oracle in the LICENSE file that accompanied this code.
duke@2 10 *
duke@2 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@2 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@2 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@2 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@2 15 * accompanied this code).
duke@2 16 *
duke@2 17 * You should have received a copy of the GNU General Public License version
duke@2 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@2 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@2 20 *
ohair@5506 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@5506 22 * or visit www.oracle.com if you need additional information or have any
ohair@5506 23 * questions.
duke@2 24 */
duke@2 25
duke@2 26 /* disable asserts in product mode */
duke@2 27 #ifndef DEBUG
duke@2 28 #ifndef NDEBUG
duke@2 29 #define NDEBUG
duke@2 30 #endif
duke@2 31 #endif
duke@2 32
duke@2 33 #include <stdio.h>
duke@2 34 #include <stdlib.h>
duke@2 35 #include <string.h>
duke@2 36 #include <assert.h>
duke@2 37
duke@2 38 #include <winscard.h>
duke@2 39
duke@2 40 // #define J2PCSC_DEBUG
duke@2 41
duke@2 42 #ifdef J2PCSC_DEBUG
duke@2 43 #define dprintf(s) printf(s)
duke@2 44 #define dprintf1(s, p1) printf(s, p1)
duke@2 45 #define dprintf2(s, p1, p2) printf(s, p1, p2)
duke@2 46 #define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3)
duke@2 47 #else
duke@2 48 #define dprintf(s)
duke@2 49 #define dprintf1(s, p1)
duke@2 50 #define dprintf2(s, p1, p2)
duke@2 51 #define dprintf3(s, p1, p2, p3)
duke@2 52 #endif
duke@2 53
duke@2 54 #include "sun_security_smartcardio_PCSC.h"
duke@2 55
duke@2 56 #include "pcsc_md.h"
duke@2 57
duke@2 58 #define MAX_STACK_BUFFER_SIZE 8192
duke@2 59
duke@2 60 // make the buffers larger than what should be necessary, just in case
duke@2 61 #define ATR_BUFFER_SIZE 128
duke@2 62 #define READERNAME_BUFFER_SIZE 128
duke@2 63 #define RECEIVE_BUFFER_SIZE MAX_STACK_BUFFER_SIZE
duke@2 64
duke@2 65 #define J2PCSC_EXCEPTION_NAME "sun/security/smartcardio/PCSCException"
duke@2 66
valeriep@23704 67 extern void throwByName(JNIEnv *, const char *, const char *);
valeriep@23704 68
valeriep@23704 69 void throwOutOfMemoryError(JNIEnv *env, const char *msg) {
valeriep@23704 70 throwByName(env, "java/lang/OutOfMemoryError", msg);
valeriep@23704 71 }
valeriep@23704 72
duke@2 73 void throwPCSCException(JNIEnv* env, LONG code) {
duke@2 74 jclass pcscClass;
duke@2 75 jmethodID constructor;
duke@2 76 jthrowable pcscException;
duke@2 77
duke@2 78 pcscClass = (*env)->FindClass(env, J2PCSC_EXCEPTION_NAME);
valeriep@23704 79 if (pcscClass == NULL) {
valeriep@23704 80 return;
valeriep@23704 81 }
duke@2 82 constructor = (*env)->GetMethodID(env, pcscClass, "<init>", "(I)V");
valeriep@23704 83 if (constructor == NULL) {
valeriep@23704 84 return;
valeriep@23704 85 }
valeriep@23704 86 pcscException = (jthrowable) (*env)->NewObject(env, pcscClass,
valeriep@23704 87 constructor, (jint)code);
valeriep@23704 88 if (pcscException != NULL) {
valeriep@23704 89 (*env)->Throw(env, pcscException);
valeriep@23704 90 }
duke@2 91 }
duke@2 92
duke@2 93 jboolean handleRV(JNIEnv* env, LONG code) {
duke@2 94 if (code == SCARD_S_SUCCESS) {
duke@2 95 return JNI_FALSE;
duke@2 96 } else {
duke@2 97 throwPCSCException(env, code);
duke@2 98 return JNI_TRUE;
duke@2 99 }
duke@2 100 }
duke@2 101
duke@2 102 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
duke@2 103 return JNI_VERSION_1_4;
duke@2 104 }
duke@2 105
duke@2 106 JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardEstablishContext
duke@2 107 (JNIEnv *env, jclass thisClass, jint dwScope)
duke@2 108 {
duke@2 109 SCARDCONTEXT context;
duke@2 110 LONG rv;
duke@2 111 dprintf("-establishContext\n");
duke@2 112 rv = CALL_SCardEstablishContext(dwScope, NULL, NULL, &context);
duke@2 113 if (handleRV(env, rv)) {
duke@2 114 return 0;
duke@2 115 }
duke@2 116 // note: SCARDCONTEXT is typedef'd as long, so this works
duke@2 117 return (jlong)context;
duke@2 118 }
duke@2 119
duke@2 120 /**
duke@2 121 * Convert a multi string to a java string array,
duke@2 122 */
duke@2 123 jobjectArray pcsc_multi2jstring(JNIEnv *env, char *spec) {
duke@2 124 jobjectArray result;
duke@2 125 jclass stringClass;
duke@2 126 char *cp, **tab;
duke@2 127 jstring js;
duke@2 128 int cnt = 0;
duke@2 129
duke@2 130 cp = spec;
duke@2 131 while (*cp != 0) {
duke@2 132 cp += (strlen(cp) + 1);
duke@2 133 ++cnt;
duke@2 134 }
duke@2 135
duke@2 136 tab = (char **)malloc(cnt * sizeof(char *));
valeriep@23704 137 if (tab == NULL) {
valeriep@23704 138 throwOutOfMemoryError(env, NULL);
valeriep@23704 139 return NULL;
valeriep@23704 140 }
duke@2 141
duke@2 142 cnt = 0;
duke@2 143 cp = spec;
duke@2 144 while (*cp != 0) {
duke@2 145 tab[cnt++] = cp;
duke@2 146 cp += (strlen(cp) + 1);
duke@2 147 }
duke@2 148
duke@2 149 stringClass = (*env)->FindClass(env, "java/lang/String");
valeriep@23704 150 if (stringClass == NULL) {
valeriep@23704 151 free(tab);
valeriep@23704 152 return NULL;
valeriep@23704 153 }
duke@2 154
duke@2 155 result = (*env)->NewObjectArray(env, cnt, stringClass, NULL);
valeriep@23704 156 if (result != NULL) {
valeriep@23704 157 while (cnt-- > 0) {
valeriep@23704 158 js = (*env)->NewStringUTF(env, tab[cnt]);
valeriep@23704 159 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 160 free(tab);
valeriep@23704 161 return NULL;
valeriep@23704 162 }
valeriep@23704 163 (*env)->SetObjectArrayElement(env, result, cnt, js);
valeriep@23704 164 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 165 free(tab);
valeriep@23704 166 return NULL;
valeriep@23704 167 }
valeriep@23704 168 (*env)->DeleteLocalRef(env, js);
valeriep@23704 169 }
duke@2 170 }
duke@2 171 free(tab);
duke@2 172 return result;
duke@2 173 }
duke@2 174
duke@2 175 JNIEXPORT jobjectArray JNICALL Java_sun_security_smartcardio_PCSC_SCardListReaders
duke@2 176 (JNIEnv *env, jclass thisClass, jlong jContext)
duke@2 177 {
duke@2 178 SCARDCONTEXT context = (SCARDCONTEXT)jContext;
duke@2 179 LONG rv;
duke@2 180 LPTSTR mszReaders;
duke@2 181 DWORD size;
duke@2 182 jobjectArray result;
duke@2 183
duke@2 184 dprintf1("-context: %x\n", context);
duke@2 185 rv = CALL_SCardListReaders(context, NULL, NULL, &size);
duke@2 186 if (handleRV(env, rv)) {
duke@2 187 return NULL;
duke@2 188 }
duke@2 189 dprintf1("-size: %d\n", size);
duke@2 190
duke@2 191 mszReaders = malloc(size);
valeriep@23704 192 if (mszReaders == NULL) {
valeriep@23704 193 throwOutOfMemoryError(env, NULL);
valeriep@23704 194 return NULL;
valeriep@23704 195 }
valeriep@23704 196
duke@2 197 rv = CALL_SCardListReaders(context, NULL, mszReaders, &size);
duke@2 198 if (handleRV(env, rv)) {
duke@2 199 free(mszReaders);
duke@2 200 return NULL;
duke@2 201 }
duke@2 202 dprintf1("-String: %s\n", mszReaders);
duke@2 203
duke@2 204 result = pcsc_multi2jstring(env, mszReaders);
duke@2 205 free(mszReaders);
duke@2 206 return result;
duke@2 207 }
duke@2 208
duke@2 209 JNIEXPORT jlong JNICALL Java_sun_security_smartcardio_PCSC_SCardConnect
duke@2 210 (JNIEnv *env, jclass thisClass, jlong jContext, jstring jReaderName,
duke@2 211 jint jShareMode, jint jPreferredProtocols)
duke@2 212 {
duke@2 213 SCARDCONTEXT context = (SCARDCONTEXT)jContext;
duke@2 214 LONG rv;
duke@2 215 LPCTSTR readerName;
duke@2 216 SCARDHANDLE card;
duke@2 217 DWORD proto;
duke@2 218
duke@2 219 readerName = (*env)->GetStringUTFChars(env, jReaderName, NULL);
valeriep@23704 220 if (readerName == NULL) {
valeriep@23704 221 return 0;
valeriep@23704 222 }
duke@2 223 rv = CALL_SCardConnect(context, readerName, jShareMode, jPreferredProtocols, &card, &proto);
duke@2 224 (*env)->ReleaseStringUTFChars(env, jReaderName, readerName);
duke@2 225 dprintf1("-cardhandle: %x\n", card);
duke@2 226 dprintf1("-protocol: %d\n", proto);
duke@2 227 if (handleRV(env, rv)) {
duke@2 228 return 0;
duke@2 229 }
duke@2 230
duke@2 231 return (jlong)card;
duke@2 232 }
duke@2 233
duke@2 234 JNIEXPORT jbyteArray JNICALL Java_sun_security_smartcardio_PCSC_SCardTransmit
duke@2 235 (JNIEnv *env, jclass thisClass, jlong jCard, jint protocol,
duke@2 236 jbyteArray jBuf, jint jOfs, jint jLen)
duke@2 237 {
duke@2 238 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 239 LONG rv;
duke@2 240 SCARD_IO_REQUEST sendPci;
duke@2 241 unsigned char *sbuf;
duke@2 242 unsigned char rbuf[RECEIVE_BUFFER_SIZE];
duke@2 243 DWORD rlen = RECEIVE_BUFFER_SIZE;
duke@2 244 int ofs = (int)jOfs;
duke@2 245 int len = (int)jLen;
duke@2 246 jbyteArray jOut;
duke@2 247
duke@2 248 sendPci.dwProtocol = protocol;
duke@2 249 sendPci.cbPciLength = sizeof(SCARD_IO_REQUEST);
duke@2 250
duke@2 251 sbuf = (unsigned char *) ((*env)->GetByteArrayElements(env, jBuf, NULL));
valeriep@23704 252 if (sbuf == NULL) {
valeriep@23704 253 return NULL;
valeriep@23704 254 }
duke@2 255 rv = CALL_SCardTransmit(card, &sendPci, sbuf + ofs, len, NULL, rbuf, &rlen);
duke@2 256 (*env)->ReleaseByteArrayElements(env, jBuf, (jbyte *)sbuf, JNI_ABORT);
duke@2 257
duke@2 258 if (handleRV(env, rv)) {
duke@2 259 return NULL;
duke@2 260 }
duke@2 261
duke@2 262 jOut = (*env)->NewByteArray(env, rlen);
valeriep@23704 263 if (jOut != NULL) {
valeriep@23704 264 (*env)->SetByteArrayRegion(env, jOut, 0, rlen, (jbyte *)rbuf);
valeriep@23704 265 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 266 return NULL;
valeriep@23704 267 }
valeriep@23704 268 }
duke@2 269 return jOut;
duke@2 270 }
duke@2 271
duke@2 272 JNIEXPORT jbyteArray JNICALL Java_sun_security_smartcardio_PCSC_SCardStatus
duke@2 273 (JNIEnv *env, jclass thisClass, jlong jCard, jbyteArray jStatus)
duke@2 274 {
duke@2 275 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 276 LONG rv;
duke@2 277 char readerName[READERNAME_BUFFER_SIZE];
duke@2 278 DWORD readerLen = READERNAME_BUFFER_SIZE;
duke@2 279 unsigned char atr[ATR_BUFFER_SIZE];
duke@2 280 DWORD atrLen = ATR_BUFFER_SIZE;
duke@2 281 DWORD state;
duke@2 282 DWORD protocol;
duke@2 283 jbyteArray jArray;
valeriep@23704 284 jbyte status[2];
duke@2 285
duke@2 286 rv = CALL_SCardStatus(card, readerName, &readerLen, &state, &protocol, atr, &atrLen);
duke@2 287 if (handleRV(env, rv)) {
duke@2 288 return NULL;
duke@2 289 }
duke@2 290 dprintf1("-reader: %s\n", readerName);
duke@2 291 dprintf1("-status: %d\n", state);
duke@2 292 dprintf1("-protocol: %d\n", protocol);
duke@2 293
duke@2 294 jArray = (*env)->NewByteArray(env, atrLen);
valeriep@23704 295 if (jArray == NULL) {
valeriep@23704 296 return NULL;
valeriep@23704 297 }
duke@2 298 (*env)->SetByteArrayRegion(env, jArray, 0, atrLen, (jbyte *)atr);
valeriep@23704 299 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 300 return NULL;
valeriep@23704 301 }
valeriep@23704 302 status[0] = (jbyte) state;
valeriep@23704 303 status[1] = (jbyte) protocol;
valeriep@23704 304 (*env)->SetByteArrayRegion(env, jStatus, 0, 2, status);
valeriep@23704 305 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 306 return NULL;
valeriep@23704 307 }
duke@2 308 return jArray;
duke@2 309 }
duke@2 310
duke@2 311 JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardDisconnect
duke@2 312 (JNIEnv *env, jclass thisClass, jlong jCard, jint jDisposition)
duke@2 313 {
duke@2 314 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 315 LONG rv;
duke@2 316
duke@2 317 rv = CALL_SCardDisconnect(card, jDisposition);
duke@2 318 dprintf1("-disconnect: 0x%X\n", rv);
duke@2 319 handleRV(env, rv);
duke@2 320 return;
duke@2 321 }
duke@2 322
duke@2 323 JNIEXPORT jintArray JNICALL Java_sun_security_smartcardio_PCSC_SCardGetStatusChange
duke@2 324 (JNIEnv *env, jclass thisClass, jlong jContext, jlong jTimeout,
duke@2 325 jintArray jCurrentState, jobjectArray jReaderNames)
duke@2 326 {
duke@2 327 SCARDCONTEXT context = (SCARDCONTEXT)jContext;
duke@2 328 LONG rv;
duke@2 329 int readers = (*env)->GetArrayLength(env, jReaderNames);
valeriep@23704 330 SCARD_READERSTATE *readerState;
duke@2 331 int i;
valeriep@23704 332 jintArray jEventState = NULL;
valeriep@23704 333 int *currentState = NULL;
valeriep@23704 334 const char *readerName;
valeriep@23704 335
valeriep@23704 336 readerState = calloc(readers, sizeof(SCARD_READERSTATE));
valeriep@23704 337 if (readerState == NULL) {
valeriep@23704 338 throwOutOfMemoryError(env, NULL);
valeriep@23704 339 return NULL;
valeriep@23704 340 }
valeriep@23704 341
valeriep@23704 342 currentState = (*env)->GetIntArrayElements(env, jCurrentState, NULL);
valeriep@23704 343 if (currentState == NULL) {
valeriep@23704 344 free(readerState);
valeriep@23704 345 return NULL;
valeriep@23704 346 }
duke@2 347
duke@2 348 for (i = 0; i < readers; i++) {
duke@2 349 jobject jReaderName = (*env)->GetObjectArrayElement(env, jReaderNames, i);
valeriep@23704 350 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 351 goto cleanup;
valeriep@23704 352 }
valeriep@23704 353 readerName = (*env)->GetStringUTFChars(env, jReaderName, NULL);
valeriep@23704 354 if (readerName == NULL) {
valeriep@23704 355 goto cleanup;
valeriep@23704 356 }
valeriep@23704 357 readerState[i].szReader = strdup(readerName);
valeriep@23704 358 (*env)->ReleaseStringUTFChars(env, jReaderName, readerName);
valeriep@23704 359 if (readerState[i].szReader == NULL) {
valeriep@23704 360 throwOutOfMemoryError(env, NULL);
valeriep@23704 361 goto cleanup;
valeriep@23704 362 }
duke@2 363 readerState[i].pvUserData = NULL;
duke@2 364 readerState[i].dwCurrentState = currentState[i];
duke@2 365 readerState[i].dwEventState = SCARD_STATE_UNAWARE;
duke@2 366 readerState[i].cbAtr = 0;
valeriep@23704 367 (*env)->DeleteLocalRef(env, jReaderName);
duke@2 368 }
duke@2 369
duke@2 370 rv = CALL_SCardGetStatusChange(context, (DWORD)jTimeout, readerState, readers);
valeriep@23704 371 if (handleRV(env, rv)) {
valeriep@23704 372 goto cleanup;
valeriep@23704 373 }
duke@2 374
duke@2 375 jEventState = (*env)->NewIntArray(env, readers);
valeriep@23704 376 if (jEventState == NULL) {
valeriep@23704 377 goto cleanup;
valeriep@23704 378 }
duke@2 379 for (i = 0; i < readers; i++) {
duke@2 380 jint eventStateTmp;
duke@2 381 dprintf3("-reader status %s: 0x%X, 0x%X\n", readerState[i].szReader,
duke@2 382 readerState[i].dwCurrentState, readerState[i].dwEventState);
duke@2 383 eventStateTmp = (jint)readerState[i].dwEventState;
duke@2 384 (*env)->SetIntArrayRegion(env, jEventState, i, 1, &eventStateTmp);
valeriep@23704 385 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 386 jEventState = NULL;
valeriep@23704 387 goto cleanup;
valeriep@23704 388 }
valeriep@23704 389 }
valeriep@23704 390 cleanup:
valeriep@23704 391 (*env)->ReleaseIntArrayElements(env, jCurrentState, currentState, JNI_ABORT);
valeriep@23704 392 for (i = 0; i < readers; i++) {
valeriep@23704 393 free((char *)readerState[i].szReader);
duke@2 394 }
duke@2 395 free(readerState);
duke@2 396 return jEventState;
duke@2 397 }
duke@2 398
duke@2 399 JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardBeginTransaction
duke@2 400 (JNIEnv *env, jclass thisClass, jlong jCard)
duke@2 401 {
duke@2 402 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 403 LONG rv;
duke@2 404
duke@2 405 rv = CALL_SCardBeginTransaction(card);
duke@2 406 dprintf1("-beginTransaction: 0x%X\n", rv);
duke@2 407 handleRV(env, rv);
duke@2 408 return;
duke@2 409 }
duke@2 410
duke@2 411 JNIEXPORT void JNICALL Java_sun_security_smartcardio_PCSC_SCardEndTransaction
duke@2 412 (JNIEnv *env, jclass thisClass, jlong jCard, jint jDisposition)
duke@2 413 {
duke@2 414 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 415 LONG rv;
duke@2 416
duke@2 417 rv = CALL_SCardEndTransaction(card, jDisposition);
duke@2 418 dprintf1("-endTransaction: 0x%X\n", rv);
duke@2 419 handleRV(env, rv);
duke@2 420 return;
duke@2 421 }
duke@2 422
duke@2 423 JNIEXPORT jbyteArray JNICALL Java_sun_security_smartcardio_PCSC_SCardControl
duke@2 424 (JNIEnv *env, jclass thisClass, jlong jCard, jint jControlCode, jbyteArray jSendBuffer)
duke@2 425 {
duke@2 426 SCARDHANDLE card = (SCARDHANDLE)jCard;
duke@2 427 LONG rv;
valeriep@23704 428 jbyte* sendBuffer;
duke@2 429 jint sendBufferLength = (*env)->GetArrayLength(env, jSendBuffer);
duke@2 430 jbyte receiveBuffer[MAX_STACK_BUFFER_SIZE];
duke@2 431 jint receiveBufferLength = MAX_STACK_BUFFER_SIZE;
duke@2 432 ULONG returnedLength = 0;
duke@2 433 jbyteArray jReceiveBuffer;
duke@2 434
valeriep@23704 435 sendBuffer = (*env)->GetByteArrayElements(env, jSendBuffer, NULL);
valeriep@23704 436 if (sendBuffer == NULL) {
valeriep@23704 437 return NULL;
valeriep@23704 438 }
valeriep@23704 439
duke@2 440 #ifdef J2PCSC_DEBUG
duke@2 441 {
duke@2 442 int k;
duke@2 443 printf("-control: 0x%X\n", jControlCode);
duke@2 444 printf("-send: ");
duke@2 445 for (k = 0; k < sendBufferLength; k++) {
duke@2 446 printf("%02x ", sendBuffer[k]);
duke@2 447 }
duke@2 448 printf("\n");
duke@2 449 }
duke@2 450 #endif
duke@2 451
duke@2 452 rv = CALL_SCardControl(card, jControlCode, sendBuffer, sendBufferLength,
duke@2 453 receiveBuffer, receiveBufferLength, &returnedLength);
duke@2 454
duke@2 455 (*env)->ReleaseByteArrayElements(env, jSendBuffer, sendBuffer, JNI_ABORT);
duke@2 456 if (handleRV(env, rv)) {
duke@2 457 return NULL;
duke@2 458 }
duke@2 459
duke@2 460 #ifdef J2PCSC_DEBUG
duke@2 461 {
duke@2 462 int k;
duke@2 463 printf("-recv: ");
duke@2 464 for (k = 0; k < returnedLength; k++) {
duke@2 465 printf("%02x ", receiveBuffer[k]);
duke@2 466 }
duke@2 467 printf("\n");
duke@2 468 }
duke@2 469 #endif
duke@2 470
duke@2 471 jReceiveBuffer = (*env)->NewByteArray(env, returnedLength);
valeriep@23704 472 if (jReceiveBuffer == NULL) {
valeriep@23704 473 return NULL;
valeriep@23704 474 }
duke@2 475 (*env)->SetByteArrayRegion(env, jReceiveBuffer, 0, returnedLength, receiveBuffer);
valeriep@23704 476 if ((*env)->ExceptionCheck(env)) {
valeriep@23704 477 return NULL;
valeriep@23704 478 }
duke@2 479 return jReceiveBuffer;
duke@2 480 }