suitestore_intern.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,943 行 · 第 1/4 页
C
1,943 行
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 status;}#define ADJUST_POS_IN_BUF(pos, bufferLen, n) \ pos += n; \ bufferLen -= n;/** * Reads the file with information about the installed suites. * * Note that if the value of the global variable g_numberOfSuites * is zero, this function does nothing. * * @param ppszError pointer to character string pointer to accept an error * * @return status code: ALL_OK if no errors, * OUT_OF_MEMORY if malloc failed * IO_ERROR if an IO_ERROR, * SUITE_CORRUPTED_ERROR if the suite database is corrupted */MIDPErrorread_suites_data(char** ppszError) { MIDPError status; int i; long bufferLen, pos; char* buffer = NULL; pcsl_string_status rc; pcsl_string suitesDataFile; MidletSuiteData *pSuitesData = NULL; MidletSuiteData *pData, *pPrevData = NULL; int numOfSuites = 0; *ppszError = NULL; /* g_pSuitesData may be non-NULL only if g_isSuitesDataLoaded is true */ if (g_isSuitesDataLoaded) { return ALL_OK; } if (midpInit(LIST_LEVEL) != 0) { return OUT_OF_MEMORY; } /* 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) { REPORT_CRIT(LC_AMS,"read_suites_data(): OUT OF MEMORY !! (1)"); return OUT_OF_MEMORY; } /* read the file */ status = read_file(ppszError, &suitesDataFile, &buffer, &bufferLen); pcsl_string_free(&suitesDataFile); if (status == NOT_FOUND || (status == ALL_OK && bufferLen == 0)) { /* _suites.dat is absent or empty, it's a normal situation */ g_pSuitesData = NULL; g_numberOfSuites = 0; g_isSuitesDataLoaded = 1; return ALL_OK; } if (status == ALL_OK && bufferLen < (long) sizeof(int)) { pcsl_mem_free(buffer); status = SUITE_CORRUPTED_ERROR; /* _suites.dat is corrupted */ REPORT_ERROR(LC_AMS,"read_suites_data(): failed to read '_suites.dat', file is corrupted (1)"); } if (status != ALL_OK) { /* if read_file() returned not ALL_OK, buffer is NULL, no need to free it */ return status; } /* parse contents of the suite database */ pos = 0; numOfSuites = *(int*)&buffer[pos]; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(int)); for (i = 0; i < numOfSuites; i++) { if (bufferLen < (long)MIDLET_SUITE_DATA_SIZE) { status = SUITE_CORRUPTED_ERROR; REPORT_ERROR(LC_AMS,"read_suites_data():_suites.dat - wrong file length. file is corrupted"); break; } pData = (MidletSuiteData*) pcsl_mem_malloc(sizeof(MidletSuiteData)); if (!pData) { status = OUT_OF_MEMORY; REPORT_CRIT(LC_AMS,"read_suites_data(): OUT OF MEMORY !! (2)"); break; } /* IMPL_NOTE: introduce pcsl_mem_copy() */ memcpy((char*)pData, (char*)&buffer[pos], MIDLET_SUITE_DATA_SIZE); ADJUST_POS_IN_BUF(pos, bufferLen, MIDLET_SUITE_DATA_SIZE); /* IMPL_NOTE: we set the pointer to NULL and pcsl_strings * to PCSL_STRING_NULL by filling memory with zeroes. * We have to avoid garbage in pointers because in case of an error * we will free all allocated structures. */ memset(&pData->varSuiteData, 0, sizeof(pData->varSuiteData)); if (pPrevData) { pPrevData->nextEntry = pData; } else { pSuitesData = pData; } pData->nextEntry = NULL; pPrevData = pData; /* this suite was not checked if it is corrupted */ pData->isChecked = 0; /* setup pJarHash */ if (pData->jarHashLen > 0) { pData->varSuiteData.pJarHash = pcsl_mem_malloc(pData->jarHashLen); if (pData->varSuiteData.pJarHash == NULL) { status = OUT_OF_MEMORY; REPORT_CRIT(LC_AMS,"read_suites_data(): OUT OF MEMORY !! (3)"); break; } memcpy(pData->varSuiteData.pJarHash, (char*)&buffer[pos], pData->jarHashLen); ADJUST_POS_IN_BUF(pos, bufferLen, pData->jarHashLen); } else { pData->varSuiteData.pJarHash = NULL; } /* setup string fields */ { int i; jint strLen; pcsl_string* pStrings[7]; pStrings[0] = &pData->varSuiteData.midletClassName; pStrings[1] = &pData->varSuiteData.displayName; pStrings[2] = &pData->varSuiteData.iconName; pStrings[3] = &pData->varSuiteData.suiteVendor; pStrings[4] = &pData->varSuiteData.suiteName; pStrings[5] = &pData->varSuiteData.pathToJar; pStrings[6] = &pData->varSuiteData.pathToSettings; status = ALL_OK; for (i = 0; i < (int) (sizeof(pStrings) / sizeof(pStrings[0])); i++) { if (bufferLen < (long)sizeof(jint)) { status = IO_ERROR; /* _suites.dat is corrupted */ REPORT_ERROR(LC_AMS,"read_suites_data(): failed to read '_suites.dat', file is corrupted (2)"); break; } /* * We have to guarantee 4 - bytes alignment to use this: * strLen = *(jint*)&buffer[pos]; * on RISC CPUs. */ pos = SUITESTORE_ALIGN_4(pos); strLen = *(jint*)&buffer[pos]; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(jint)); if (bufferLen < (long)strLen) { status = IO_ERROR; /* _suites.dat is corrupted */ REPORT_ERROR(LC_AMS,"read_suites_data(): failed to read '_suites.dat', file is corrupted (3)"); break; } if (strLen > 0) { rc = pcsl_string_convert_from_utf16( (jchar*)&buffer[pos], strLen, pStrings[i]); if (rc != PCSL_STRING_OK) { status = OUT_OF_MEMORY; REPORT_CRIT(LC_AMS,"read_suites_data(): OUT OF MEMORY !! (4)"); break; } ADJUST_POS_IN_BUF(pos, bufferLen, strLen * sizeof(jchar)); } else { *pStrings[i] = strLen ? PCSL_STRING_NULL : PCSL_STRING_EMPTY; } } } if (status != ALL_OK) { break; } } /* end for (numOfSuites) */ pcsl_mem_free(buffer); g_numberOfSuites = numOfSuites; g_pSuitesData = pSuitesData; g_isSuitesDataLoaded = 1; if (status != ALL_OK) { free_suites_data(); } return status;}/** * Writes the file with information about the installed suites. * * Note that if the value of the global variable g_numberOfSuites * is zero, the file will be truncated. * * @param ppszError pointer to character string pointer to accept an error * * @return status code: ALL_OK if no errors, * OUT_OF_MEMORY if malloc failed * IO_ERROR if an IO_ERROR */MIDPErrorwrite_suites_data(char** ppszError) { MIDPError status = ALL_OK; long bufferLen, pos; char* buffer = NULL; pcsl_string_status rc; pcsl_string suitesDataFile; MidletSuiteData* pData; *ppszError = 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; } if (!g_numberOfSuites) { /* truncate the file with the list of the installed suites */ status = write_file(ppszError, &suitesDataFile, buffer, 0); pcsl_string_free(&suitesDataFile); return status; } /* allocate a buffer where the information about all suites will be saved */ bufferLen = g_numberOfSuites * (sizeof(MidletSuiteData) + MAX_VAR_SUITE_DATA_LEN); /* space to store the number of suites */ bufferLen += sizeof(int); buffer = pcsl_mem_malloc(bufferLen); if (buffer == NULL) { pcsl_string_free(&suitesDataFile); return OUT_OF_MEMORY; } /* assemble the information about all suites into the allocated buffer */ pos = 0; pData = g_pSuitesData; *(int*)&buffer[pos] = g_numberOfSuites; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(int)); while (pData != NULL) { memcpy((char*)&buffer[pos], (char*)pData, MIDLET_SUITE_DATA_SIZE); ADJUST_POS_IN_BUF(pos, bufferLen, MIDLET_SUITE_DATA_SIZE); /* setup pJarHash */ if (pData->jarHashLen > 0) { memcpy((char*)&buffer[pos], pData->varSuiteData.pJarHash, pData->jarHashLen); ADJUST_POS_IN_BUF(pos, bufferLen, pData->jarHashLen); } /* setup string fields */ { int i, convertedLen; jint strLen; pcsl_string* pStrings[7]; pStrings[0] = &pData->varSuiteData.midletClassName; pStrings[1] = &pData->varSuiteData.displayName; pStrings[2] = &pData->varSuiteData.iconName; pStrings[3] = &pData->varSuiteData.suiteVendor; pStrings[4] = &pData->varSuiteData.suiteName; pStrings[5] = &pData->varSuiteData.pathToJar; pStrings[6] = &pData->varSuiteData.pathToSettings; status = ALL_OK; for (i = 0; i < (int) (sizeof(pStrings) / sizeof(pStrings[0])); i++) { strLen = pcsl_string_utf16_length(pStrings[i]); /* * We have to guarantee 4 - bytes alignment to use this: * *(jint*)&buffer[pos] = strLen; * on RISC CPUs. */ pos = SUITESTORE_ALIGN_4(pos); *(jint*)&buffer[pos] = strLen; ADJUST_POS_IN_BUF(pos, bufferLen, sizeof(jint)); /* assert(bufferLen > 0); */ if (strLen > 0) { rc = pcsl_string_convert_to_utf16(pStrings[i], (jchar*)&buffer[pos], bufferLen / sizeof(jchar), &convertedLen); if (rc != PCSL_STRING_OK) { status = OUT_OF_MEMORY; break; } ADJUST_POS_IN_BUF(pos, bufferLen, convertedLen * sizeof(jchar)); } } } if (status != ALL_OK) { break; } pData = pData->nextEntry; } if (status == ALL_OK) { /* write the buffer into the file */ status = write_file(ppszError, &suitesDataFile, buffer, pos); } /* cleanup */ pcsl_mem_free(buffer); pcsl_string_free(&suitesDataFile); return status;}#undef ADJUST_POS_IN_BUF/** * Builds a full file name using the storage root and MIDlet suite by ID. * * @param suiteId suite ID * @param filename filename without a root path * @param sRoot receives full name of the file * * @return the status: ALL_OK if ok, OUT_OF_MEMORY if out of memory */static MIDPErrorget_suite_filename(SuiteIdType suiteId, const pcsl_string* filename, pcsl_string* sRoot) { int sRoot_len; const pcsl_string* root; root = storage_get_root(INTERNAL_STORAGE_ID); *sRoot = PCSL_STRING_EMPTY; sRoot_len = pcsl_string_length(root) + GET_SUITE_ID_LEN(suiteId) + pcsl_string_length(filename); pcsl_string_predict_size(sRoot, sRoot_len); if (PCSL_STRING_OK == pcsl_string_append(sRoot, root) && PCSL_STRING_OK == pcsl_string_append(sRoot, midp_suiteid2pcsl_string(suiteId)) && PCSL_STRING_OK == pcsl_string_append(sRoot, filename)) { return ALL_OK; } else { pcsl_string_free(sRoot); *sRoot = PCSL_STRING_NULL; return OUT_OF_MEMORY; }}/** * Builds a full file name using the storage root and MIDlet suite by ID. * get_suite_filename is used to build a filename after validation checks. * * @param suiteId suite ID * @param filename filename without a root path * @param res receives full name of the file * * @return the status: * ALL_OK if ok, * NOT_FOUND mean the suite does not exist, * OUT_OF_MEMORY if out of memory, * IO_ERROR if an IO_ERROR */MIDPErrorbuild_suite_filename(SuiteIdType suiteId, const pcsl_string* filename, pcsl_string* res) { MIDPError status; *res = PCSL_STRING_NULL; status = midp_suite_exists(suiteId); /* Ignore if suite is corrupted */ if ((status != ALL_OK) && (status != SUITE_CORRUPTED_ERROR)) { return status; } return get_suite_filename(suiteId, filename, res);}/** * 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 MIDPErrorget_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;}/** * Gets location of the properties file * for 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 checkSuiteExists true if suite should be checked for existence or not * @param pFilename 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 * </pre> */MIDPError get_property_file(SuiteIdType suiteId, jboolean checkSuiteExists, pcsl_string *pFilename) { return get_suite_resource_file(suiteId, &PROPS_FILENAME, checkSuiteExists, pFilename);}/** * Gets filename of the secure suite resource by suiteId and resource name *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?