⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nvs.c

📁 这是DVD中伺服部分的核心代码
💻 C
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2002 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file nvs.c
 *
 * $Revision: 1.9 $ 
 *
 * Public API to the Non-Volatile Storage (NVS) module.
 *
 */

#include <stdio.h>
#include <string.h>
#include "vdvd_types.h"
#include "nvs.h"
#include "osapi.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

/* Debug macros */
#define DBG_NVS     DBG_ERROR
#define DBG_ON(x)   (DBG_NVS >= x)

/**
 * Local constants
 * TODO: Make the path for sysparam.dat configurable
 */
#define NVS_DEV_LIMIT   1

#if 1
    #define NVS_FILE        "sysparam.dat"
#else
    #define NVS_FILE        "/hd0/sysparam.dat"
#endif

/**
 * NVS handle data.
 */
typedef struct tagNVS_HANDLE_DATA
{
    BYTE        bDevNumber;
    FILE        *pDataFile;
    ULONG       ulStorageSize;
    PVOID       pvBuffer;
    OS_SEM_ID   critical_section;
} NVS_HANDLE_DATA;

/**
 * NVS manager
 */
typedef struct tagNVS_MANAGER
{
    USHORT          usCount;
    NVS_HANDLE_DATA *aNVS[NVS_DEV_LIMIT];
} NVS_MANAGER;

/**
 * Local variables
 */
static NVS_MANAGER  m_NvsManager = {0, {NULL} };

/**
 * NVSOpen -- Create a handle to an NVS device.
 *
 * @param
 *      bDevNum -- device number to use for the NVS handle
 *      ulSize  -- size of nvs buffer for this device handle
 *
 * @retval
 *      NVS_HANDLE, a handle to an NVS device, if successful
 *      NULL on failure
 *
 * @remark
 *      For this implementation, HD is the only available storage device,
 *      so bDevNum is ignored.
 */
NVS_HANDLE  NVSOpen(BYTE bDevNum, ULONG ulSize)
{
    NVS_HANDLE_DATA *pNvs   = NULL;
    NVS_HANDLE      hNVS    = NULL;

    /* Check if we have reached the device limit */
    if (m_NvsManager.usCount == NVS_DEV_LIMIT)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: device limit reached!\n"));
        goto errout;
    }

    /* Allocate NVS handle */
    pNvs = (NVS_HANDLE_DATA *)OS_MemAlloc(sizeof(NVS_HANDLE_DATA) );
    if (pNvs == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure allocating handle!\n"));
        goto errout;
    }

    /* Create buffer for this handle */
    pNvs->pvBuffer = (PVOID)OS_MemAlloc(ulSize);
    if (pNvs->pvBuffer == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure creating buffer!\n"));
        goto errout;
    }

    /* Set the device number and storage size */
    pNvs->bDevNumber    = bDevNum;
    pNvs->ulStorageSize = ulSize;

    /* Create critical section semaphore */
    pNvs->critical_section = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (pNvs->critical_section == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: Could not create semaphore\n"));
        goto errout;
    }

    /* Open the storage file in read/write mode */
    pNvs->pDataFile = fopen(NVS_FILE, "r+");
    if (pNvs->pDataFile == NULL)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("NVSOpen: Creating NVS file\n"));

        /* create file */
        pNvs->pDataFile = fopen(NVS_FILE, "w");
        if (pNvs->pDataFile == NULL)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure creating file!\n"));
            goto errout;
        }

        /* reopen file in read/write mode */
        pNvs->pDataFile = freopen(NVS_FILE, "r+", pNvs->pDataFile);
        if (pNvs->pDataFile == NULL)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("NVSOpen: failure re-opening file in rw mode!\n"));
            goto errout;
        }
    }

    /* Add this NVS handle to the NVS manager */
    m_NvsManager.aNVS[m_NvsManager.usCount] = pNvs;
    m_NvsManager.usCount++;

    /* Set the NVS handle to return */
    hNVS = (NVS_HANDLE)pNvs;
    pNvs = NULL;

    DBGPRINT(DBG_ON(DBG_TRACE), ("NVSOpen: NVS handle successfully created\n"));

    return (hNVS);

