/** * Gets the properties of a MIDlet suite to persistent storage. * <pre> * The format of the properties file will be: * <number of strings as int (2 strings per property)> * {repeated for each property} * <length of a property key as int> * <property key as jchars> * <length of property value as int> * <property value as jchars> * </pre> * * * Note that memory for the strings inside the returned MidpProperties * structure is allocated by the callee, and the caller is * responsible for freeing it using midp_free_properties(). * * @param suiteId ID of the suite * * @return properties in a pair pattern of key and value, * use the status macros to check the result. A SUITE_CORRUPTED_ERROR * is returned as a status of MidpProperties when suite is corrupted */ MidpProperties midp_get_suite_properties(SuiteIdType suiteId) { pcsl_string filename; MidpProperties result = { 0, ALL_OK, NULL }; int len; char* pszError; MIDPError status; /* * This is a public API which can be called without the VM running * so we need automatically init anything needed, to make the * caller's code less complex. * * Initialization is performed in steps so that we do use any * extra resources such as the VM for the operation being performed. */ if (midpInit(LIST_LEVEL) != 0) { result.numberOfProperties = 0; result.status = OUT_OF_MEMORY; return result; } /* if (check_for_corrupted_suite(suiteId) == SUITE_CORRUPTED_ERROR) { result.numberOfProperties = 0; result.status = SUITE_CORRUPTED_ERROR; return result; } */ if (get_property_file(suiteId, KNI_TRUE, &filename) != ALL_OK) { result.numberOfProperties = 0; result.status = NOT_FOUND; return result; } status = get_string_list(&pszError, &filename, &result.pStringArr, &len); pcsl_string_free(&filename); if (status != ALL_OK) { result.numberOfProperties = 0; result.status = status; storageFreeError(pszError); return result; } if (len < 0) { /* error */ result.numberOfProperties = 0; result.status = GENERAL_ERROR; } else { /* each property is 2 strings (key and value) */ result.numberOfProperties = len / 2; } return result; }
/** * Check if the suite is corrupted * @param suiteId ID of a suite * * @return ALL_OK if the suite is not corrupted, * SUITE_CORRUPTED_ERROR is suite is corrupted, * OUT_OF_MEMORY if out of memory, * IO_ERROR if I/O error */ MIDPError check_for_corrupted_suite(SuiteIdType suiteId) { pcsl_string filename[NUM_SUITE_FILES]; int arc[NUM_SUITE_FILES]; int i; StorageIdType storageId; MIDPError status = ALL_OK; /* Default to no error */ MidletSuiteData *pData = get_suite_data(suiteId); if (!pData) { return SUITE_CORRUPTED_ERROR; } /* if this suite was already checked, just return "OK" status */ if (pData->isChecked) { return status; } /* get an id of the storage where the suite is located */ status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return status; } arc[0] = get_suite_filename(suiteId, &INSTALL_INFO_FILENAME, &filename[0]); arc[1] = get_suite_filename(suiteId, &SETTINGS_FILENAME, &filename[1]); arc[2] = midp_suite_get_class_path(suiteId, storageId, KNI_FALSE, &filename[2]); arc[3] = get_property_file(suiteId, KNI_FALSE, &filename[3]); for (i = 0; i < NUM_SUITE_FILES; i++) { if (arc[i] != ALL_OK) { status = (MIDPError)arc[i]; break; } if (!storage_file_exists(&filename[i])) { /* File does not exist; suite must be corrupted */ status = SUITE_CORRUPTED_ERROR; break; } } if (status == ALL_OK) { /* if the suite is not currupted, mark it as "checked" */ pData->isChecked = 1; } pcsl_string_free(&filename[0]); pcsl_string_free(&filename[1]); pcsl_string_free(&filename[2]); pcsl_string_free(&filename[3]); return status; }
/** * Loads the properties of a MIDlet suite from persistent storage. * * @param suiteId ID of the suite * @param pJadProps [out] pointer to a structure containing an array of strings, * in a pair pattern of key and value; NULL may be passed if it is not required * to read JAD properties * @param pJarProps [out] pointer to a structure containing an array of strings, * in a pair pattern of key and value; NULL may be passed if it is not required * to read JAR properties * * @return error code (ALL_OK for success) */ MIDPError load_install_properties(SuiteIdType suiteId, MidpProperties* pJadProps, MidpProperties* pJarProps) { pcsl_string filename; char* pszError = NULL; int handle, i, n; int numberOfProps; MIDPError status; status = get_property_file(suiteId, KNI_TRUE, &filename); if (status != ALL_OK) { return status; } handle = storage_open(&pszError, &filename, OPEN_READ); pcsl_string_free(&filename); if (pszError != NULL) { storageFreeError(pszError); return IO_ERROR; } status = ALL_OK; /* Read JAD, then JAR properties. */ for (n = 0; n < 2; n++) { MidpProperties *pProps = n ? pJarProps : pJadProps; if (!pProps) { continue; } storageRead(&pszError, handle, (char*)&numberOfProps, sizeof (numberOfProps)); if (pszError != NULL) { break; } pProps->pStringArr = alloc_pcsl_string_list(numberOfProps << 1); for (i = 0; i < numberOfProps << 1; i++) { storage_read_utf16_string(&pszError, handle, &pProps->pStringArr[i]); if (pszError != NULL) { break; } } if (pszError != NULL) { break; } pProps->numberOfProperties = numberOfProps; } if (pszError != NULL) { status = IO_ERROR; storageFreeError(pszError); } storageClose(&pszError, handle); storageFreeError(pszError); if (status != ALL_OK) { if (pJadProps) { free_pcsl_string_list(pJadProps->pStringArr, pJadProps->numberOfProperties << 1); } if (pJarProps) { free_pcsl_string_list(pJarProps->pStringArr, pJarProps->numberOfProperties << 1); } } return status; }
/** * Gets the amount of storage on the device that this suite is using. * This includes the JAD, JAR, management data, and RMS. * * @param suiteId ID of the suite * * @return number of bytes of storage the suite is using or less than * OUT_OF_MEM_LEN if out of memory */ long midp_get_suite_storage_size(SuiteIdType suiteId) { long used = 0; long rms = 0; pcsl_string filename[NUM_SUITE_FILES]; int i; char* pszError; StorageIdType storageId; MIDPError status; MidletSuiteData* pData; pcsl_string filenameBase; // get the filename base from the suite id status = build_suite_filename(suiteId, &PCSL_STRING_EMPTY, &filenameBase); if (status != ALL_OK) { return status; } pData = get_suite_data(suiteId); if (pData) { used = (jint)pData->suiteSize; } if (used <= 0) { /* Suite size is not cached (should not happen!), calculate it. */ for (i = 0; i < NUM_SUITE_FILES; i++) { filename[i] = PCSL_STRING_NULL; } /* * This is a public API which can be called without the VM running * so we need automatically init anything needed, to make the * caller's code less complex. * * Initialization is performed in steps so that we do use any * extra resources such as the VM for the operation being performed. */ if (midpInit(LIST_LEVEL) != 0) { return OUT_OF_MEM_LEN; } status = midp_suite_get_suite_storage(suiteId, &storageId); if (status != ALL_OK) { return OUT_OF_MEM_LEN; } status = build_suite_filename(suiteId, &INSTALL_INFO_FILENAME, &filename[0]); if (status != ALL_OK) { return status; } status = build_suite_filename(suiteId, &SETTINGS_FILENAME, &filename[1]); if (status != ALL_OK) { return status; } midp_suite_get_class_path(suiteId, storageId, KNI_TRUE, &filename[2]); get_property_file(suiteId, KNI_TRUE, &filename[3]); for (i = 0; i < NUM_SUITE_FILES; i++) { long tmp; if (pcsl_string_is_null(&filename[i])) { continue; } tmp = storage_size_of_file_by_name(&pszError, &filename[i]); pcsl_string_free(&filename[i]); if (pszError != NULL) { storageFreeError(pszError); continue; } used += tmp; } if (pData) { /* cache the calculated size */ pData->suiteSize = (jint)used; status = write_suites_data(&pszError); if (status != ALL_OK) { storageFreeError(pszError); return OUT_OF_MEM_LEN; } } } rms = rmsdb_get_rms_storage_size(&filenameBase, suiteId); if (rms == OUT_OF_MEM_LEN) { return OUT_OF_MEM_LEN; } return used + rms; }