/** * Native method boolean removeFromSuiteList(String) for class * com.sun.midp.midletsuite.MIDletSuiteStorage. * <p> * Removes the suite from the list of installed suites. * <p> * Used from suitestore_midletsuitestorage_kni.c so is non-static. * * @param suiteId ID of a suite * * @return 1 if the suite was in the list, 0 if not * -1 if out of memory */ int remove_from_suite_list_and_save(SuiteIdType suiteId) { int existed = 0; MidletSuiteData *pData, *pPrevData = NULL; if (suiteId == UNUSED_SUITE_ID || suiteId == INTERNAL_SUITE_ID) { return 0; /* suite was not in the list */ } /* * This function is called from midp_remove_suite(), * so read_suites_data() was already called. */ pData = g_pSuitesData; /* try to find a suite */ while (pData != NULL) { if (pData->suiteId == suiteId) { int status; char* pszError; /* remove the entry we have found from the list */ if (pPrevData) { /* this entry is not the first */ pPrevData->nextEntry = pData->nextEntry; } else { /* handle the first entry */ g_pSuitesData = pData->nextEntry; } /* free the memory allocated for the entry */ free_suite_data_entry(pData); /* decrease the number of the installed suites */ g_numberOfSuites--; /* save the modified list into _suites.dat */ status = write_suites_data(&pszError); existed = (status == ALL_OK) ? 1 : -1; storageFreeError(pszError); break; } pPrevData = pData; pData = pData->nextEntry; } /* Reset the static variable for MVM-safety */ g_lastSuiteExistsID = UNUSED_SUITE_ID; return existed; }
/** * Change the enabled state of a suite. * * @param suiteId ID of the suite * @param enabled true if the suite is be enabled * * @return an error code (ALL_OK if no errors) */ static MIDPError change_enabled_state(SuiteIdType suiteId, jboolean enabled) { char* pszError; MIDPError status; jbyte* pPermissions; int numberOfPermissions; jbyte pushInterrupt; jint pushOptions; jboolean temp; lockStorageList* node; MidletSuiteData* pData; /* * 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_MEMORY; } status = midp_suite_exists(suiteId); if ((status != ALL_OK) && (status != SUITE_CORRUPTED_ERROR)) { return status; } node = find_storage_lock(suiteId); if (node != NULL) { if (node->update == KNI_TRUE) { /* Suite is being updated currently. */ return SUITE_LOCKED; } } status = read_settings(&pszError, suiteId, &temp, &pushInterrupt, &pushOptions, &pPermissions, &numberOfPermissions); if (status != ALL_OK) { storageFreeError(pszError); return status; } status = begin_transaction(TRANSACTION_ENABLE_SUITE, suiteId, NULL); if (status != ALL_OK) { return status; } status = write_settings(&pszError, suiteId, enabled, pushInterrupt, pushOptions, pPermissions, numberOfPermissions, NULL); pcsl_mem_free(pPermissions); if (status != ALL_OK) { storageFreeError(pszError); /* nothing was written, so nothing to rollback, just finish */ (void)finish_transaction(); return status; } /* synchronize the settings in the list of MidletSuiteData structures */ pData = get_suite_data(suiteId); /* * We can assert that pData is not NULL because midp_suite_exists() * was called above to ensure that the suite with the given ID exists. */ if (pData != NULL) { int status; char* pszError; pData->isEnabled = enabled; /* IMPL_NOTE: these settings must be cached and saved on AMS exit. */ status = write_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { (void)rollback_transaction(); return IO_ERROR; } } (void)finish_transaction(); return ALL_OK; }
/** * Moves the given midlet suite to another folder. * * @param suiteId ID of the suite * @param newFolderId ID of the folder where the suite must be moved * * @return ALL_OK if no errors or an error code */ MIDPError midp_move_suite_to_folder(SuiteIdType suiteId, FolderIdType newFolderId) { MIDPError status = ALL_OK; char* pszError = NULL; lockStorageList *node = NULL; MidletSuiteData* pSuiteData; FolderIdType oldFolderId; /* * 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(REMOVE_LEVEL) != 0) { return OUT_OF_MEMORY; } /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } node = find_storage_lock(suiteId); if (node != NULL) { if (node->update != KNI_TRUE) { return SUITE_LOCKED; } } pSuiteData = get_suite_data(suiteId); if (pSuiteData == NULL) { remove_storage_lock(suiteId); return NOT_FOUND; } status = begin_transaction(TRANSACTION_MOVE_TO_FOLDER, suiteId, NULL); if (status != ALL_OK) { remove_storage_lock(suiteId); return status; } oldFolderId = pSuiteData->folderId; pSuiteData->folderId = newFolderId; status = write_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { pSuiteData->folderId = oldFolderId; (void)rollback_transaction(); } else { (void)finish_transaction(); } remove_storage_lock(suiteId); 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; }
/** * Moves a software package with given suite ID to the specified storage. * * @param suiteId suite ID for the installed package * @param storageId new storage ID * * @return SUITE_LOCKED if the * suite is locked, NOT_FOUND if the suite cannot be found or * invalid storage ID specified, BAD_PARAMS if attempt is made * to move suite to the external storage, GENERAL_ERROR if * VERIFY_ONCE is not enabled and if MONET is enabled */ MIDPError midp_change_suite_storage(SuiteIdType suiteId, StorageIdType newStorageId) { #ifndef VERIFY_ONCE (void)suiteId; (void)newStorageId; return GENERAL_ERROR; #else /* * if VERIFY_ONCE is enabled then MONET is disabled * so we don't have to check ENABLE_MONET. */ { pcsl_string suiteRoot; MidletSuiteData* pData = NULL; int status; void* fileIteratorHandle = NULL; lockStorageList *node = NULL; if ((UNUSED_STORAGE_ID == newStorageId) || (newStorageId >= MAX_STORAGE_NUM)) { return BAD_PARAMS; } /* * IMPL_NOTE: for security reasons we allow to move suite * only to the internal storage. */ if (newStorageId != INTERNAL_STORAGE_ID) { return BAD_PARAMS; } node = find_storage_lock(suiteId); if (node != NULL) { if (node->update != KNI_TRUE) { return SUITE_LOCKED; } } /* * 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(REMOVE_LEVEL) != 0) { remove_storage_lock(suiteId); return OUT_OF_MEMORY; } /* check that the suite exists and it is not a preloaded one */ pData = get_suite_data(suiteId); if (pData == NULL) { remove_storage_lock(suiteId); return NOT_FOUND; } if (pData->storageId == newStorageId) { remove_storage_lock(suiteId); return BAD_PARAMS; } if (pData->type == COMPONENT_PREINSTALLED_SUITE) { remove_storage_lock(suiteId); return BAD_PARAMS; } do { jsize oldRootLength; jsize newRootLength; const pcsl_string* newRoot; const pcsl_string* oldRoot; char* pszError = NULL; pcsl_string filePath; pcsl_string newFilePath; status = begin_transaction(TRANSACTION_CHANGE_STORAGE, suiteId, NULL); if (status != ALL_OK) { break; } if ((status = get_suite_storage_root(suiteId, &suiteRoot)) != ALL_OK) { break; } fileIteratorHandle = storage_open_file_iterator(&suiteRoot); if (!fileIteratorHandle) { status = IO_ERROR; break; } newRoot = storage_get_root(newStorageId); oldRoot = storage_get_root(pData->storageId); newRootLength = pcsl_string_length(newRoot); oldRootLength = pcsl_string_length(oldRoot); status = ALL_OK; if ((status = midp_suite_get_class_path(suiteId, pData->storageId, KNI_FALSE, &filePath)) != ALL_OK) { break; } if ((status = midp_suite_get_class_path(suiteId, newStorageId, KNI_FALSE, &newFilePath)) != ALL_OK) { break; } storage_rename_file(&pszError, &filePath, &newFilePath); if (pszError != NULL) { status = IO_ERROR; storageFreeError(pszError); pcsl_string_free(&filePath); pcsl_string_free(&newFilePath); break; } pcsl_string_free(&filePath); pcsl_string_free(&newFilePath); #if ENABLE_IMAGE_CACHE moveImageCache(suiteId, pData->storageId, newStorageId); #endif pData->storageId = newStorageId; status = write_suites_data(&pszError); storageFreeError(pszError); } while (0); pcsl_string_free(&suiteRoot); storageCloseFileIterator(fileIteratorHandle); if (status != ALL_OK) { (void)rollback_transaction(); } else { (void)finish_transaction(); } remove_storage_lock(suiteId); return status; } #endif /* VERIFY_ONCE */ }