Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * content manager for Android
- */
- #include <android/log.h>
- #include <stdio.h>
- #include "murmurhash3.h"
- #include "unzip.h"
- #include "content_manager.h"
- #define ACTIVITYTHREAD_CLASSNAME "android/app/ActivityThread"
- #define APPBINDDATA_CLASSNAME ACTIVITYTHREAD_CLASSNAME"$AppBindData"
- #define APPLICATIONINFO_CLASSNAME "android/content/pm/ApplicationInfo"
- #define ENVIRONMENT_CLASSNAME "android/os/Environment"
- #define FILE_CLASSNAME "java/io/File"
- #define STRING_CLASSNAME "java/lang/String"
- #define ACTIVITYTHREAD_CLASS_SIGNATURE "L"ACTIVITYTHREAD_CLASSNAME";"
- #define APPBINDDATA_CLASS_SIGNATURE "L"APPBINDDATA_CLASSNAME";"
- #define APPLICATIONINFO_CLASS_SIGNATURE "L"APPLICATIONINFO_CLASSNAME";"
- #define STRING_CLASS_SIGNATURE "L"STRING_CLASSNAME";"
- #define FILE_CLASS_SIGNATURE "L"FILE_CLASSNAME";"
- #define DATA_DIRECTORY "/Android/data"
- #define MEDIA_DIRECTORY "/Android/media"
- #define OBB_DIRECTORY "/Android/obb"
- #define LOG_TAG "ContentManager"
- #ifndef NDEBUG
- #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
- #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
- #else
- #define LOGD(...) do {} while (0)
- #define LOGE(...) do {} while (0)
- #define LOGW(...) do {} while (0)
- #define LOGI(...) do {} while (0)
- #endif
- #define STRING_BUFFERSIZE 512
- static char PackageName[STRING_BUFFERSIZE] = {0};
- static char DataDir[STRING_BUFFERSIZE] = {0};
- static char SourceDir[STRING_BUFFERSIZE] = {0};
- static char ExternalDirectory[STRING_BUFFERSIZE] = {0};
- static char ExternalDataDirectory[STRING_BUFFERSIZE] = {0};
- static char ExternalMediaDirectory[STRING_BUFFERSIZE] = {0};
- static char ExternalOBBDirectory[STRING_BUFFERSIZE] = {0};
- static unzFile APKFile = 0;
- typedef struct
- {
- unz64_file_pos file_pos;
- uLong uncompressed_size;
- } Content;
- static jclass cm_get_jclass(const char *class_name, JNIEnv *env)
- {
- jclass clazz = 0;
- if (env)
- {
- clazz = (*env)->FindClass(env, class_name);
- if ((*env)->ExceptionCheck(env))
- (*env)->ExceptionClear(env);
- }
- return clazz;
- }
- static jmethodID cm_get_jmethod(jclass clazz, const char *method_name, const char *signature, JNIEnv *env)
- {
- jmethodID methodId = 0;
- if (env)
- {
- methodId = (*env)->GetMethodID(env, clazz, method_name, signature);
- if ((*env)->ExceptionCheck(env))
- (*env)->ExceptionClear(env);
- }
- return methodId;
- }
- static jmethodID cm_get_static_jmethod(jclass clazz, const char *method_name, const char *signature, JNIEnv *env)
- {
- jmethodID methodId = 0;
- if (env)
- {
- methodId = (*env)->GetStaticMethodID(env, clazz, method_name, signature);
- if ((*env)->ExceptionCheck(env))
- (*env)->ExceptionClear(env);
- }
- return methodId;
- }
- static jfieldID cm_get_jfield(jclass clazz, const char *field_name, const char *signature, JNIEnv *env)
- {
- jfieldID fieldId = 0;
- if (env)
- {
- fieldId = (*env)->GetFieldID(env, clazz, field_name, signature);
- if ((*env)->ExceptionCheck(env))
- (*env)->ExceptionClear(env);
- }
- return fieldId;
- }
- int cm_initialize(JNIEnv *env)
- {
- int ret = 0;
- jclass jcActivityThread = 0, jcAppBindData = 0, jcApplicationInfo = 0, jcEnvironment = 0, jcFile = 0;
- jstring jsString = 0;
- jobject joActivityThread = 0, joAppBindData = 0, joAppInfo = 0, joFile = 0;
- jmethodID jmCurrentActivityThread, jmGetExtStorageDir, jmGetAbsolutePath;
- jfieldID jfAppInfo, jfBoundApplication, jfSourceDir, jfDataDir, jfPackageName;
- const char *package_name, *source_dir, *data_dir, *ext_storage_dir;
- if (!env)
- goto cm_initialize_error_;
- if ((*env)->PushLocalFrame(env, 10))
- goto cm_initialize_error_;
- if (!(jcActivityThread = cm_get_jclass(ACTIVITYTHREAD_CLASSNAME, env)))
- goto cm_initialize_error;
- if (!(jcAppBindData = cm_get_jclass(APPBINDDATA_CLASSNAME, env)))
- goto cm_initialize_error;
- if (!(jcApplicationInfo = cm_get_jclass(APPLICATIONINFO_CLASSNAME, env)))
- goto cm_initialize_error;
- if (!(jcEnvironment = cm_get_jclass(ENVIRONMENT_CLASSNAME, env)))
- goto cm_initialize_error;
- if (!(jcFile = cm_get_jclass(FILE_CLASSNAME, env)))
- goto cm_initialize_error;
- if (!(jmCurrentActivityThread = cm_get_static_jmethod(jcActivityThread, "currentActivityThread", "()"ACTIVITYTHREAD_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jmGetExtStorageDir = cm_get_static_jmethod(jcEnvironment, "getExternalStorageDirectory", "()"FILE_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jmGetAbsolutePath = cm_get_jmethod(jcFile, "getAbsolutePath", "()"STRING_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jfBoundApplication = cm_get_jfield(jcActivityThread, "mBoundApplication", APPBINDDATA_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jfAppInfo = cm_get_jfield(jcAppBindData, "appInfo", APPLICATIONINFO_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jfPackageName = cm_get_jfield(jcApplicationInfo, "packageName", STRING_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jfSourceDir = cm_get_jfield(jcApplicationInfo, "sourceDir", STRING_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(jfDataDir = cm_get_jfield(jcApplicationInfo, "dataDir", STRING_CLASS_SIGNATURE, env)))
- goto cm_initialize_error;
- if (!(joActivityThread = (*env)->CallStaticObjectMethod(env, jcActivityThread, jmCurrentActivityThread)))
- goto cm_initialize_error;
- if (!(joAppBindData = (*env)->GetObjectField(env, joActivityThread, jfBoundApplication)))
- goto cm_initialize_error;
- if (!(joAppInfo = (*env)->GetObjectField(env, joAppBindData, jfAppInfo)))
- goto cm_initialize_error;
- if (!(joFile = (*env)->CallStaticObjectMethod(env, jcEnvironment, jmGetExtStorageDir)))
- goto cm_initialize_error;
- // get packagename
- if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfPackageName)))
- goto cm_initialize_error;
- if (!(package_name = (*env)->GetStringUTFChars(env, jsString, 0)))
- goto cm_initialize_error;
- snprintf(PackageName, STRING_BUFFERSIZE, "%s", package_name);
- (*env)->ReleaseStringUTFChars(env, jsString, package_name);
- (*env)->DeleteLocalRef(env, jsString);
- // get sourceDir
- if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfSourceDir)))
- goto cm_initialize_error;
- if (!(source_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
- goto cm_initialize_error;
- snprintf(SourceDir, STRING_BUFFERSIZE, "%s", source_dir);
- (*env)->ReleaseStringUTFChars(env, jsString, source_dir);
- (*env)->DeleteLocalRef(env, jsString);
- // get dataDir
- if (!(jsString = (*env)->GetObjectField(env, joAppInfo, jfDataDir)))
- goto cm_initialize_error;
- if (!(data_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
- goto cm_initialize_error;
- snprintf(DataDir, STRING_BUFFERSIZE, "%s", data_dir);
- (*env)->ReleaseStringUTFChars(env, jsString, data_dir);
- (*env)->DeleteLocalRef(env, jsString);
- // get external storage directory
- if (!(jsString = (*env)->CallObjectMethod(env, joFile, jmGetAbsolutePath)))
- goto cm_initialize_error;
- if (!(ext_storage_dir = (*env)->GetStringUTFChars(env, jsString, 0)))
- goto cm_initialize_error;
- snprintf(ExternalDirectory, STRING_BUFFERSIZE, "%s", ext_storage_dir);
- (*env)->ReleaseStringUTFChars(env, jsString, ext_storage_dir);
- // delete local ref in cm_initialize_error
- snprintf(ExternalDataDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, DATA_DIRECTORY);
- snprintf(ExternalMediaDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, MEDIA_DIRECTORY);
- snprintf(ExternalOBBDirectory, STRING_BUFFERSIZE, "%s%s", ExternalDirectory, OBB_DIRECTORY);
- LOGD("package = %s", PackageName);
- LOGD("source dir = %s", SourceDir);
- LOGD("data dir = %s", DataDir);
- LOGD("ext dir = %s", ExternalDirectory);
- LOGD("ext data = %s", ExternalDataDirectory);
- LOGD("ext media = %s", ExternalMediaDirectory);
- LOGD("ext obb = %s", ExternalOBBDirectory);
- if (!(APKFile = unzOpen(SourceDir)))
- goto cm_initialize_error;
- char file_name[STRING_BUFFERSIZE];
- unz_file_info64 file_info;
- unz64_file_pos file_pos;
- unz_global_info64 global_info;
- ZPOS64_T start_pos;
- uLong handle;
- if (unzGetGlobalInfo64(APKFile, &global_info) == UNZ_OK)
- {
- LOGD("entry: %llu", global_info.number_entry);
- do
- {
- if (unzGetCurrentFileInfo64(APKFile, &file_info, file_name, STRING_BUFFERSIZE - 1, 0, 0, 0, 0) == UNZ_OK)
- {
- if (unzGetFilePos64(APKFile, &file_pos) == UNZ_OK)
- {
- if (unzOpenCurrentFile(APKFile) == UNZ_OK)
- {
- start_pos = unzGetCurrentFileZStreamPos64(APKFile);
- handle = crc32(0, file_name, file_info.size_filename);
- // MurmurHash3_x86_32(file_name, file_info.size_filename, 0, &handle);
- LOGD("%s : start 0x%08llx length 0x%08llx 0x%08lx handle = %lu", file_name,
- start_pos,
- file_info.compressed_size,
- handle,
- (handle % 32));
- }
- }
- }
- } while (unzGoToNextFile(APKFile) == UNZ_OK);
- }
- LOGD("end of list file");
- unzGoToFirstFile(APKFile);
- ret = 1;
- cm_initialize_error:
- (*env)->DeleteLocalRef(env, jcActivityThread);
- (*env)->DeleteLocalRef(env, jcAppBindData);
- (*env)->DeleteLocalRef(env, jcApplicationInfo);
- (*env)->DeleteLocalRef(env, jcEnvironment);
- (*env)->DeleteLocalRef(env, jcFile);
- (*env)->DeleteLocalRef(env, joActivityThread);
- (*env)->DeleteLocalRef(env, joAppBindData);
- (*env)->DeleteLocalRef(env, joAppInfo);
- (*env)->DeleteLocalRef(env, joFile);
- (*env)->DeleteLocalRef(env, jsString);
- (*env)->PopLocalFrame(env, 0);
- cm_initialize_error_:
- return ret;
- }
- int cm_deinitialize(void)
- {
- unzClose(APKFile);
- }
- // for test
- #include <pthread.h>
- #define USE_JNI_VERSION JNI_VERSION_1_4
- static JavaVM *jvm = 0;
- static void jvm_detach_thread(void *arg)
- {
- pthread_key_t *jvm_detach_key = (pthread_key_t *)arg;
- if (jvm)
- (*jvm)->DetachCurrentThread(jvm);
- pthread_setspecific(*jvm_detach_key, 0);
- free(jvm_detach_key);
- }
- int getEnv(JNIEnv **env)
- {
- switch ((*jvm)->GetEnv(jvm, (void **)env, USE_JNI_VERSION))
- {
- default:
- {
- return 0;
- }
- case JNI_EDETACHED:
- {
- if ((*jvm)->AttachCurrentThread(jvm, env, 0))
- {
- return 0;
- }
- pthread_key_t *jvm_detach_key = (pthread_key_t *)calloc(1, sizeof(pthread_key_t));
- // attach successfully
- pthread_key_create(jvm_detach_key, jvm_detach_thread);
- pthread_setspecific(*jvm_detach_key, jvm_detach_key);
- }
- case JNI_OK:
- {
- break;
- }
- }
- return 1;
- }
- jint JNI_OnLoad(JavaVM *vm, void *reserved)
- {
- JNIEnv *env;
- jvm = vm;
- if (getEnv(&env) && cm_initialize(env))
- return USE_JNI_VERSION;
- return -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement