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