コード例 #1
0
/**
 * Writes the settings of a MIDlet suite to persistent storage.
 * <pre>
 * The format of the properties file will be:
 *
 *   push interrupt setting as an jbyte
 *   length of a permissions as an int
 *   array of permissions jbytes
 *   push options as jint
 * </pre>
 *
 * @param ppszError pointer to character string pointer to accept an error
 * @param suiteId  ID of the suite
 * @param enabled enabled setting
 * @param pushInterrupt pointer to a push interruptSetting
 * @param pushOptions user options for push interrupts
 * @param pPermissions pointer a pointer to accept a permissions array
 * @param numberOfPermissions length of pPermissions
 *
 * @return error code (ALL_OK if successful)
 */
MIDPError
write_settings(char** ppszError, SuiteIdType suiteId, jboolean enabled,
               jbyte pushInterrupt, jint pushOptions,
               jbyte* pPermissions, int numberOfPermissions) {
    pcsl_string filename;
    int handle;
    char* pszTemp;
    MIDPError status;

    *ppszError = NULL;

    status = build_suite_filename(suiteId, &SETTINGS_FILENAME, &filename);
    if (status != ALL_OK) {
        return status;
    }

    handle = storage_open(ppszError, &filename, OPEN_READ_WRITE_TRUNCATE);
    pcsl_string_free(&filename);
    if (*ppszError != NULL) {
        return IO_ERROR;
    }

    storageWrite(ppszError, handle, (char*)&enabled, sizeof (jboolean));
    do {
        if (*ppszError != NULL) {
            break;
        }

        storageWrite(ppszError, handle, (char*)&pushInterrupt, sizeof (jbyte));
        if (*ppszError != NULL) {
            break;
        }

        storageWrite(ppszError, handle, (char*)&numberOfPermissions,
                                sizeof (int));
        if (*ppszError != NULL) {
            break;
        }

        storageWrite(ppszError, handle, (char*)pPermissions,
                                numberOfPermissions * sizeof (jbyte));

        storageWrite(ppszError, handle, (char*)&pushOptions, sizeof (jint));
        if (*ppszError != NULL) {
            break;
        }
    } while (0);

    if (*ppszError != NULL) {
        status = IO_ERROR;
    }

    storageClose(&pszTemp, handle);
    storageFreeError(pszTemp);

    return ALL_OK;
}
コード例 #2
0
/**
 * Gets location of the file associated with the named resource
 * of the suite with the specified suiteId.
 *
 * Note that in/out parameter filename MUST be allocated by callee with
 * pcsl_mem_malloc(), the caller is responsible for freeing it.
 *
 * @param suiteId The application suite ID
 * @param resourceName The name of suite resource whose location is requested
 * @param checkSuiteExists true if suite should be checked for existence or not
 * @param filename The in/out parameter that contains returned filename
 * @return error code that should be one of the following:
 * <pre>
 *     ALL_OK, OUT_OF_MEMORY, NOT_FOUND,
 *     SUITE_CORRUPTED_ERROR, BAD_PARAMS
 * </pre>
 */
static MIDPError
get_suite_resource_file(SuiteIdType suiteId,
                        const pcsl_string* resourceName,
                        jboolean checkSuiteExists,
                        pcsl_string *filename) {
  pcsl_string returnFileName = PCSL_STRING_NULL;
  int rc;
  *filename = PCSL_STRING_NULL;

  if (checkSuiteExists) {
      rc = build_suite_filename(suiteId, resourceName, &returnFileName);
  } else {
      rc = get_suite_filename(suiteId, resourceName, &returnFileName);
  }

  if (rc == ALL_OK) {
      *filename = returnFileName;
  }

  return ALL_OK;
}
コード例 #3
0
/**
 * 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;
}
コード例 #4
0
/**
 * Gets the settings of a MIDlet suite from persistent storage.
 * <pre>
 * The format of the properties file will be:
 *
 *   push interrupt setting as an jbyte
 *   length of a permissions as an int
 *   array of permissions jbytes
 *   push options as jint
 * </pre>
 *
 * @param ppszError pointer to character string pointer to accept an error
 * @param suiteId  ID of the suite
 * @param pEnabled pointer to an enabled setting
 * @param pPushInterrupt pointer to a push interruptSetting
 * @param pPushOptions user options for push interrupts
 * @param ppPermissions pointer a pointer to accept a permissions array
 * @param pNumberOfPermissions pointer to an int
 *
 * @return error code (ALL_OK if successful)
 */
