📄 keyvalue.c
字号:
//
// 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 + -