392 lines
13 KiB
C++

//----------------------------------------------------------------------------
//
// Copyright (C) 2007 Intel Corporation
//
// File: SetupFileReader.h
//
// Contents: Demonstrates how to read and write a configuration setup file.
//
// Notes: This file contains a number of functions that demonstrate how
// to read and write a configuration setup file.
//
//----------------------------------------------------------------------------
#ifndef _SETUP_FILE_READER_H
#define _SETUP_FILE_READER_H
#include <string>
#include <vector>
#include <set>
#include <algorithm>
#include <memory>
using namespace std;
// Error Codes
// the request was completed successfully
#define MEMORY_ALLOC_ERROR -1
// the request was completed successfully
#define CONFIG_SUCCESS 0
// the setup file header has an illegal UUID
#define CONFIG_INVALID_UUID 1
// the setup file version is unsupported
#define CONFIG_VERSION_UNSUPPORTED 2
// a record entry that does not contain a current MEBx Password was encountered
#define CONFIG_MISSING_CURRENT_MEBX_PWD_ENTRY 3
// the given buffer length is invalid
#define CONFIG_INVALID_BUFFER_LENGTH 4
// the header chunk count cannot contain all of the setup file header data
#define CONFIG_INVALID_HEADER_CHUNK_COUNT 5
// the record chunk count cannot contain all of the setup file record data
#define CONFIG_INVALID_RECORD_CHUNK_COUNT 6
// the requested index is invalid
#define CONFIG_INVALID_INDEX 7
// the setup file header indicates that there are no valid records
// (RecordsConsumed >= RecordCount)
#define CONFIG_NO_VALID_RECORDS 8
// the given buffer is invalid
#define CONFIG_INVALID_BUFFER 9
// a record entry with an invalid Module ID was encountered
#define CONFIG_INVALID_MODULE_ID 10
// a record entry with an invalid record number was encountered
#define CONFIG_INVALID_RECORD_NUMBER 11
// the setup file header contains an invalid module ID list
#define CONFIG_INVALID_MODULE_LIST 12
// the setup file header contains an invalid byte count
#define CONFIG_INVALID_RECORD_HEADER_BYTE_COUNT 13
// the setup file record id is not RECORD_IDENTIFIER_DATA_RECORD
#define CONFIG_RECORD_TYPE_INVALID 14
// the list of data record entries is invalid
#define CONFIG_INVALID_ENTRY_LIST 15
// the setup file is corrupted
#define CONFIG_INVALID_FILE 16
// the setup record has already been used
#define CONFIG_INVALID_RECORD 17
// a record entry that does not contain a new MEBx password was encountered
#define CONFIG_MISSING_NEW_MEBX_PWD_ENTRY 18
// a record with an invalid manageability feature selection was found
#define CONFIG_INVALID_MANAGEABILITY_FEATURE_SELECTION 19
// invalid input was received
#define CONFIG_INVALID_INPUT 20
// a record with invalid certificate hash settings was encountered
#define CONFIG_INVALID_CERT_SETTINGS 21
// a file contains both scrambled and clear records was encountered
#define CONFIG_INVALID_SCRAMBLED_STATE 22
// setup file version definitions
#define SETUP_FILE_VERSION_1 1
#define SETUP_FILE_VERSION_2 2
#define SETUP_FILE_VERSION_3 3
#define SETUP_FILE_VERSION_4 4
//setup file default version
#define DEFAULT_MAJOR_VERSION 4
#define DEFAULT_MINOR_VERSION 0
// DataRecordEntry represents a single entry of a setup file data record
class DataRecordEntry
{
private:
// the target ME module for the entry
unsigned short _moduleId;
// identifies the variable
unsigned short _variableId;
unsigned short _variableLength;
unsigned char* _variableValue;
public:
// Constructors
DataRecordEntry();
DataRecordEntry(const unsigned short moduleId,
const unsigned short variableId,
const unsigned short variableLength,
const unsigned char* variableValue);
// Copy Constructor
DataRecordEntry(const DataRecordEntry& entry);
//Assignment operator
DataRecordEntry& operator=(const DataRecordEntry& entry);
// Destructor
~DataRecordEntry();
// Returns the module ID
unsigned short GetModuleId() const;
// Returns the variable ID
unsigned short GetVariableId() const;
// Returns the variable value length
unsigned short GetVariableLength() const;
// Copies up to bufferLen bytes of the variable value into the
// given buffer.
// Returns: the number of bytes copied
unsigned short GetVariableValue(const unsigned short bufferLen,
unsigned char* buffer) const;
// Sets the module ID
void SetModuleId(const unsigned short moduleId);
// Sets the variable ID
void SetVariableId(const unsigned short variableId);
// Sets the variable length and value
void SetVariableValue(const unsigned short bufferLen,
const unsigned char* buffer);
};
// DataRecord represents a setup file data record
class DataRecord
{
private:
// the entries of the data record
vector<DataRecordEntry>* _recordEntries;
// determines whether the record is valid
bool _isValid;
// determines whether the record is scrambled
bool _isScrambled;
public:
// Constructor
DataRecord(const bool isValid = true, const bool isScrambled = false);
// Copy Constructor
DataRecord(const DataRecord& record);
// Assignment operator
DataRecord& operator=(const DataRecord& record);
// Destructor
~DataRecord();
// Returns whether the record is valid
bool GetIsValid() const;
// Returns whether the record is scrambled
bool GetIsScrambled() const;
// Returns a copy of the list of entries
vector<DataRecordEntry> GetRecordEntries() const;
// Sets whether the record is valid
void SetValid(const bool isValid);
// Sets whether the record is valid
void SetScrambled(const bool isScrambled);
// Adds an entry with the given data to the list of record entries
void AddRecordEntry(const unsigned short moduleId,
const unsigned short variableId,
const unsigned short variableLength,
const unsigned char* variableValue);
// Sets the record to be identical to the given record
void CopyRecord(const DataRecord& record);
// Searches the entry list for an entry with the given moduleId and
// variableId. If found, and variableLength is not NULL, variableLength
// will hold the variable length of the entry on return. If found, and the
// given buffer is not NULL, up to bufferLength bytes of the variable value
// will be copied to buffer.
// Returns: true if found, false if not
bool FindEntry(const unsigned short moduleId,
const unsigned short variableId,
unsigned short* variableLength = NULL,
const unsigned short bufferLength = 0,
unsigned char* buffer = NULL) const;
};
struct SetupFileInfo
{
// major version of the setup file
unsigned char majorVersion;
// minor version of the setup file
unsigned char minorVersion;
// does the file contain a list of consumable record/s (true) or a single -
// inconsumable record (false). if majorVersion = 1, this is assumed to be
// true
bool consumeRecords;
// total number of records in the file. Assumed to be 1 if consumeRecords
// is false
unsigned int recordCount;
// number of records consumed. Assumed to be 0 if consumeRecords is false
unsigned int recordsConsumed;
// the number of chunks that will make up the setup file header
unsigned short headerChunkCount;
// the chunk count of each of the setup file records
unsigned short dataRecordChunkCount;
};
////////////////////////
// Function declarations
////////////////////////
/*
* This function parses the setup file header.
* Arguments:
* bufferLength - the length of the given buffer
* buffer - a buffer pointing to the beginning of the setup file header
* fileInfo - if not NULL this will hold the setup file info
* moduleListSize - if not NULL this will hold the number of module ID's listed
* in the header on successful return
* moduleList - if not NULL this will hold a list of the module ID's that are
* used in the file on successful return
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int ParseFileHeader(const unsigned int bufferLength,
const unsigned char* buffer,
SetupFileInfo* fileInfo,
unsigned int* moduleListSize,
set<unsigned short>* moduleList);
/*
* This function writes a setup file header with the given information to the
* given buffer.
* Arguments:
* buffer - a buffer pointing to the beginning of the setup file header
* fileInfo - the setup file info
* moduleList - a list of the module ID's that are used in the file
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int WriteFileHeader(unsigned char* buffer,
const SetupFileInfo fileInfo,
const set<unsigned short>& moduleList);
/*
* This function parses a setup file data record
* Arguments:
* numChunks - The number of chunks that will be written
* buffer - a buffer pointing to the beginning of the setup file record
* legalModules - if not NULL, the function will verify that all of the entry
* - module ID's appear on this list. This should be the list determined by
* the setup file header.
* majorVersion - the major version of the setup file (for the purpose of
* record validation).
* minorVersion - the minor version of the setup file (for the purpose of
* record validation).
* record - if not NULL the data record will be inserted to record
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int GetDataRecord(const unsigned short numChunks,
const unsigned char* buffer,
const unsigned char majorVersion,
const unsigned char minorVersion,
set<unsigned short>* legalModules,
DataRecord* record);
/*
* This function writes a setup file data record
* Arguments:
* numChunks - The number of chunks of the data record
* buffer - a buffer pointing to the beginning of the setup file record
* majorVersion - the major version of the setup file (for the purpose of
* record validation).
* minorVersion - the minor version of the setup file (for the purpose of
* record validation).
* recordNumber - the number of the record in the setup file
* record - the data record information
* modulesUsed - if not NULL, the function will add all of the entry - module
* ID's that appear in the record to this set
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int WriteDataRecord(const unsigned short numChunks,
unsigned char* buffer,
const unsigned char majorVersion,
const unsigned char minorVersion,
const unsigned int recordNumber,
const DataRecord& record,
set<unsigned short>* modulesUsed);
/*
* This function parses a setup file; the valid (unconsumed) records are
* returned in the order that they appear in the file.
* Arguments:
* bufferLength - the length of the given buffer
* buffer - a buffer pointing to the beginning of the setup file
* fileInfo - if not NULL, this will hold the setup file info
* records - if not NULL, each valid data record that appears on the file
* will be parsed and added to the given list. If an error occurs, the list
* will include all of the records that were parsed before the error occurred.
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int BufferToRecords(const unsigned int bufferLength,
const unsigned char* buffer,
SetupFileInfo* fileInfo,
vector<DataRecord>* records);
/*
* This function parses a setup file and returns the data record at the given
* index
* Arguments:
* bufferLength - the length of the given buffer
* buffer - a buffer pointing to the beginning of the setup file
* index - a non-zero integer indicating the index of the requested record
* record - if not NULL, this will hold the requested data record, on
* successful return
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int GetRecordByIndex(const unsigned int bufferLength,
const unsigned char* buffer,
const unsigned int index,
DataRecord* record);
/*
* This function parses a setup file and returns the next valid data record.
* This record is determined by the setup file header. It is the record at:
* index = (NumberOfRecordsOnFile - NumberOfRecordsConsumed)
* Arguments:
* bufferLength - the length of the given buffer
* buffer - a buffer pointing to the beginning of the setup file
* record - if not NULL, this will hold the requested data record, on
* successful return
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int GetNextValidRecord(const unsigned int bufferLength,
const unsigned char* buffer,
DataRecord* record);
/*
* This function writes a setup file containing the given data records to the
* given buffer.
* Arguments:
* records - a list of records. Note: all records are assumed to be
* unconsumed (i.e. the valid setting is 'true')
* setupInfo - the setup file info
* bufferLength - the length of the given buffer
* buffer - a buffer pointing to the beginning of the setup file header
* Return Value:
* CONFIG_SUCCES - on success
* a non-zero error code - on failure
*/
int RecordsToBuffer(const vector<DataRecord>& records,
const SetupFileInfo& setupInfo,
const unsigned int bufferLength,
unsigned char* buffer);
/*
* Calculate the number of chunks required for a given record.
* Arguments:
* record - a data records.
* Return Value:
* a the number of chunks required, or a negative value if an error occurred
*/
int GetChunkCount(const DataRecord& record);
#endif