MIDPError
read_settings(char** ppszError, SuiteIdType suiteId, jboolean* pEnabled,
             jbyte* pPushInterrupt, jint* pPushOptions,
             jbyte** ppPermissions, int* pNumberOfPermissions) {
    pcsl_string filename;
    int handle;
    int bytesRead;
    char* pszTemp;
    MIDPError status;

    *ppszError = NULL;
    *ppPermissions = NULL;
    *pNumberOfPermissions = 0;

    status = build_suite_filename(suiteId, &SETTINGS_FILENAME, &filename);
    if (status != ALL_OK) {
        return status;
    }

    handle = storage_open(ppszError, &filename, OPEN_READ);
    pcsl_string_free(&filename);
    if (*ppszError != NULL) {
        return IO_ERROR;
    }

    bytesRead = storageRead(ppszError, handle, (char*)pEnabled,
        sizeof (jboolean));
    do {
        if (*ppszError != NULL) {
            status = IO_ERROR;
            break;
        }

        bytesRead = storageRead(ppszError, handle, (char*)pPushInterrupt,
                                sizeof (jbyte));
        if (*ppszError != NULL) {
            status = IO_ERROR;
            break;
        }

        bytesRead = storageRead(ppszError, handle, (char*)pNumberOfPermissions,
                                sizeof (int));

        if (bytesRead != sizeof (int) || *pNumberOfPermissions == 0) {
            status = IO_ERROR;
            break;
        }

        *ppPermissions = (jbyte*)pcsl_mem_malloc(
                *pNumberOfPermissions * sizeof (jbyte));
        if (*ppPermissions == NULL) {
            status = OUT_OF_MEMORY;
            break;
        }

        bytesRead = storageRead(ppszError, handle, (char*)(*ppPermissions),
                                *pNumberOfPermissions * sizeof (jbyte));

        if (bytesRead != *pNumberOfPermissions) {
            *pNumberOfPermissions = 0;
            pcsl_mem_free(*ppPermissions);
            status = SUITE_CORRUPTED_ERROR;
            break;
        }

        /* Old versions of the file may not have options. */
        status = ALL_OK;
        *pPushOptions = 0;
        bytesRead = storageRead(ppszError, handle, (char*)pPushOptions,
                                sizeof (jint));
        if (*ppszError != NULL) {
            storageFreeError(*ppszError);
            *ppszError = NULL;
            break;
        }
    } while (0);

    storageClose(&pszTemp, handle);
    storageFreeError(pszTemp);

    return status;
}
コード例 #5
0
/**
 * Removes a software package given its suite ID
 * <p>
 * If the component is in use it must continue to be available
 * to the other components that are using it.  The resources it
 * consumes must not be released until it is not in use.
 *
 * @param suiteId ID of the suite
 *
 * @return ALL_OK if no errors,
 *         NOT_FOUND if the suite does not exist,
 *         SUITE_LOCKED if the suite is locked,
 *         BAD_PARAMS this suite cannot be removed
 */
MIDPError
midp_remove_suite(SuiteIdType suiteId) {
    pcsl_string filename;
    char* pszError;
    pcsl_string suiteRoot;
    MIDPError status;
    int operationStarted = 0;
    void* fileIteratorHandle = NULL;
    MidpProperties properties;
    pcsl_string* pproperty;
    MidletSuiteData* pData = NULL;
    pcsl_string filenameBase;

    lockStorageList *node = NULL;

    /* get the filename base from the suite id */
    status = build_suite_filename(suiteId, &PCSL_STRING_EMPTY, 
                                          &filenameBase);
    if (status != ALL_OK) {
        return status;
    }
    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) {
        return OUT_OF_MEMORY;
    }

    do {
        int rc; /* return code for rmsdb_... and storage_... */

        /* load _suites.dat */
        status = read_suites_data(&pszError);
        storageFreeError(pszError);
        if (status != ALL_OK) {
            break;
        }

        /* check that the suite exists and it is not a preloaded one */
        pData = get_suite_data(suiteId);

        if (pData == NULL) {
            status = NOT_FOUND;
            break;
        }

        /* notify the listeners that we starting to remove the suite */
        operationStarted = 1;
        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,
            SUITESTORE_OPERATION_START, ALL_OK, pData);

        if (pData->type == COMPONENT_PREINSTALLED_SUITE) {
            status = BAD_PARAMS;
            break;
        }

        status = begin_transaction(TRANSACTION_REMOVE_SUITE, suiteId, NULL);
        if (status != ALL_OK) {
            return status;
        }

        /*
         * Remove the files
         * Call the native RMS method to remove the RMS data.
         * This function call is needed for portability
         */
        rc = rmsdb_remove_record_stores_for_suite(&filenameBase, suiteId);
        if (rc == KNI_FALSE) {
            status = SUITE_LOCKED;
            break;
        }

        pushdeletesuite(suiteId);

        /*
         * If there is a delete notify property, add the value to the delete
         * notify URL list.
         */
        properties = midp_get_suite_properties(suiteId);
        if (properties.numberOfProperties > 0) {
            pproperty = midp_find_property(&properties, &DELETE_NOTIFY_PROP);
            if (pcsl_string_length(pproperty) > 0) {
                midpAddDeleteNotification(suiteId, pproperty);
            }

            pproperty = midp_find_property(&properties, &INSTALL_NOTIFY_PROP);
            if (pcsl_string_length(pproperty) > 0) {
                /*
                 * Remove any pending install notifications since they are only
                 * retried when the suite is run.
                 */
                midpRemoveInstallNotification(suiteId);
            }

            midp_free_properties(&properties);
        }

        if ((status = get_suite_storage_root(suiteId, &suiteRoot)) != ALL_OK) {
            break;
        }

        fileIteratorHandle = storage_open_file_iterator(&suiteRoot);
        if (!fileIteratorHandle) {
            status = IO_ERROR;
            break;
        }

#if ENABLE_ICON_CACHE
        midp_remove_suite_icons(suiteId);
#endif        

        for (;;) {
            rc = storage_get_next_file_in_iterator(&suiteRoot,
                fileIteratorHandle, &filename);
            if (0 != rc) {
                break;
            }
            storage_delete_file(&pszError, &filename);
            pcsl_string_free(&filename);
            if (pszError != NULL) {
                storageFreeError(pszError);
                break;
            }
        }

    } while (0);

    pcsl_string_free(&suiteRoot);
    storageCloseFileIterator(fileIteratorHandle);

    (void)finish_transaction();

    /*
     * Notify the listeners the we've finished removing the suite.
     * It should be done before remove_from_suite_list_and_save()
     * call because it frees pData structure.
     */
    if (operationStarted) {
        suite_listeners_notify(SUITESTORE_LISTENER_TYPE_REMOVE,
            SUITESTORE_OPERATION_END, status, pData);
    }

    if (status == ALL_OK) {
        (void)remove_from_suite_list_and_save(suiteId);
    }

    remove_storage_lock(suiteId);

    return status;
}