/** * Opens a file and fills the content of the file in the result_buf. <BR> * This function made memory allocation inside. * * @param filename Path to the file. * @param result_buf Pointer to the buffer that will be filled by content of the file. * @return buffer file size in bytes */ long readJadFile(const pcsl_string * filename, char** result_buf) { int fd = 0; char* err = NULL; long bufsize = -1; int numread = 0; char* res = *result_buf; if (pcsl_string_length(filename) <= 0) { REPORT_INFO(LC_AMS, "readJadFile():No file name."); return BAD_PARAMS; } fd = storage_open(&err, filename, OPEN_READ); if(err != NULL) { REPORT_INFO1(LC_AMS, "readJadFile():Can't open jad file '%s'",err); storageFreeError(err); return NO_JAD_FILE; } bufsize = storageSizeOf(&err, fd); if((bufsize <= 0) || (err != NULL)) { REPORT_INFO1(LC_AMS, "readJadFile():Problem getting file size: %s", err ); storageFreeError(err); return IO_ERROR; } res = (char*)midpMalloc(bufsize+1); if (res == NULL || (err != NULL)) { REPORT_INFO1(LC_AMS, "readJadFile():Can't allocate memory. %s", err); storageFreeError(err); return OUT_OF_MEMORY; } memset(res,0,(bufsize+1)); REPORT_INFO2(LC_AMS, "fd = %d, bufsize = %ld\n", fd, bufsize); numread = storageRead(&err, fd, res, bufsize); if((numread <= 0) || (numread != bufsize) || (err)) { REPORT_INFO3(LC_AMS, "size = %ld, numread = %d, err = %s.", bufsize, numread, err); storageClose(&err, fd); return IO_ERROR; } REPORT_INFO2(LC_AMS, "size = %ld, numread = %d", bufsize, numread); storageClose(&err, fd); if(err != NULL) { REPORT_INFO1(LC_AMS, "Can't close jad file %s\n", err); } *result_buf = res; return bufsize; } /* end of readJadFile */
/** * Reads named secure resource of the suite with specified suiteId * from secure persistent storage. * * Note that when porting memory for the in/out parameter * returnValue MUST be allocated using pcsl_mem_malloc(). * The caller is responsible for freeing it. * * @param suiteId The suite id used to identify the MIDlet suite * @param resourceName The name of secure resource to read from storage * @param returnValue The in/out parameter that will return the * value part of the requested secure resource * (NULL is a valid return value) * @param valueSize The length of the secure resource value * * @return one of the error codes: * <pre> * ALL_OK, OUT_OF_MEMORY, NOT_FOUND, * SUITE_CORRUPTED_ERROR, BAD_PARAMS * </pre> */ MIDPError midp_suite_read_secure_resource(SuiteIdType suiteId, const pcsl_string* resourceName, jbyte **returnValue, jint *valueSize) { pcsl_string filename = PCSL_STRING_NULL; char *pszError = NULL; MIDPError errorCode; int bytesRead; int handle; *returnValue = NULL; *valueSize = 0; errorCode = get_secure_resource_file(suiteId, resourceName, &filename); if (errorCode != ALL_OK) { pcsl_string_free(&filename); return errorCode; } handle = storage_open(&pszError, &filename, OPEN_READ); pcsl_string_free(&filename); if (pszError != NULL) { storageFreeError(pszError); return SUITE_CORRUPTED_ERROR; } do { bytesRead = storageRead(&pszError, handle, (char*)valueSize, sizeof (int)); if (bytesRead != sizeof (int) || *valueSize == 0) break; *returnValue = (jbyte*)pcsl_mem_malloc(*valueSize * sizeof (jbyte)); if (*returnValue == NULL) { errorCode = OUT_OF_MEMORY; break; } bytesRead = storageRead(&pszError, handle, (char*)(*returnValue), *valueSize * sizeof (jbyte)); if (pszError != NULL || bytesRead != *valueSize) { errorCode = SUITE_CORRUPTED_ERROR; pcsl_mem_free(*returnValue); *returnValue = NULL; break; } } while (0); storageClose(&pszError, handle); storageFreeError(pszError); return errorCode; }
static void push_save() { char *error; bt_push_t *push = g_registry; pcsl_string full_name = PCSL_STRING_NULL; int storage; pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &BT_PUSH_FILENAME, &full_name); storage = storage_open(&error, &full_name, OPEN_READ_WRITE_TRUNCATE); pcsl_string_free(&full_name); if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Error opening `BtPush' file: %s", error); storageFreeError(error); return; } storageWrite(&error, storage, (char *)&g_count, sizeof(g_count)); while (push != NULL && error == NULL) { bt_push_t *next = push->next; storageWrite(&error, storage, (char *)&push->port, sizeof(bt_port_t)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->params, sizeof(bt_params_t)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->record.classes, sizeof(push->record.classes)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)&push->record.size, sizeof(push->record.size)); if (error != NULL) { break; } storageWrite(&error, storage, (char *)push->record.data, push->record.size); storageWrite(&error, storage, (char *)&push->record.id, sizeof(push->record.id)); if (error != NULL) { break; } push = next; } if (error != NULL) { REPORT_ERROR1(LC_PUSH, "Error writing `BtPush' file: %s", error); storageFreeError(error); } storageClose(&error, storage); storageFreeError(error); }
/** * Saves class of device and service classes for the next * usage of the same device. Makes nothing if an IO error * occured. */ static void saveCod(int cod) { char *error; int handle = openCodFile(); if (-1 != handle) { storageWrite(&error, handle, (char*)&cod, sizeof(int)); storageFreeError(error); } storageClose(&error, handle); storageFreeError(error); }
/** * 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) */ MIDPError write_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) { status = IO_ERROR; } /* close the file */ storageClose(&pszTemp, handle); storageFreeError(pszTemp); if (status == ALL_OK) { /* rename the temporary file */ storage_rename_file(ppszError, &tmpFileName, pFileName); if (*ppszError != NULL) { status = IO_ERROR; storage_delete_file(&pszTemp, &tmpFileName); storageFreeError(pszTemp); } } else { storage_delete_file(&pszTemp, &tmpFileName); storageFreeError(pszTemp); } pcsl_string_free(&tmpFileName); return (MIDPError)status; }
/** * Returns class of device and service classes saved for an * emulated device with the same address previous time. * It is considered to be the same device as current one. */ static int loadCod() { char *error; int cod = DEFAULT_COD; int handle = openCodFile(); if (-1 != handle) { storageRead(&error, handle, (char*)&cod, sizeof(int)); storageFreeError(error); } storageClose(&error, handle); storageFreeError(error); return cod; }
/** * Opens file that keeps device and service classes. * @return handle for the file, <code>-1</code> if opening failed. */ static int openCodFile() { char *error; int handle = -1; pcsl_string name = PCSL_STRING_EMPTY; int i; if (PCSL_STRING_OK == pcsl_string_append(&name, storage_get_root(INTERNAL_STORAGE_ID))) { for (i = 0; i < BT_ADDRESS_SIZE * 2; i++) { char c = (emul_data.local_addr[i / 2] >> ((i % 2) * 4)) & 0xf; if (c <= 9) { c += '0'; } else { c += 'a'; } if (PCSL_STRING_OK != pcsl_string_append_char(&name, c)) { break; } } if (i == BT_ADDRESS_SIZE * 2) { handle = storage_open(&error, &name, OPEN_READ_WRITE); storageFreeError(error); } } pcsl_string_free(&name); return handle; }
/** * Tells if a given suite is in a list of the installed suites. * * @param suiteId unique ID of the midlet suite * * @return ALL_OK if the suite is in the list of the installed suites, * NOT_FOUND if not, * IO_ERROR if an i/o error occured when reading the information * about the installed suites, * OUT_OF_MEMORY if out of memory or IO error, * SUITE_CORRUPTED_ERROR is suite is found in the list, but it's * corrupted. */ static MIDPError suite_in_list(SuiteIdType suiteId) { MIDPError status; char* pszError; MidletSuiteData* pData; /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } pData = get_suite_data(suiteId); if (pData != NULL) { /* * Make sure that suite is not corrupted. Return * SUITE_CORRUPTED_ERROR if the suite is corrupted. * Remove the suite before returning the status. */ status = check_for_corrupted_suite(suiteId); } else { status = NOT_FOUND; } return status; }
/** * If the suite exists, this function returns a unique identifier of * MIDlet suite. Note that suite may be corrupted even if it exists. * If the suite doesn't exist, a new suite ID is created. * * @param vendor name of the vendor that created the application, as * given in a JAD file * @param name name of the suite, as given in a JAD file * @param pSuiteId [out] receives the platform-specific suite ID of the * application given by vendorName and appName, or string with * a null data if suite does not exist, or * out of memory error occured, or suite is corrupted. * * @return ALL_OK if suite found, * NOT_FOUND if suite does not exist (so a new ID was created), * other error code in case of error */ MIDPError midp_get_suite_id(const pcsl_string* vendor, const pcsl_string* name, SuiteIdType* pSuiteId) { MIDPError status; char *pszError; MidletSuiteData* pData; *pSuiteId = UNUSED_SUITE_ID; /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } pData = g_pSuitesData; /* try to find a suite */ while (pData != NULL) { if (pcsl_string_equals(&pData->varSuiteData.suiteName, name) && pcsl_string_equals(&pData->varSuiteData.suiteVendor, vendor)) { *pSuiteId = pData->suiteId; return ALL_OK; /* IMPL_NOTE: consider SUITE_CORRUPTED_ERROR */ } pData = pData->nextEntry; } /* suite was not found - create a new suite ID */ status = midp_create_suite_id(pSuiteId); return (status == ALL_OK) ? NOT_FOUND : status; }
/** * Retrieves an ID of the storage where the midlet suite with the given suite ID * is stored. * * @param suiteId The application suite ID * @param pSuiteId [out] receives an ID of the storage where the suite is stored * * @return error code (ALL_OK if successful) */ MIDPError midp_suite_get_suite_storage(SuiteIdType suiteId, StorageIdType* pStorageId) { MIDPError status; MidletSuiteData* pData; char* pszError; if (pStorageId == NULL) { return BAD_PARAMS; } if (suiteId == INTERNAL_SUITE_ID) { /* handle a special case: predefined suite ID is given */ *pStorageId = INTERNAL_STORAGE_ID; return ALL_OK; } /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status == ALL_OK) { pData = get_suite_data(suiteId); if (pData) { *pStorageId = pData->storageId; } else { *pStorageId = UNUSED_STORAGE_ID; status = NOT_FOUND; } } return status; }
/** * Retrieves the number of the installed components belonging * to the given midlet suite. * * @param suiteId [in] ID of the MIDlet suite the information about * whose components must be retrieved * @param pNumOfComponents [out] pointer to variable to accept the number * of components * * @returns error code (ALL_OK if no errors) */ MIDPError midp_get_number_of_components(SuiteIdType suiteId, int* pNumOfComponents) { MIDPError status; char* pszError; MidletSuiteData* pData; int n = 0; do { if (midpInit(LIST_LEVEL) != 0) { status = OUT_OF_MEMORY; break; } /* load _suites.dat */ status = read_suites_data(&pszError); if (status != ALL_OK) { storageFreeError(pszError); break; } pData = g_pSuitesData; /* walk through the linked list */ while (pData != NULL) { if (pData->suiteId == suiteId && pData->type == COMPONENT_DYNAMIC) { n++; } pData = pData->nextEntry; } *pNumOfComponents = n; } while(0); return status; }
/** * Initializes a property set with the contents of a property file. * * @param props The property set to initialize * @param name The name of the property file to load. It is relative * to the <tt>configRoot</tt> path. * @param configRoot The fully qualified pathname to the root * configuration directory. * * @return <tt>0</tt> for success, otherwise <tt>-1</tt> */ static int initProps(Property** props, const pcsl_string * name, const pcsl_string * configRoot) { pcsl_string pathname; int fd = -1 ; char * errStr; /* Property file can be relative or at midp_home variable */ pcsl_string_cat(configRoot, name, &pathname); fd = storage_open(&errStr, &pathname, OPEN_READ); pcsl_string_free(&pathname); if (errStr != NULL) { REPORT_WARN2(LC_CORE, "Warning: could not open config file(%s): %s\n", pathname, errStr); storageFreeError(errStr); return 0; } /* Read through the file one line at a time */ if (parseConfig(fd, props) != 0) { return -1; } /* Close the storage handle */ storageClose(&errStr, fd); return 0; }
/** * 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 fileName 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) */ MIDPError write_file(char** ppszError, const pcsl_string* fileName, char* inBuffer, long inBufferLen) { int handle, status = ALL_OK; char* pszTemp; *ppszError = NULL; /* open the file */ handle = storage_open(ppszError, fileName, OPEN_WRITE); if (*ppszError != NULL) { return IO_ERROR; } /* write the whole buffer */ if (inBufferLen > 0) { storageWrite(ppszError, handle, inBuffer, inBufferLen); } else { storageTruncate(ppszError, handle, 0); } if (*ppszError != NULL) { status = IO_ERROR; } /* close the file */ storageClose(&pszTemp, handle); storageFreeError(pszTemp); return status; }
/** * Finishes the previously started transaction. * * @return ALL_OK if the transaction was successfully finished, * NOT_FOUND if the transaction has not been started, * IO_ERROR if I/O error */ MIDPError finish_transaction() { pcsl_string_status rc; pcsl_string transDataFile; char* pszTemp = NULL; MIDPError status = ALL_OK; if (!g_transactionStarted) { return NOT_FOUND; } /* transaction is finished, removed the transaction file */ /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } storage_delete_file(&pszTemp, &transDataFile); pcsl_string_free(&transDataFile); if (pszTemp != NULL) { storageFreeError(pszTemp); status = IO_ERROR; } g_transactionStarted = 0; return status; }
/** * Tries to repair the suite database. * * @return ALL_OK if succeeded, other value if failed */ MIDPError repair_suite_db() { /* IMPL_NOTE: should be replaced with more sophisticated routine. */ MIDPError status = ALL_OK; pcsl_string_status rc; pcsl_string suitesDataFile; char* pszTemp = NULL; /* get a full path to the _suites.dat */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &SUITE_DATA_FILENAME, &suitesDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } storage_delete_file(&pszTemp, &suitesDataFile); pcsl_string_free(&suitesDataFile); if (pszTemp != NULL) { storageFreeError(pszTemp); status = IO_ERROR; } if (g_isSuitesDataLoaded) { free_suites_data(); g_isSuitesDataLoaded = 0; } return status; }
static int seekChars(void* state, long offset, int whence) { long absPos; char* pszError; switch (whence) { case SEEK_SET: absPos = offset; storagePosition(&pszError, (int)state, absPos); break; case SEEK_END: absPos = sizeOfFile(state) + offset; storagePosition(&pszError, (int)state, absPos); break; case SEEK_CUR: absPos = storageRelativePosition(&pszError, (int)state, offset); break; default: return -1; } storageFreeError(pszError); return absPos; }
/* * Reads information about the installed midlet suite's component * from the storage. * * @param componentId unique ID of the component * @param ci ComponentInfo object to fill with the information about * the midlet suite's component having the given ID * * @exception IOException if an the information cannot be read * @exception IllegalArgumentException if suiteId is invalid or ci is null */ KNIEXPORT KNI_RETURNTYPE_VOID KNIDECL( com_sun_midp_midletsuite_DynamicComponentStorage_getComponentInfo) { ComponentIdType componentId = KNI_GetParameterAsInt(1); MIDPError status = ALL_OK; KNI_StartHandles(3); KNI_DeclareHandle(componentInfoObject); KNI_DeclareHandle(componentInfoClass); KNI_DeclareHandle(tmpHandle); KNI_GetParameterAsObject(2, componentInfoObject); KNI_GetObjectClass(componentInfoObject, componentInfoClass); do { char *pszError = NULL; MidletSuiteData *pData = NULL; /* Ensure that suite data are read */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { break; } pData = get_component_data(componentId); if (!pData) { status = NOT_FOUND; break; } KNI_RESTORE_INT_FIELD(componentInfoObject, componentInfoClass, "componentId", componentId); KNI_RESTORE_INT_FIELD(componentInfoObject, componentInfoClass, "suiteId", pData->suiteId); KNI_RESTORE_PCSL_STRING_FIELD(componentInfoObject, componentInfoClass, "displayName", &(pData->varSuiteData.displayName), tmpHandle); KNI_RESTORE_PCSL_STRING_FIELD(componentInfoObject, componentInfoClass, "version", &(pData->varSuiteData.suiteVersion), tmpHandle); KNI_RESTORE_BOOLEAN_FIELD(componentInfoObject, componentInfoClass, "trusted", pData->isTrusted); } while (0); if (status != ALL_OK) { if (status == NOT_FOUND) { KNI_ThrowNew(midpIllegalArgumentException, "bad component ID"); } else { KNI_ThrowNew(midpIOException, NULL); } } KNI_EndHandles(); KNI_ReturnVoid(); }
static long readChars(void* state, unsigned char* buffer, long n) { long size; char* pszError; size = storageRead(&pszError, (int)state, (char*)buffer, n); storageFreeError(pszError); return size; }
static long sizeOfFile(void* state) { long size; char* pszError; size = storageSizeOf(&pszError,(int)state); storageFreeError(pszError); return size; }
/** * Reads the given file into the given 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 buffer where the file contents should be stored * @param outBufferLen length of the outBuffer * * @return status code (ALL_OK if there was no errors) */ MIDPError read_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 (MIDPError)status; }
/** * 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; }
/** * 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; }
/** * Writes named secure resource of the suite with specified suiteId * to secure persistent storage. * * @param suiteId The suite id used to identify the MIDlet suite * @param resourceName The name of secure resource to read from storage * @param value The value part of the secure resource to be stored * @param valueSize The length of the secure resource value * * @return one of the error codes: * <pre> * ALL_OK, OUT_OF_MEMORY, NOT_FOUND, * SUITE_CORRUPTED_ERROR, BAD_PARAMS * </pre> */ MIDPError midp_suite_write_secure_resource(SuiteIdType suiteId, const pcsl_string* resourceName, jbyte *value, jint valueSize) { pcsl_string filename = PCSL_STRING_NULL; char *pszError = NULL; MIDPError errorCode; int handle; errorCode = get_secure_resource_file(suiteId, resourceName, &filename); if (errorCode != ALL_OK) { pcsl_string_free(&filename); return errorCode; } handle = storage_open(&pszError, &filename, OPEN_READ_WRITE_TRUNCATE); pcsl_string_free(&filename); if (pszError != NULL) { storageFreeError(pszError); return SUITE_CORRUPTED_ERROR; } do { storageWrite(&pszError, handle, (char*)&valueSize, sizeof (int)); if (pszError != NULL) break; storageWrite(&pszError, handle, (char*)value, valueSize * sizeof (jbyte)); if (pszError != NULL) break; } while (0); if (pszError != NULL) { errorCode = SUITE_CORRUPTED_ERROR; storageFreeError(pszError); } storageClose(&pszError, handle); storageFreeError(pszError); return errorCode; }
/** * 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; }
/** * Copies a file. * * @param srcName source file * @param destName destination file * * @return 0 for success */ static int copyFile(const pcsl_string * srcName, const pcsl_string * destName) { char* pszError = NULL; char* pszDummy = NULL; int src; int dest; char buffer[1024]; long bytesRead; src = storage_open(&pszError, srcName, OPEN_READ); if (pszError == NULL) { dest = storage_open(&pszError, destName, OPEN_READ_WRITE_TRUNCATE); if (pszError == NULL) { bytesRead = storageRead(&pszError, src, buffer, sizeof (buffer)); while (pszError == NULL && bytesRead > 0) { storageWrite(&pszError, dest, buffer, bytesRead); if (pszError == NULL) { bytesRead = storageRead(&pszError, src, buffer, sizeof (buffer)); } } storageClose(&pszDummy, dest); storageFreeError(pszDummy); pszDummy = NULL; } storageClose(&pszDummy, src); storageFreeError(pszDummy); } if (pszError != NULL) { REPORT_ERROR1(LC_AMS, "Error while copying file: %s", pszError); storageFreeError(pszError); return -1; } return 0; }
void midpCloseJar(void* handle) { MidpJarInfo* pJarInfo = (MidpJarInfo*)handle; char* pszError; if (handle == NULL) { return; } storageClose(&pszError, (int)(pJarInfo->fileObj.state)); storageFreeError(pszError); midpFree(pJarInfo); }
/** * Removes the files belonging to the specified component, or to all * components owned by the given suite. * * @param suiteId ID of the suite whose components are being removed * @param componentId ID of the component to remove or UNUSED_COMPONENT_ID * if all components of the suite are being removed * * @return status code, ALL_OK if no errors */ static MIDPError delete_components_files(SuiteIdType suiteId, ComponentIdType componentId) { pcsl_string componentFileName; char* pszError; int suiteFound = 0; MIDPError status = ALL_OK; MidletSuiteData* pData = g_pSuitesData; /* handle the list entries having the given suiteId */ while (pData != NULL) { if (pData->suiteId == suiteId) { suiteFound = 1; if (pData->type == COMPONENT_DYNAMIC && (componentId == UNUSED_COMPONENT_ID || pData->componentId == componentId)) { /* remove the file holding the component */ status = get_jar_path(COMPONENT_DYNAMIC, (jint)pData->componentId, &componentFileName); if (status != ALL_OK) { break; } storage_delete_file(&pszError, &componentFileName); if (pszError != NULL) { storageFreeError(pszError); /* it's an error only if the file exists */ if (storage_file_exists(&componentFileName)) { status = IO_ERROR; pcsl_string_free(&componentFileName); break; } } pcsl_string_free(&componentFileName); } } pData = pData->nextEntry; } if (status == ALL_OK && suiteFound == 0) { /* suite doesn't exist */ status = NOT_FOUND; } return status; }
/** * Starts a new transaction of the given type. * * @param transactionType type of the new transaction * @param suiteId ID of the suite, may be UNUSED_SUITE_ID * @param pFilename name of the midlet suite's file, may be NULL * * @return ALL_OK if no errors, * IO_ERROR if I/O error */ MIDPError begin_transaction(MIDPTransactionType transactionType, SuiteIdType suiteId, const pcsl_string *pFilename) { pcsl_string_status rc; pcsl_string transDataFile; char *pszError = NULL; MIDPError status = ALL_OK; char pBuffer[MAX_FILENAME_LENGTH + sizeof(int) /* file name length */ + sizeof(suiteId) + sizeof(transactionType)]; char *p = pBuffer; int len = sizeof(suiteId) + sizeof(transactionType); *(MIDPTransactionType*)p = transactionType; p += sizeof(MIDPTransactionType); *(SuiteIdType*)p = suiteId; p += sizeof(SuiteIdType); if (pFilename != NULL) { int strLen; rc = pcsl_string_convert_to_utf16(pFilename, (jchar*)(p + sizeof(int)), MAX_FILENAME_LENGTH / sizeof(jchar), &strLen); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } *(int*)p = strLen; len += strLen; } /* get a full path to the transaction data file */ rc = pcsl_string_cat(storage_get_root(INTERNAL_STORAGE_ID), &TRANSACTION_DATA_FILENAME, &transDataFile); if (rc != PCSL_STRING_OK) { return OUT_OF_MEMORY; } status = write_file(&pszError, &transDataFile, pBuffer, len); storageFreeError(pszError); pcsl_string_free(&transDataFile); g_transactionStarted = 1; return status; }
/** * Tells if a given suite is in a list of the installed suites. * * @param suiteId unique ID of the midlet suite * * @return ALL_OK if the suite is in the list of the installed suites, * NOT_FOUND if not, * IO_ERROR if an i/o error occured when reading the information * about the installed suites, * OUT_OF_MEMORY if out of memory or IO error, * SUITE_CORRUPTED_ERROR is suite is found in the list, but it's * corrupted. */ static MIDPError suite_in_list(ComponentType type, SuiteIdType suiteId, ComponentIdType componentId) { MIDPError status; char* pszError; MidletSuiteData* pData; #if !ENABLE_DYNAMIC_COMPONENTS /** to supress compilation warnings */ (void)type; (void)componentId; #endif /* load _suites.dat */ status = read_suites_data(&pszError); storageFreeError(pszError); if (status != ALL_OK) { return status; } #if ENABLE_DYNAMIC_COMPONENTS if (type == COMPONENT_DYNAMIC) { pData = get_component_data(componentId); if (pData == NULL) { status = NOT_FOUND; } } else { #endif /* ENABLE_DYNAMIC_COMPONENTS */ pData = get_suite_data(suiteId); if (pData != NULL) { /* * Make sure that suite is not corrupted. Return * SUITE_CORRUPTED_ERROR if the suite is corrupted. * Remove the suite before returning the status. */ status = check_for_corrupted_suite(suiteId); } else { status = NOT_FOUND; } #if ENABLE_DYNAMIC_COMPONENTS } #endif return status; }
/** * Retrieves the number of installed midlet suites. * * @param pNumOfSuites [out] pointer to variable to accept the number of suites * * @returns error code (ALL_OK if no errors) */ MIDPError midp_get_number_of_suites(int* pNumOfSuites) { MIDPError status; char* pszError; do { /* * 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) { status = OUT_OF_MEMORY; break; } /* load _suites.dat */ status = read_suites_data(&pszError); if (status == ALL_OK) { #if ENABLE_DYNAMIC_COMPONENTS MidletSuiteData* pData = g_pSuitesData; int num = 0; /* walk through the linked list */ while (pData != NULL) { if (pData->type == COMPONENT_REGULAR_SUITE) { num++; } pData = pData->nextEntry; } *pNumOfSuites = num; #else *pNumOfSuites = g_numberOfSuites; #endif /* ENABLE_DYNAMIC_COMPONENTS */ } else { storageFreeError(pszError); } } while(0); return status; }