suitestore_intern.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,943 行 · 第 1/4 页

C
1,943
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * * @ingroup AMS * * This is reference implementation of the internal MIDlet suite storage * functions. * <p> * <h3>Common String List Files</h3> * <p> * A suite has more state than what is in the JAD or JAR, to hold this state * there a multiple files that contain lists of string values, with a string * key. The format of the string list file is a common Unicode-string file * format, for any file that is a series of Unicode strings. The format of * the file is binary and is written without byte conversion. These decisions * save code. Byte conversion can be omitted because the file is never copied * between devices. * <p> * The structure of the file is one native integer (int) for the number of * strings, followed by the data. The data consists of, for each Unicode * string, a Java programming language int for the number characters, * followed by the Java programming language characters themselves. * <p> * <h3>Suite Storage Files</h3> * <p> * When a suite is stored the files or record in a file listed below are * created. * <p> * <table border=2> * <tr> *   <th>File Type</th> *   <th>Description</th> * </tr> * <tr> *   <td>JAR</td> *   <td>The JAR file downloaded for the suite. This file is created by the *       installer and renamed when it is stored.</td> * </tr> * <tr> *   <td>Application Properties</td> *   <td>JAD properties file followed by the manifest properties of the MIDlet *       suite. The file is a Unicode string file, with each property written *       as two strings: the property key followed by the property value.</td> * </tr> * <tr> *   <td>Suite Settings</td> *   <td>API permissions and push interrupt setting of the MIDlet suite, *       written as an array of bytes</td> * </tr> * <tr> *   <td>Install Information</td> *   <td>The JAD file URL, JAR file URL, Software Certificate Authority (CA), *       Content Provider, Permission Domain, and a trusted boolean</td> * </tr> * <tr> *   <td>Suite ID</td> *   <td>List of MIDlet-suite identifiers. There is only one copy of this *       file, which is shared by all MIDlet suites. It is a common Unicode *       string file.</td> * </tr> * <tr> *   <td>Install Notification URLs</td> *   <td>One record is added to a list of URLs to which to post install *       notifications when the next OTA installation is performed or a MIDlet *       suite is run. There is only one copy of this file, which is shared by *       all MIDlet suites. It is a common Unicode string file.</td> * </tr> *   <td>Delete Notification URLs</td> *   <td>One record is added to a list of URLs to which to post delete *       notifications when the next OTA installation is performed. There is *       only one copy of this file, which is shared by all MIDlet suites. It *       is a common Unicode string file.</td> * </tr> * <tr> *   <td>Verification Hash<td> *   <td>If the preverification option is built, a file with the hash of *       the JAR is written to its own file.</td> * </tr> * <tr> *   <td>Cached Images<td> *   <td>If the image cache option is is built, each image in the JAR, will *       be extracted, decode into a platform binary image, and stored in the *       image cache. See imageCache.h.</td> * </tr> * </table> */#include <kni.h>#include <string.h> /* for NULL */#include <midpInit.h>#include <midpStorage.h>#include <pcsl_memory.h>#include <midp_logging.h>#include <suitestore_intern.h>#include <suitestore_listeners.h>/* * This header is required for midp_suite_exists() which is used * from build_suite_filename(). This introduces a cyclic dependency * between suitestore_intern and suitestore_query libraries. * It can be easily eliminated by introducing suite_exists_impl() * in this (suitestore_intern) library, but it seems to be unnecessary * because suitestore_intern contains only internal functions and * is not intended to be ported. */#include <suitestore_task_manager.h>/** Cache of the last suite the exists function found. */SuiteIdType g_lastSuiteExistsID = UNUSED_SUITE_ID;#if ENABLE_DYNAMIC_COMPONENTS/** Cache of the last component that midp_component_exists() function found. */ComponentIdType g_lastComponentExistsID = UNUSED_COMPONENT_ID;#endif/** A flag indicating that the _suites.dat was already loaded. */int g_isSuitesDataLoaded = 0;/** Number of the installed midlet suites. */int g_numberOfSuites = 0;/** List of structures with the information about the installed suites. */MidletSuiteData* g_pSuitesData = NULL;/** Indicates if the suite storage is already initialized. */static int g_suiteStorageInitDone = 0;/** Indicates if a transaction was started. */static int g_transactionStarted = 0;/** * A string that will be added to a file name to * make the name of the temporary file. */PCSL_DEFINE_ASCII_STRING_LITERAL_START(TMP_FILE_EXTENSION)    {'.', 't', 'm', 'p', '\0'}PCSL_DEFINE_ASCII_STRING_LITERAL_END(TMP_FILE_EXTENSION);/* forward declaration */static intremove_from_list_and_save_impl(SuiteIdType suiteId, ComponentIdType componentId,                               int removeSuiteAndComponents);/** * Initializes the subsystem. This wrapper is used to hide * global variables from the suitestore_common library. * * @return status code (ALL_OK if successful) */MIDPErrorsuite_storage_init_impl() {    if (g_suiteStorageInitDone) {        /* Already initialized */        return ALL_OK;    }    g_suiteStorageInitDone = 1;    g_pSuitesData        = NULL;    g_numberOfSuites     = 0;    g_isSuitesDataLoaded = 0;    g_lastSuiteExistsID  = UNUSED_SUITE_ID;#if ENABLE_DYNAMIC_COMPONENTS    g_lastComponentExistsID = UNUSED_COMPONENT_ID;#endif        return init_listeners_impl();}/** * Frees the memory occupied by the given MidletSuiteData structure. * * @param pData MidletSuiteData entry to be freed */voidfree_suite_data_entry(MidletSuiteData* pData) {    if (pData != NULL) {        if ((pData->jarHashLen > 0) && pData->varSuiteData.pJarHash) {            pcsl_mem_free(pData->varSuiteData.pJarHash);        }        pcsl_string_free(&pData->varSuiteData.midletClassName);        pcsl_string_free(&pData->varSuiteData.displayName);        pcsl_string_free(&pData->varSuiteData.iconName);        pcsl_string_free(&pData->varSuiteData.suiteVendor);        pcsl_string_free(&pData->varSuiteData.suiteName);        pcsl_string_free(&pData->varSuiteData.pathToJar);        pcsl_string_free(&pData->varSuiteData.pathToSettings);        pcsl_mem_free(pData);    }}/** * Resets any persistent resources allocated by MIDlet suite storage functions. * This wrapper is used to hide global variables from the suitestore_common * library. */voidsuite_storage_cleanup_impl() {    if (!g_suiteStorageInitDone) {        /* The subsystem was not initialized */        return;    }    remove_all_storage_lock();    suite_remove_all_listeners();        if (g_isSuitesDataLoaded) {        MidletSuiteData* pData = g_pSuitesData;        /* free each midlet suite entry */        while (pData != NULL) {            MidletSuiteData* pTmp = pData->nextEntry;            free_suite_data_entry(pData);            pData = pTmp;        }    }    g_pSuitesData        = NULL;    g_numberOfSuites     = 0;    g_isSuitesDataLoaded = 0;    g_lastSuiteExistsID  = UNUSED_SUITE_ID;#if ENABLE_DYNAMIC_COMPONENTS    g_lastComponentExistsID = UNUSED_COMPONENT_ID;#endif    g_suiteStorageInitDone = 0;}/** * Gets the storage root for a MIDlet suite by ID. * Free the data of the string returned with pcsl_string_free(). * * @param suiteId suite ID * @param sRoot receives storage root (gets set to NULL in the case of an error) * * @return status: ALL_OK if success, * OUT_OF_MEMORY if out-of-memory */MIDPErrorget_suite_storage_root(SuiteIdType suiteId, pcsl_string* sRoot) {    StorageIdType storageId;    const pcsl_string* root;    MIDPError status;    *sRoot = PCSL_STRING_EMPTY;    /* 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;    }    root = storage_get_root(storageId);    pcsl_string_predict_size(sRoot,        pcsl_string_length(root) + GET_SUITE_ID_LEN(suiteId));    if (PCSL_STRING_OK == pcsl_string_append(sRoot, root) &&            PCSL_STRING_OK == pcsl_string_append(sRoot,                midp_suiteid2pcsl_string(suiteId))) {        return ALL_OK;    }    pcsl_string_free(sRoot);    *sRoot = PCSL_STRING_NULL;    return OUT_OF_MEMORY;}/** * Free the buffers allocated for structures containing information * about the installed midlet suites. */static voidfree_suites_data() {    MidletSuiteData *pData = g_pSuitesData, *pNextData;    while (pData != NULL) {        pNextData = pData->nextEntry;        free_suite_data_entry(pData);        pData = pNextData;    }    g_pSuitesData        = NULL;    g_numberOfSuites     = 0;    g_isSuitesDataLoaded = 0;}/** * Search for a structure describing the suite by the suite's ID. * * @param suiteId unique ID of the midlet suite * * @return pointer to the MidletSuiteData structure containing * the suite's attributes or NULL if the suite was not found */MidletSuiteData*get_suite_data(SuiteIdType suiteId) {    MidletSuiteData* pData;    pData = g_pSuitesData;    /* walk through the linked list */    while (pData != NULL) {        if (pData->suiteId == suiteId#if ENABLE_DYNAMIC_COMPONENTS            && (pData->type == COMPONENT_REGULAR_SUITE ||                pData->type == COMPONENT_PREINSTALLED_SUITE)#endif         ) {            return pData;        }        pData = pData->nextEntry;    }    return NULL;}#if ENABLE_DYNAMIC_COMPONENTS/** * Search for a structure describing the component by the component's ID. * * @param componentId unique ID of the dynamic component * * @return pointer to the MidletSuiteData structure containing * the component's attributes or NULL if the component was not found */MidletSuiteData*get_component_data(ComponentIdType componentId) {    MidletSuiteData* pData;    pData = g_pSuitesData;    /* walk through the linked list */    while (pData != NULL) {        if (pData->type == COMPONENT_DYNAMIC &&                pData->componentId == componentId) {            return pData;        }        pData = pData->nextEntry;    }    return NULL;}#endif /* ENABLE_DYNAMIC_COMPONENTS *//** * Allocates a memory buffer enough to hold the whole file * and reads the given file into the buffer. * File contents is read as one piece. * * @param ppszError pointer to character string pointer to accept an error * @param pFileName file to read * @param outBuffer receives the address of a buffer where the file contents are stored, NULL on error * @param outBufferLen receives the length of outBuffer, 0 on error * * @return status code (ALL_OK if there was no errors) */MIDPErrorread_file(char** ppszError, const pcsl_string* pFileName,          char** outBuffer, long* outBufferLen) {    int handle, status = ALL_OK;    long fileSize, len;    char* pszTemp;    char* buffer = NULL;    *ppszError  = NULL;    *outBuffer  = NULL;    *outBufferLen = 0;    /* open the file */    handle = storage_open(ppszError, pFileName, OPEN_READ);    if (*ppszError != NULL) {        if (!storage_file_exists(pFileName)) {            return NOT_FOUND;        }        return IO_ERROR;    }    do {        /* get the size of file */        fileSize = storageSizeOf(ppszError, handle);        if (*ppszError != NULL) {            status = IO_ERROR;            break;        }        if (fileSize > 0) {            /* allocate a buffer to store the file contents */            buffer = (char*)pcsl_mem_malloc(fileSize);            if (buffer == NULL) {                status = OUT_OF_MEMORY;                break;            }            /* read the whole file */            len = storageRead(ppszError, handle, buffer, fileSize);            if (*ppszError != NULL || len != fileSize) {                pcsl_mem_free(buffer);                status = IO_ERROR;            }        }    } while (0);    /* close the file */    storageClose(&pszTemp, handle);    storageFreeError(pszTemp);    if (status == ALL_OK) {        *outBuffer    = buffer;        *outBufferLen = fileSize;    }    return status;}/** * Writes the contents of the given buffer into the given file. * * Note that if the length of the input buffer is zero or less, * the file will be truncated. * * @param ppszError pointer to character string pointer to accept an error * @param pFileName file to write * @param inBuffer buffer with data that will be stored * @param inBufferLen length of the inBuffer * * @return status code (ALL_OK if there was no errors) */MIDPErrorwrite_file(char** ppszError, const pcsl_string* pFileName,           char* inBuffer, long inBufferLen) {    int handle, status = ALL_OK;    char* pszTemp;    pcsl_string tmpFileName;    pcsl_string_status rc;    *ppszError = NULL;    /* get the name of the temporary file */    rc = pcsl_string_cat(pFileName, &TMP_FILE_EXTENSION, &tmpFileName);    if (rc != PCSL_STRING_OK) {        return OUT_OF_MEMORY;    }    /* open the file */    handle = storage_open(ppszError, &tmpFileName, OPEN_READ_WRITE_TRUNCATE);    if (*ppszError != NULL) {        pcsl_string_free(&tmpFileName);        return IO_ERROR;    }    /* write the whole buffer */    if (inBufferLen > 0) {        storageWrite(ppszError, handle, inBuffer, inBufferLen);    }    if (*ppszError != NULL) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?