errout:

    if (pNvs != NULL)
    {
        if (pNvs->pDataFile != NULL)
        {
            /* close the file */
            fclose(pNvs->pDataFile);
        }

        /* delete critical section sem */
        if (pNvs->critical_section != 0)
        {
            OS_SemDelete(pNvs->critical_section);
            pNvs->critical_section = 0;
        }

        /* free buffer */
        if (pNvs->pvBuffer != NULL)
        {
            /* free NVS handle data */
            OS_MemFree(pNvs->pvBuffer);
            pNvs->pvBuffer = NULL;
        }

        /* free NVS handle data */
        OS_MemFree(pNvs);
        pNvs = NULL;
    }

    return (NULL);
}

/**
 * NVSClose -- Delete the handle to an NVS device
 *
 * @param
 *      tNVS -- handle to an NVS device
 *
 * @retval
 *    NVS_ERR value
 */
NVS_ERR  NVSClose(NVS_HANDLE tNVS)
{
    if (tNVS != NULL)
    {
        NVS_HANDLE_DATA *pNvs   = (NVS_HANDLE_DATA *)tNVS;
        USHORT          i;

        /* close the file */
        if (pNvs->pDataFile != NULL)
        {
            fclose(pNvs->pDataFile);
        }

        /* delete critical section sem */
        if (pNvs->critical_section != 0)
        {
            OS_SemDelete(pNvs->critical_section);
            pNvs->critical_section = 0;
        }

        /* free buffer */
        if (pNvs->pvBuffer != NULL)
        {
            /* free NVS handle data */
            OS_MemFree(pNvs->pvBuffer);
            pNvs->pvBuffer = NULL;
        }

        /* remove this NVS handle from NVS manager */
        for (i = 0; i < m_NvsManager.usCount; i++)
        {
            if (m_NvsManager.aNVS[i] == pNvs)
            {
                m_NvsManager.aNVS[i] = NULL;
                m_NvsManager.usCount--;
                break;
            }
        }

        /* free NVS handle data */
        OS_MemFree(pNvs);
        pNvs = NULL;

        /* point handle to NULL */
        tNVS = NULL;

        DBGPRINT(DBG_ON(DBG_TRACE), ("NVSClose: NVS handle deleted\n"));

        return (NVS_SUCCESS);
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSClose: NVS handle is NULL!\n"));
        return (NVS_FAILURE);
    }
}

/**
 * NVSLoad -- Load buffer with data stored in NVS device
 *
 * @param
 *      tNVS        -- handle to an NVS device to load from
 *      pvBuffer    -- buffer to load data into
 *      ulBufSize   -- size of buffer pointed to by pvBuffer
 *
 * @retval
 *    NVS_ERR value
 *
 * @remark
 *      ulBufSize must be the same size that was specified when the NVS
 *      device was open.  If sizes are different, then NVS_INVALID_BUFFER_SIZE
 *      will be returned.
 */
NVS_ERR  NVSLoad(NVS_HANDLE tNVS, PVOID pvBuffer, ULONG ulBufSize)
{
    NVS_HANDLE_DATA *pNvs   = (NVS_HANDLE_DATA *)tNVS;

    /* Check for Null pointers */
    if ( (pNvs == NULL) || (pvBuffer == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: NULL pointer!\n"));
        return (NVS_NULL_PTR);
    }

    /* Check for valid buffer size */
    if (pNvs->ulStorageSize != ulBufSize)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: Invalid buffer size!\n"));
        return (NVS_INVALID_BUFFER_SIZE);
    }

    /* entering critical section */
    OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);

    /* Zero the NVS storage buffer before reading file data into it */
    memset(pNvs->pvBuffer, 0x00, (size_t)pNvs->ulStorageSize);

    /* flush file stream */
    if (fflush(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure flushing file stream!\n"));
        goto errout;
    }

    /* Set file position to beginning of file */
    if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure setting file position!\n"));
        goto errout;
    }

    /* Read the file and store data in NVS storage buffer */
    fread(pNvs->pvBuffer, 1, (size_t)pNvs->ulStorageSize, pNvs->pDataFile);

    /* check for error from read */
    if (ferror(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSLoad: failure reading file!\n"));
        goto errout;
    }

    /* copy this NVS storage buffer to return buffer */
    memcpy(pvBuffer, pNvs->pvBuffer, ulBufSize);

    /* leaving critical section */
    OS_SemGive(pNvs->critical_section);

    return (NVS_SUCCESS);

errout:

    OS_SemGive(pNvs->critical_section);

    return (NVS_FAILURE);
}

