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

📄 keyvalue.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  Module: keyvalue.c
//  
//  Defines the interface to the OAL Key-Value component. The Key-value
//  component provides a framework to specify bootloader and CE boot time
//  parameters from a text file. The text file is included in the image
//  using the BIB file.
//
#include <windows.h>
#include <oal.h>
#include <romldr.h>
#include <pehdr.h>

// External Functions

//------------------------------------------------------------------------------
//  Extern: pTOC
//
//  Pointer to the ROM header's Table of Contents (TOC).
//

extern ROMHDR * volatile const pTOC;

// External Variables 
 
// Global Variables 

// Defines 

//------------------------------------------------------------------------------
//  Define: DUMP_CONTEXT
//
//  This define controls whether the KeyValue control block is 
//  dumped after every operation. This is for debug only.
//

#undef DUMP_CONTEXT

// Types
 
// Local Variables 
 
// Local Functions 

static  OAL_KEYVALUE_STATUS 
ProcessFile ( POAL_KEYVALUE, UINT32 StartAddr, UINT32 Length );

static  UINT32              
getline( UINT8 *pRead, UINT8 *pEnd, UINT8 *pLine, UINT32 LineLen );

static  UINT32              
gettoken( UINT8 *pLine, UINT8 *pToken, UINT32 TokenLen );

static  UINT32              
StoreLiteral( POAL_KEYVALUE, char *Literal, UINT32 Length );

static  void                
DumpCB( POAL_KEYVALUE );


//------------------------------------------------------------------------------
//  Function:  OALKeyValueInit
//
//  Initializes the key-value component. The caller specifies the literal
//  table and its size.
//

BOOL OALKeyValueInit( POAL_KEYVALUE pKeyValue, UINT8 *pTable, UINT32 TableSize )
{
    OALMSG( OAL_FUNC && OAL_KEYVAL, 
    (TEXT("+OALKeyValueInit( 0x%x, 0x%x, %d )\r\n"), pKeyValue, pTable, TableSize ));

    // Validate arguments

    if( (pKeyValue == NULL) || (pTable == NULL) )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueInit: NULL argument.\r\n" )));
        return( FALSE );
    }

    if( TableSize == 0 )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueInit: TableSize zero.\r\n" )));
        return( FALSE );
    }

    // Clear control block and table

    memset( pKeyValue, 0, sizeof(OAL_KEYVALUE) );
    memset( pTable, 0, TableSize );

    // Setup control block

    pKeyValue->Signature = OAL_KEYVALUE_SIGNATURE;
    pKeyValue->Space     = TableSize;
    pKeyValue->TableSize = TableSize;
    pKeyValue->pEnd      = pTable + TableSize - 1;
    pKeyValue->pTable    = pTable;

    // Indicate status

    DumpCB( pKeyValue );
    OALMSG( OAL_FUNC && OAL_KEYVAL, (TEXT("-OALKeyValueInit(rc=1)\r\n" )));
    return( TRUE );
}

//------------------------------------------------------------------------------
//  Function:  OALKeyValueAdd
//
//  This function adds the key-value table to its internal storage area. 
//

OAL_KEYVALUE_STATUS OALKeyValueAdd( POAL_KEYVALUE pKeyValue, char *Key, char *Value )
{
UINT32              i;
OAL_KEYVALUE_PAIR   Pair;
POAL_KEYVALUE_PAIR  pPair;
UINT32              TotalLen;

    OALMSG( OAL_FUNC && OAL_KEYVAL, 
    (TEXT("+OALKeyValueAdd( 0x%x, '%S', '%S' )\r\n"), pKeyValue, Key, Value ));

    // Validate arguments

    if( (pKeyValue == NULL) || (Key == NULL) || (Value == NULL) )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: NULL argument.\r\n" )));
        return( OAL_KEYVALUE_ARG );
    }

    // Validate initialization

    if( pKeyValue->Signature != OAL_KEYVALUE_SIGNATURE )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: not initialized.\r\n" )));
        return( OAL_KEYVALUE_INIT );
    }

    Pair.KeyLength = strlen( Key ) + 1;             // add space for null
    Pair.ValueLength = strlen( Value ) + 1;         // add space for null

    if( (Pair.KeyLength == 1) || (Pair.ValueLength == 1) )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: invalid key-value pair.\r\n" )));
        return( OAL_KEYVALUE_ARG );
    }

    // Search the table for Key as duplicates are not allowed.

    for( i=0, pPair = (POAL_KEYVALUE_PAIR )pKeyValue->pTable;
         i < pKeyValue->Count;
         i++, pPair++ )
    {
        if( strncmp( Key, (pKeyValue->pTable + pPair->KeyOffset), Pair.KeyLength ) == 0 )
        {
            OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: duplicate key.\r\n" )));
            return( OAL_KEYVALUE_USED );
        }
    }

    // Make sure we have room for data type and literals

    TotalLen = sizeof(OAL_KEYVALUE_PAIR) + Pair.KeyLength + Pair.ValueLength;

    if( TotalLen > pKeyValue->Space )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: insufficient space.\r\n" )));
        return( OAL_KEYVALUE_SPACE );
    }

    // Store the literal strings in the table

    Pair.KeyOffset   = StoreLiteral( pKeyValue, Key,   Pair.KeyLength );
    Pair.ValueOffset = StoreLiteral( pKeyValue, Value, Pair.ValueLength );

    // Save the key-value pair info to the front of the table.

    memcpy( &(((OAL_KEYVALUE_PAIR *)pKeyValue->pTable)[pKeyValue->Count]),
            &Pair,
            sizeof(OAL_KEYVALUE_PAIR) );

    // Update the number of entries and remainging space

    pKeyValue->Count++;
    pKeyValue->Space -= TotalLen;

    // Indicate status

    DumpCB( pKeyValue );
    OALMSG( OAL_FUNC && OAL_KEYVAL, (TEXT("-OALKeyValueAdd(SUCCESS)\r\n")));
    return( OAL_KEYVALUE_SUCCESS );
}

