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 + -
显示快捷键?