/**
 * NVSStore -- Store data from buffer onto NVS device.
 *
 * @param
 *      tNVS        -- handle to an NVS device to store data to
 *      pvBuffer    -- buffer containing the data to store
 *      ulBufSize   -- size of buffer pointed to by pvBuffer
 *
 * @retval
 *    NVS_ERR value
 *
 * @remark
 *      ulBufSize must be the same size that was specified when the NVS
 *      device was open.  If sizes are different, then NVS_INVALID_BUFFER_SIZE
 *      will be returned.
 */
NVS_ERR  NVSStore(NVS_HANDLE tNVS, PVOID pvBuffer, ULONG ulBufSize)
{
    NVS_HANDLE_DATA *pNvs   = (NVS_HANDLE_DATA *)tNVS;

    /* Check for Null pointers */
    if ( (pNvs == NULL) || (pvBuffer == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: NULL pointer!\n"));
        return (NVS_NULL_PTR);
    }

    /* Check for valid buffer size */
    if (pNvs->ulStorageSize != ulBufSize)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: Invalid buffer size!\n"));
        return (NVS_INVALID_BUFFER_SIZE);
    }

    /* entering critical section */
    OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);

    /* flush file stream */
    if (fflush(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure flushing file stream!\n"));
        goto errout;
    }

    /* Set file position to beginning of file */
    if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure setting file position!\n"));
        goto errout;
    }

    /* Write the buffer to the NVS file */
    fwrite(pvBuffer, 1, (size_t)ulBufSize, pNvs->pDataFile);

    /* check for error from write */
    if (ferror(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSStore: failure writing file!\n"));
        goto errout;
    }

    /* leaving critical section */
    OS_SemGive(pNvs->critical_section);

    return (NVS_SUCCESS);

errout:

    OS_SemGive(pNvs->critical_section);

    return (NVS_FAILURE);
}

/**
 * NVSSet -- Set entire buffer on NVS device to a specified value.
 *
 * @param
 *      tNVS    -- handle to an NVS device
 *      bValue  -- value to set each byte of NVS buffer to
 *
 * @retval
 *    NVS_ERR value
 */
NVS_ERR  NVSSet(NVS_HANDLE tNVS, BYTE bValue)
{
    NVS_HANDLE_DATA *pNvs   = (NVS_HANDLE_DATA *)tNVS;

    /* Check for Null pointers */
    if (pNvs == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: NULL pointer!\n"));
        return (NVS_NULL_PTR);
    }

    /* entering critical section */
    OS_SemTake(pNvs->critical_section, OS_WAIT_FOREVER);

    /* set the NVS storage buffer before writing data into file */
    memset(pNvs->pvBuffer, (int)bValue, (size_t)pNvs->ulStorageSize);

    /* flush file stream */
    if (fflush(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure flushing file stream!\n"));
        goto errout;
    }

    /* Set file position to beginning of file */
    if (fseek(pNvs->pDataFile, 0, SEEK_SET) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure setting file position!\n"));
        goto errout;
    }

    /* Write the buffer to the NVS file */
    fwrite(pNvs->pvBuffer, 1, (size_t)pNvs->ulStorageSize, pNvs->pDataFile);

    /* check for error from write */
    if (ferror(pNvs->pDataFile) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("NVSSet: failure writing file!\n"));
        goto errout;
    }

    /* leaving critical section */
    OS_SemGive(pNvs->critical_section);

    return (NVS_SUCCESS);

errout:

    OS_SemGive(pNvs->critical_section);

    return (NVS_FAILURE);
}

⌨️ 快捷键说明

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