/** * This DLL is being unloaded, do any clean up required. * This may be called more than once!! */ JNIEXPORT void JNICALL JNI_OnUnload (JavaVM * vm, void *reserved) { JNIEnv *env; void *keyInitCountPtr = GLOBAL_DATA (keyInitCount); void **jclIdCache = GLOBAL_DATA (JCL_ID_CACHE); if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_2) == JNI_OK) { JniIDCache *idCache = (JniIDCache *) HY_VMLS_GET (env, *jclIdCache); if (idCache) { JCLZipFileLink *zipfileHandles; JCLZipFile *jclZipFile; PORT_ACCESS_FROM_ENV (env); #ifdef HY_ZIP_API VMI_ACCESS_FROM_ENV(env); VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI); #endif /* HY_ZIP_API */ /* Detach from the common library */ ClearLibDetach (env); /* Close and free the HyZipFile handles */ zipfileHandles = JCL_CACHE_GET (env, zipfile_handles); if (zipfileHandles != NULL) { jclZipFile = zipfileHandles->next; while (jclZipFile != NULL) { JCLZipFile *next = jclZipFile->next; #ifndef HY_ZIP_API zip_closeZipFile (PORTLIB, &jclZipFile->hyZipFile); #else /* HY_ZIP_API */ zipFuncs->zip_closeZipFile (VMI, &jclZipFile->hyZipFile); #endif /* HY_ZIP_API */ jclmem_free_memory (env, jclZipFile); jclZipFile = next; } MUTEX_DESTROY (zipfileHandles->mutex); jclmem_free_memory (env, zipfileHandles); } /* Free any global references */ freeReferences (env); /* Free VMLS keys */ idCache = (JniIDCache *) HY_VMLS_GET (env, *jclIdCache); HY_VMLS_FNTBL (env)->HYVMLSFreeKeys (env, keyInitCountPtr, jclIdCache, NULL); hymem_free_memory (idCache); } } }
JNIEXPORT void JNICALL Java_java_util_zip_ZipFile_closeZipImpl (JNIEnv * env, jobject recv) { PORT_ACCESS_FROM_ENV (env); I_32 retval = 0; JCLZipFile *jclZipFile; jfieldID descriptorFID = JCL_CACHE_GET (env, FID_java_util_zip_ZipFile_descriptor); jclZipFile = (JCLZipFile *) (IDATA) (*env)->GetLongField (env, recv, descriptorFID); if (jclZipFile != (void *) -1) { retval = zip_closeZipFile (privatePortLibrary, &(jclZipFile->hyZipFile)); (*env)->SetLongField (env, recv, descriptorFID, -1); /* Free the zip struct */ if (jclZipFile->last != NULL) jclZipFile->last->next = jclZipFile->next; if (jclZipFile->next != NULL) jclZipFile->next->last = jclZipFile->last; jclmem_free_memory (env, jclZipFile); if (retval) { throwJavaZIOException (env, ""); return; } } }
JNIEXPORT void JNICALL Java_java_util_zip_Deflater_setDictionaryImpl (JNIEnv * env, jobject recv, jbyteArray dict, int off, int len, jlong handle) { PORT_ACCESS_FROM_ENV (env); int err = 0; char *dBytes; JCLZipStream *stream = (JCLZipStream *) ((IDATA) handle); dBytes = jclmem_allocate_memory (env, len); if (dBytes == NULL) { throwNewOutOfMemoryError (env, ""); return; } (*env)->GetByteArrayRegion (env, dict, off, len, (jbyte *) dBytes); err = deflateSetDictionary (stream->stream, (Bytef *) dBytes, len); if (err != Z_OK) { jclmem_free_memory (env, dBytes); THROW_ZIP_EXCEPTION(env, err, IllegalArgumentException); return; } stream->dict = (U_8*) dBytes; }
JNIEXPORT void JNICALL Java_java_util_zip_Deflater_endImpl (JNIEnv * env, jobject recv, jlong handle) { PORT_ACCESS_FROM_ENV (env); JCLZipStream *stream; stream = (JCLZipStream *) ((IDATA) handle); deflateEnd (stream->stream); if (stream->inaddr != NULL) jclmem_free_memory (env, stream->inaddr); if (stream->dict != NULL) jclmem_free_memory (env, stream->dict); jclmem_free_memory (env, stream->stream); jclmem_free_memory (env, stream); }
JNIEXPORT void JNICALL Java_java_util_zip_Deflater_setInputImpl (JNIEnv * env, jobject recv, jbyteArray buf, jint off, jint len, jlong handle) { PORT_ACCESS_FROM_ENV (env); jbyte *in; JCLZipStream *stream; stream = (JCLZipStream *) ((IDATA) handle); if (stream->inaddr != NULL) /*Input has already been provided, free the old buffer */ jclmem_free_memory (env, stream->inaddr); stream->inaddr = jclmem_allocate_memory (env, len); if (stream->inaddr == NULL) { throwNewOutOfMemoryError (env, ""); return; } in = ((*env)->GetPrimitiveArrayCritical (env, buf, 0)); if (in == NULL) { throwNewOutOfMemoryError(env, ""); return; } memcpy (stream->inaddr, (in + off), len); ((*env)->ReleasePrimitiveArrayCritical (env, buf, in, JNI_ABORT)); stream->stream->next_in = (Bytef *) stream->inaddr; stream->stream->avail_in = len; return; }
JNIEXPORT jint JNICALL Java_java_util_zip_ZipFile_openZipImpl (JNIEnv * env, jobject recv, jbyteArray zipName) { VMI_ACCESS_FROM_ENV (env); PORT_ACCESS_FROM_ENV (env); I_32 retval; JCLZipFile *jclZipFile; JCLZipFileLink *zipfileHandles; jsize length; char pathCopy[HyMaxPath]; HyZipCachePool *zipCachePool; jclZipFile = jclmem_allocate_memory (env, sizeof (*jclZipFile)); if (!jclZipFile) return 3; length = (*env)->GetArrayLength (env, zipName); length = length < HyMaxPath - 1 ? length : HyMaxPath - 1; ((*env)->GetByteArrayRegion (env, zipName, 0, length, pathCopy)); pathCopy[length++] = '\0'; ioh_convertToPlatform (pathCopy); /* Open the zip file (caching will be managed automatically by zipsup) */ zipCachePool = (*VMI)->GetZipCachePool (VMI); retval = zip_openZipFile (privatePortLibrary, pathCopy, &(jclZipFile->hyZipFile), zipCachePool); if (retval) { jclmem_free_memory (env, jclZipFile); /* free on fail */ if (retval == ZIP_ERR_FILE_OPEN_ERROR) return 1; else return 2; } /* Add the zipFile we just allocated to the list of zip files -- we will * free this on UnLoad if its not already free'd. */ zipfileHandles = JCL_CACHE_GET (env, zipfile_handles); jclZipFile->last = (JCLZipFile *) zipfileHandles; jclZipFile->next = zipfileHandles->next; if (zipfileHandles->next != NULL) zipfileHandles->next->last = jclZipFile; zipfileHandles->next = jclZipFile; (*env)->SetLongField (env, recv, JCL_CACHE_GET (env, FID_java_util_zip_ZipFile_descriptor), ((IDATA) jclZipFile)); return 0; }
/* Create a new stream . This stream cannot be used until it has been properly initialized. */ JNIEXPORT jlong JNICALL Java_java_util_zip_Deflater_createStream (JNIEnv * env, jobject recv, jint level, jint strategy, jboolean noHeader) { PORT_ACCESS_FROM_ENV (env); JCLZipStream *jstream; z_stream *stream; int err = 0; int wbits = 15; /*Use MAX for fastest */ #ifdef HY_ZIP_API VMI_ACCESS_FROM_ENV (env); VMIZipFunctionTable *zipFuncs; zipFuncs = (*VMI)->GetZipFunctions(VMI); #endif /*Allocate mem for wrapped struct */ jstream = jclmem_allocate_memory (env, sizeof (JCLZipStream)); if (jstream == NULL) { throwNewOutOfMemoryError (env, ""); return -1; } /*Allocate the z_stream */ stream = jclmem_allocate_memory (env, sizeof (z_stream)); if (stream == NULL) { jclmem_free_memory (env, jstream); throwNewOutOfMemoryError (env, ""); return -1; } stream->opaque = (void *) privatePortLibrary; stream->zalloc = zalloc; stream->zfree = zfree; jstream->stream = stream; jstream->dict = NULL; jstream->inaddr = NULL; /*Unable to find official doc that this is the way to avoid zlib header use. However doc in zipsup.c claims it is so */ if (noHeader) wbits = wbits / -1; err = deflateInit2 (stream, level, Z_DEFLATED, /*Only supported ZLIB method */ wbits, /*Window bits to use. 15 is fastest but consumes the most memory */ 9, /*Memory allocation for internal compression state. 9 uses the most. */ strategy); if (err != Z_OK) { THROW_ZIP_EXCEPTION(env, err, IllegalArgumentException); return -1; } return (jlong) ((IDATA) jstream); }
createZipEntry (JNIEnv * env, VMIZipFile * zipFile, VMIZipEntry * zipEntry) #endif { PORT_ACCESS_FROM_ENV (env); #ifdef HY_ZIP_API VMI_ACCESS_FROM_ENV(env); #endif /* HY_ZIP_API */ jclass javaClass; jobject java_ZipEntry, extra, entryName; jmethodID mid; #ifdef HY_ZIP_API VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI); #endif /* HY_ZIP_API */ /* Build a new ZipEntry from the C struct */ entryName = ((*env)->NewStringUTF (env, (const char*)zipEntry->filename)); if (((*env)->ExceptionCheck (env))) return NULL; extra = NULL; if (zipEntry->extraFieldLength > 0) { #ifndef HY_ZIP_API zip_getZipEntryExtraField (PORTLIB, zipFile, zipEntry, NULL, #else /* HY_ZIP_API */ zipFuncs->zip_getZipEntryExtraField (VMI, zipFile, zipEntry, NULL, #endif /* HY_ZIP_API */ zipEntry->extraFieldLength); if (zipEntry->extraField == NULL) return NULL; extra = ((*env)->NewByteArray (env, zipEntry->extraFieldLength)); if (((*env)->ExceptionCheck (env))) return NULL; ((*env)-> SetByteArrayRegion (env, extra, 0, zipEntry->extraFieldLength, (jbyte*)zipEntry->extraField)); jclmem_free_memory (env, zipEntry->extraField); zipEntry->extraField = NULL; }
JNIEXPORT jobject JNICALL Java_java_util_zip_ZipFile_00024ZFEnum_getNextEntry (JNIEnv * env, jobject recv, jlong descriptor, jlong nextEntry) { PORT_ACCESS_FROM_ENV (env); I_32 retval; HyZipFile *zipFile; HyZipEntry zipEntry; jobject java_ZipEntry, extra; jclass javaClass; jmethodID mid; jstring entryName = NULL; IDATA nextEntryPointer; JCLZipFile *jclZipFile = (JCLZipFile *) (IDATA) descriptor; if (jclZipFile == (void *) -1) { throwNewIllegalStateException (env, ""); return NULL; } zipFile = &(jclZipFile->hyZipFile); zip_initZipEntry (PORTLIB, &zipEntry); nextEntryPointer = (IDATA) nextEntry; retval = zip_getNextZipEntry (PORTLIB, zipFile, &zipEntry, &nextEntryPointer); if (retval) { if (retval != ZIP_ERR_NO_MORE_ENTRIES) { char buf[40]; sprintf (buf, "Error %d getting next zip entry", retval); throwNewInternalError (env, buf); } return (jobject) NULL; } /* Build a new ZipEntry from the C struct */ entryName = ((*env)->NewStringUTF (env, zipEntry.filename)); if (((*env)->ExceptionCheck (env))) return NULL; extra = NULL; if (zipEntry.extraFieldLength > 0) { zip_getZipEntryExtraField (PORTLIB, zipFile, &zipEntry, NULL, zipEntry.extraFieldLength); extra = ((*env)->NewByteArray (env, zipEntry.extraFieldLength)); if (((*env)->ExceptionCheck (env))) { /* free the extraField entry */ zip_freeZipEntry (PORTLIB, &zipEntry); return NULL; } ((*env)-> SetByteArrayRegion (env, extra, 0, zipEntry.extraFieldLength, zipEntry.extraField)); jclmem_free_memory (env, zipEntry.extraField); zipEntry.extraField = NULL; } javaClass = JCL_CACHE_GET (env, CLS_java_util_zip_ZipEntry); javaClass = (*env)->NewLocalRef(env, javaClass); if (javaClass == NULL) { return NULL; } mid = JCL_CACHE_GET (env, MID_java_util_zip_ZipEntry_init); java_ZipEntry = ((*env)->NewObject (env, javaClass, mid, entryName, NULL, /* comment */ extra, (jlong) zipEntry.lastModTime, (jlong) zipEntry.uncompressedSize, (jlong) zipEntry.compressedSize, (jlong) zipEntry.crc32, zipEntry.compressionMethod, (jlong) zipEntry.lastModDate, (jlong) zipEntry.dataPointer)); zip_freeZipEntry (PORTLIB, &zipEntry); (*env)->SetLongField (env, recv, JCL_CACHE_GET (env, FID_java_util_zip_ZipFile_nextEntryPointer), nextEntryPointer); return java_ZipEntry; }
/** * Create a System Process with the specified * environment and arguments */ JNIEXPORT jlongArray JNICALL Java_org_apache_harmony_luni_internal_process_SystemProcess_createImpl (JNIEnv * env, jclass clazz, jobject recv, jobjectArray arg1, jobjectArray arg2, jbyteArray dir) { jbyteArray envString; jlongArray pVals = NULL; jlong npVals[4]; char *envArray[256]; char *command[256]; int i, retVal; IDATA pHandle, inHandle, outHandle, errHandle; int envLength, commandLineLength, len; char *workingDir = NULL; PORT_ACCESS_FROM_ENV (env); /* validate sizes */ commandLineLength = (*env)->GetArrayLength (env, arg1); envLength = (*env)->GetArrayLength (env, arg2); if (commandLineLength >= 255) { throwJavaIoIOException(env, "Too many arguments"); return NULL; } if (envLength >= 255) { throwJavaIoIOException(env, "Too many environment arguments"); return NULL; } memset (command, 0, sizeof (command)); memset (envArray, 0, sizeof (envArray)); /* Get the command string and arguments */ /* convert java.lang.String into C char* */ for (i = commandLineLength; --i >= 0;) { jbyteArray element = (*env)->GetObjectArrayElement (env, arg1, i); len = (*env)->GetArrayLength (env, element); command[i] = jclmem_allocate_memory (env, len + 1); if (command[i] == NULL) { throwNewOutOfMemoryError (env, ""); goto failed; } (*env)->GetByteArrayRegion (env, element, 0, len, (jbyte *)command[i]); command[i][len] = 0; } if (envLength) for (i = 0; i < envLength; i++) { envString = (*env)->GetObjectArrayElement (env, arg2, i); len = (*env)->GetArrayLength (env, envString); envArray[i] = jclmem_allocate_memory (env, len + 1); if (envArray[i] == NULL) { throwNewOutOfMemoryError (env, ""); goto failed; } (*env)->GetByteArrayRegion (env, envString, 0, len, (jbyte *)envArray[i]); envArray[i][len] = 0; } /* NULL terminate for UNIX (does work on windows too; in fact, it doesn't care) */ command[commandLineLength] = NULL; envArray[envLength] = NULL; if (dir != NULL) { jsize dirLength = (*env)->GetArrayLength (env, dir); workingDir = jclmem_allocate_memory (env, dirLength + 1); if (workingDir) { (*env)->GetByteArrayRegion (env, dir, 0, dirLength, (jbyte *) workingDir); workingDir[dirLength] = '\0'; } } /* * now call execProgram. Any non-zero return code * indicates some kind of failure */ retVal = execProgram (env, recv, command, commandLineLength, envArray, envLength, workingDir, &pHandle, &inHandle, &outHandle, &errHandle); if (workingDir) { jclmem_free_memory (env, workingDir); } if (retVal) { char errMsg[256]; /* Failed to exec program */ switch(retVal) { case 1001 : sprintf(errMsg, "Unable to start program : %s", "fork() failed with errno = EOMEM"); break; case 1002 : sprintf(errMsg, "Unable to start program : %s", "fork() failed with errno = EAGAIN"); break; default: sprintf(errMsg, "Unable to start program : %s", "unknown"); break; } throwJavaIoIOException(env, errMsg); goto failed; } pVals = (*env)->NewLongArray (env, 4); if (pVals) { npVals[0] = (jlong) pHandle; npVals[1] = (jlong) inHandle; npVals[2] = (jlong) outHandle; npVals[3] = (jlong) errHandle; (*env)->SetLongArrayRegion (env, pVals, 0, 4, (jlong *) (&npVals)); } failed: for (i = 0; i < envLength; i++) { if (envArray[i]) jclmem_free_memory (env, envArray[i]); } for (i = commandLineLength; --i >= 0;) { if (command[i]) jclmem_free_memory (env, command[i]); } return pVals; }