//------------------------------------------------------------------------------
//  Function:  OALKeyValueGet
//
//  Given the Key, returns the associated Value, if the Key is found. If the 
//  Value pointer is NULL, only the length of the Value is returned. If the
//  Key is not found, NOT_FOUND status is returned 
//

OAL_KEYVALUE_STATUS OALKeyValueGet( POAL_KEYVALUE pKeyValue, 
                                    char *Key, 
                                    char *Value,
                                    UINT32 *pValueLen )
{
OAL_KEYVALUE_STATUS rc;
UINT32              i;
POAL_KEYVALUE_PAIR  pPair;
UINT32              KeyLen;
BOOL                KeyFound;

    OALMSG( OAL_FUNC && OAL_KEYVAL, 
    (TEXT("+OALKeyValueGet( 0x%x, '%S', 0x%x, 0x%x )\r\n"), pKeyValue, Key, Value, pValueLen ));

    // Validate arguments

    if( (pKeyValue == NULL) || (Key == NULL) || (pValueLen == NULL) )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueGet: NULL argument.\r\n" )));
        return( OAL_KEYVALUE_ARG );
    }

    // Validate initialization

    if( pKeyValue->Signature != OAL_KEYVALUE_SIGNATURE )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueGet: not initialized.\r\n" )));
        return( OAL_KEYVALUE_INIT );
    }

    KeyLen = strlen( Key );

    // Search the table for the Key.

    for( i=0, pPair = (POAL_KEYVALUE_PAIR )pKeyValue->pTable, KeyFound = FALSE;
         i < pKeyValue->Count;
         i++, pPair++ )
    {
        // Look for our key

        if( strncmp( Key, (pKeyValue->pTable + pPair->KeyOffset), KeyLen ) == 0 )
        {
            KeyFound = TRUE;
            break;
        }
    }

    if( KeyFound )
    {
        // Key found - Set output depending on output buffer and its size

        if( Value == NULL )
        {
            // Output buffer is NULL, set the length only

            rc = OAL_KEYVALUE_SUCCESS;
            *pValueLen = pPair->ValueLength;
        }
        else if( Value && (*pValueLen < pPair->ValueLength) )
        {
            // The provided buffer is too small - indicate SIZE error

            OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueGet: buffer too small.\r\n" )));
            rc = OAL_KEYVALUE_SIZE;
            *pValueLen = pPair->ValueLength;
        }
        else 
        {
            // The output buffer is NOT null and there is enough 
            // space, so copy the Value and update the length.

            rc = OAL_KEYVALUE_SUCCESS;
            memcpy( Value, pKeyValue->pTable + pPair->ValueOffset, pPair->ValueLength );
            *pValueLen = pPair->ValueLength;
        }
    }
    else
    {
        // Key not found - clear the output values 

        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueGet: Key not found.\r\n" )));
        rc = OAL_KEYVALUE_KEY;
        *Value = '\0';
        *pValueLen = 0;
    }

    // Indicate status

    DumpCB( pKeyValue );
    OALMSG( OAL_FUNC && OAL_KEYVAL, (TEXT("-OALKeyValueGet(rc=%d)\r\n"), rc ));
    return( rc );
}

//------------------------------------------------------------------------------
//  Function:  OALKeyValueAddFile
//
//  Desc...
//

OAL_KEYVALUE_STATUS OALKeyValueAddFile( POAL_KEYVALUE pKeyValue,
                                        ROMHDR *pTOC,
                                        char *FileName )
{
OAL_KEYVALUE_STATUS rc;
LPFILESentry pFiles;
UINT32 i;

    OALMSG( OAL_FUNC && OAL_KEYVAL, 
    (TEXT("+OALKeyValueAddFile( 0x%x, 0x%x, '%S' )\r\n"), pKeyValue, pTOC, FileName ));

    // Validate arguments

    if( (pKeyValue == NULL) || (pTOC == NULL) || (FileName == NULL) )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: NULL argument.\r\n" )));
        return( OAL_KEYVALUE_ARG );
    }

    // Validate initialization

    if( pKeyValue->Signature != OAL_KEYVALUE_SIGNATURE )
    {
        OALMSG( OAL_ERROR, (TEXT("ERROR: OALKeyValueAdd: not initialized.\r\n" )));
        return( OAL_KEYVALUE_INIT );
    }

    // Locate File using ROMHDR TOC
    // 
    // Search the FILESentry array for our file. The FILESentry 
    // array is after the ROMHDR and the TOCentry array.

    pFiles = (LPFILESentry )((UINT32)pTOC + sizeof(ROMHDR) + (pTOC->nummods*sizeof(TOCentry)));

    for( i=0; i < pTOC->numfiles; i++, pFiles++ )
    {
        OALMSG( OAL_INFO && OAL_KEYVAL && OAL_VERBOSE, 
        (TEXT("INFO: FileName: %S\r\n" ), pFiles->lpszFileName ));

        if( strcmp( FileName, pFiles->lpszFileName ) == 0 )
        {
            rc = ProcessFile( pKeyValue, pFiles->ulLoadOffset, pFiles->nRealFileSize );
            break;
        }
    }

    // Indicate status

    DumpCB( pKeyValue );

⌨️ 快捷键说明

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