summaryrefslogtreecommitdiff
path: root/Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c')
-rw-r--r--Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c2728
1 files changed, 0 insertions, 2728 deletions
diff --git a/Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c b/Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c
deleted file mode 100644
index 6f182615a6..0000000000
--- a/Tools/CCode/Source/GenCapsuleHdr/GenCapsuleHdr.c
+++ /dev/null
@@ -1,2728 +0,0 @@
-/*++
-
-Copyright (c) 2002-2006 Intel Corporation. All rights reserved
-This program and the accompanying materials are licensed and made available
-under the terms and conditions of the BSD License which accompanies this
-distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-
-Module Name:
-
- GenCapsuleHdr.c
-
-Abstract:
-
- Generate a capsule header for a file, and optionally prepend the
- header to a file or list of files.
-
---*/
-
-#define _UNICODE
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include <Common/UefiBaseTypes.h>
-#include <Common/MultiPhase.h>
-#include <Common/Capsule.h>
-#include <Common/FirmwareVolumeImageFormat.h>
-#include <Common/FirmwareVolumeHeader.h>
-#include <Common/FirmwareFileSystem.h> // for FV header GUID
-#include <Guid/Capsule.h>
-#include <Guid/FirmwareFileSystem.h> // for FV header GUID
-
-#include "CommonLib.h"
-#include "EfiUtilityMsgs.h"
-
-#define MAX_PATH 256
-
-#define UTILITY_NAME "GenCapsuleHdr"
-#define UTILITY_MAJOR_VERSION 1
-#define UTILITY_MINOR_VERSION 0
-
-#define UNICODE_BACKSLASH L'\\'
-#define UNICODE_FILE_START 0xFEFF
-#define UNICODE_CR 0x000D
-#define UNICODE_LF 0x000A
-#define UNICODE_NULL 0x0000
-#define UNICODE_SPACE L' '
-#define UNICODE_SLASH L'/'
-#define UNICODE_DOUBLE_QUOTE L'"'
-#define UNICODE_A L'A'
-#define UNICODE_F L'F'
-#define UNICODE_Z L'Z'
-#define UNICODE_a L'a'
-#define UNICODE_f L'f'
-#define UNICODE_z L'z'
-#define UNICODE_0 L'0'
-#define UNICODE_9 L'9'
-#define UNICODE_TAB L'\t'
-
-#define OEM_HEADER_STRING L"OemHeader"
-#define AUTHOR_INFO_STRING L"AuthorInfo"
-#define REVISION_INFO_STRING L"RevisionInfo"
-#define SHORT_DESCRIPTION_STRING L"ShortDescription"
-#define LONG_DESCRIPTION_STRING L"LongDescription"
-#define EQUAL_STRING L"="
-#define OPEN_BRACE_STRING L"{"
-#define CLOSE_BRACE_STRING L"}"
-#define GUID_STRING L"GUID"
-#define DATA_STRING L"DATA"
-
-#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
-#define UEFI_CAPSULE_HEADER_NO_FALAGS 0
-#define UEFI_CAPSULE_HEADER_RESET_FALAGS CAPSULE_FLAGS_PERSIST_ACROSS_RESET
-#define UEFI_CAPSULE_HEADER_ALL_FALAGS (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)
-#endif
-
-typedef wchar_t WCHAR;
-
-typedef struct _FILE_LIST {
- struct _FILE_LIST *Next;
- INT8 FileName[MAX_PATH];
-} FILE_LIST;
-
-typedef struct _SIZE_LIST {
- struct _SIZE_LIST *Next;
- UINT32 Size;
-} SIZE_LIST;
-
-typedef struct {
- INT8 FileName[MAX_PATH];
- WCHAR *FileBuffer;
- WCHAR *FileBufferPtr;
- UINT32 FileSize;
- FILE *FilePtr;
- BOOLEAN EndOfFile;
- UINT32 LineNum;
-} SOURCE_FILE;
-
-//
-// Here's all our globals.
-//
-static struct {
- BOOLEAN Dump;
- BOOLEAN Verbose;
- BOOLEAN JoinMode;
- INT8 ScriptFileName[MAX_PATH];
- INT8 OutputFileName[MAX_PATH];
- FILE_LIST *FileList;
- FILE *OutFptr;
- SIZE_LIST *SizeList;
- SIZE_LIST *LastSize;
- SIZE_LIST *CurrentSize;
-} mOptions;
-
-static EFI_GUID mEfiCapsuleHeaderGuid = EFI_CAPSULE_GUID;
-
-void
-CreateGuid (
- EFI_GUID *Guid
- );
-
-static
-STATUS
-ProcessArgs (
- int Argc,
- char *Argv[]
- );
-
-static
-void
-SkipWhiteSpace (
- SOURCE_FILE *SourceFile
- );
-
-static
-STATUS
-GetHexValue (
- SOURCE_FILE *SourceFile,
- UINT32 *Value,
- UINT32 NumDigits
- );
-
-static
-BOOLEAN
-GetSplitFileName (
- INT8 *BaseFileName,
- INT8 *NewFileName,
- UINT32 SequenceNumber
- );
-
-static
-STATUS
-SplitCapsule (
- INT8 *CapsuleFileName
- );
-
-static
-void
-Version (
- VOID
- );
-
-static
-void
-Usage (
- VOID
- );
-
-static
-void
-DumpCapsule (
- VOID
- );
-
-static
-STATUS
-JoinCapsule (
- VOID
- );
-
-static
-STATUS
-DumpCapsuleHeaderStrings (
- UINT8 *SectionName,
- WCHAR *Buffer
- );
-
-static
-STATUS
-CheckFirmwareVolumeHeader (
- INT8 *FileName,
- INT8 *Buffer,
- UINT32 BufferSize
- );
-
-static
-BOOLEAN
-IsToken (
- SOURCE_FILE *File,
- WCHAR *Token
- );
-
-static
-BOOLEAN
-GetNumber (
- INT8 *Str,
- UINT32 *Value
- );
-
-static
-STATUS
-ProcessScriptFile (
- INT8 *ScriptFileName,
- FILE *OutFptr,
- EFI_CAPSULE_HEADER *CapsuleHeader
- );
-
-static
-STATUS
-ParseCapsuleInfo (
- SOURCE_FILE *SourceFile,
- FILE *OutFptr,
- WCHAR *SectionName
- );
-
-static
-STATUS
-CreateCapsule (
- VOID
- );
-
-static
-STATUS
-ParseOemInfo (
- SOURCE_FILE *SourceFile,
- FILE *OutFptr
- );
-
-static
-BOOLEAN
-IsWhiteSpace (
- WCHAR Char
- );
-
-static
-BOOLEAN
-EndOfFile (
- SOURCE_FILE *File
- );
-
-int
-main (
- int Argc,
- char *Argv[]
- )
-/*++
-
-Routine Description:
- Call the routine to process the command-line arguments, then
- dispatch to the appropriate function.
-
-Arguments:
- Standard C main() argc and argv.
-
-Returns:
- 0 if successful
- nonzero otherwise
-
---*/
-// GC_TODO: Argc - add argument and description to function comment
-// GC_TODO: ] - add argument and description to function comment
-{
- STATUS Status;
- FILE_LIST *NextFile;
- //
- // Specify our program name to the error printing routines.
- //
- SetUtilityName (UTILITY_NAME);
- //
- // Process the command-line arguments
- //
- Status = ProcessArgs (Argc, Argv);
- if (Status == STATUS_SUCCESS) {
- if (mOptions.Dump) {
- DumpCapsule ();
- } else if (mOptions.JoinMode) {
- JoinCapsule ();
- } else {
- CreateCapsule ();
- }
- }
- //
- // Cleanup
- //
- while (mOptions.FileList != NULL) {
- NextFile = mOptions.FileList->Next;
- free (mOptions.FileList);
- mOptions.FileList = NextFile;
- }
-
- while (mOptions.SizeList != NULL) {
- mOptions.CurrentSize = mOptions.SizeList->Next;
- free (mOptions.SizeList);
- mOptions.SizeList = mOptions.CurrentSize;
- }
-
- return GetUtilityStatus ();
-}
-
-static
-STATUS
-CreateCapsule (
- VOID
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- None
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- FILE *InFptr;
- FILE_LIST *FileList;
- INT8 *Buffer;
- UINT32 Size;
- EFI_CAPSULE_HEADER CapsuleHeader;
- UINT8 Zero;
- UINT8 FirstFile;
- UINT32 CapsuleHeaderSize;
- long InsertedBlockMapEntryOffset;
- EFI_FV_BLOCK_MAP_ENTRY InsertedBlockMapEntry;
- UINT64 FirmwareVolumeSize;
- long FileSize;
- EFI_FIRMWARE_VOLUME_HEADER FVHeader;
-
- Buffer = NULL;
- InFptr = NULL;
- FirmwareVolumeSize = 0;
- CapsuleHeaderSize = 0;
- InsertedBlockMapEntryOffset = 0;
- memset (&InsertedBlockMapEntry, 0, sizeof (EFI_FV_BLOCK_MAP_ENTRY));
- memset (&FVHeader, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
-
- if ((mOptions.OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing");
- return STATUS_ERROR;
- }
-
- memset ((char *) &CapsuleHeader, 0, sizeof (CapsuleHeader));
- memcpy ((void *) &CapsuleHeader.CapsuleGuid, (void *) &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID));
- CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER);
- CapsuleHeader.CapsuleImageSize = sizeof (EFI_CAPSULE_HEADER);
- if (mOptions.ScriptFileName[0] != 0) {
- if (ProcessScriptFile (mOptions.ScriptFileName, mOptions.OutFptr, &CapsuleHeader) != STATUS_SUCCESS) {
- goto Done;
- }
- } else {
- //
- // Insert a default capsule header
-#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
- CapsuleHeader.HeaderSize = sizeof (EFI_CAPSULE_HEADER);
- CapsuleHeader.Flags = UEFI_CAPSULE_HEADER_ALL_FALAGS;
-#endif
- CapsuleHeader.OffsetToCapsuleBody = sizeof (EFI_CAPSULE_HEADER);
-
- if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
- }
-
- CapsuleHeaderSize = CapsuleHeader.OffsetToCapsuleBody;
- //
- // Now copy the contents of any other files specified on the command
- // line to the output file. Files must be FFS files, which are aligned
- // on 8-byte boundaries. Don't align the first file, since it's the start
- // of the image once the capsule header has been removed.
- //
- FileList = mOptions.FileList;
- FirstFile = 1;
- Zero = 0;
- while (FileList != NULL) {
- if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {
- Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");
- goto Done;
- }
- //
- // Allocate a buffer into which we can read the file.
- //
- fseek (InFptr, 0, SEEK_END);
- Size = ftell (InFptr);
- rewind (InFptr);
- Buffer = (char *) malloc (Size);
- if (Buffer == NULL) {
- Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into");
- goto Done;
- }
-
- if (fread ((void *) Buffer, Size, 1, InFptr) != 1) {
- Error (NULL, 0, 0, FileList->FileName, "failed to read file contents");
- goto Done;
- }
-
- if (Size > 0) {
- //
- // Align the write of the first bytes from the file if not the first file
- //
- if (FirstFile) {
- //
- // First file must be a firmware volume. Double-check, and then insert
- // an additional block map entry so we can add more files from the command line
- //
- if (CheckFirmwareVolumeHeader (FileList->FileName, Buffer, Size) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Save a copy of the firmware volume header for later
- //
- memcpy (&FVHeader, Buffer, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
- FirmwareVolumeSize = FVHeader.FvLength;
- if (FileList->Next != NULL) {
- //
- // Copy the firmware volume header
- //
- InsertedBlockMapEntryOffset = CapsuleHeaderSize + FVHeader.HeaderLength;
- if (fwrite (Buffer, FVHeader.HeaderLength, 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
-
- if (fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
-
- if (fwrite (
- Buffer + FVHeader.HeaderLength,
- Size - FVHeader.HeaderLength,
- 1,
- mOptions.OutFptr
- ) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
- } else {
- //
- // Copy the file contents as-is
- //
- if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
- }
- } else {
- while ((ftell (mOptions.OutFptr) - CapsuleHeaderSize) & 0x07) {
- if (fwrite ((void *) &Zero, 1, 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
- }
-
- if (fwrite ((void *) Buffer, Size, 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto Done;
- }
- }
-
- FirstFile = 0;
- }
-
- free (Buffer);
- Buffer = NULL;
- fclose (InFptr);
- InFptr = NULL;
- FileList = FileList->Next;
- }
-
-Done:
- if (Buffer != NULL) {
- free (Buffer);
- }
-
- if (InFptr != NULL) {
- fclose (InFptr);
- }
- //
- // If we inserted an additional block map entry, then fix it up. Fix up the
- // FV header as well to reflect our new size.
- //
- if (InsertedBlockMapEntryOffset != 0) {
- FileSize = ftell (mOptions.OutFptr);
- InsertedBlockMapEntry.NumBlocks = 1;
- InsertedBlockMapEntry.BlockLength = (UINT32) ((UINT64) FileSize - (UINT64) CapsuleHeaderSize - FirmwareVolumeSize - sizeof (EFI_FV_BLOCK_MAP_ENTRY));
- fseek (mOptions.OutFptr, InsertedBlockMapEntryOffset, SEEK_SET);
- fwrite (&InsertedBlockMapEntry, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr);
- //
- // Fix up the firmware volume header and write it out
- //
- fseek (mOptions.OutFptr, CapsuleHeaderSize, SEEK_SET);
- FVHeader.FvLength = FileSize - CapsuleHeaderSize;
- FVHeader.HeaderLength += sizeof (EFI_FV_BLOCK_MAP_ENTRY);
- fwrite (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, mOptions.OutFptr);
- //
- // Reposition to the end of the file
- //
- }
- //
- // Close files and free the global string lists we allocated memory for
- //
- if (mOptions.OutFptr != NULL) {
- //
- // We should now know the full capsule image size. Update the header and write it again.
- //
- fseek (mOptions.OutFptr, 0, SEEK_END);
- Size = ftell (mOptions.OutFptr);
- CapsuleHeader.CapsuleImageSize = Size;
- fseek (mOptions.OutFptr, 0, SEEK_SET);
- if (fwrite ((void *) &CapsuleHeader, sizeof (CapsuleHeader), 1, mOptions.OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- }
-
- fseek (mOptions.OutFptr, 0, SEEK_END);
- fclose (mOptions.OutFptr);
- mOptions.OutFptr = NULL;
- }
- //
- // If they are doing split capsule output, then split it up now.
- //
- if ((mOptions.Dump == 0) && (GetUtilityStatus () == STATUS_SUCCESS) && (mOptions.SizeList != NULL)) {
- SplitCapsule (mOptions.OutputFileName);
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-STATUS
-ProcessScriptFile (
- INT8 *ScriptFileName,
- FILE *OutFptr,
- EFI_CAPSULE_HEADER *CapsuleHeader
- )
-/*++
-
-Routine Description:
- Parse a capsule header script file.
-
-Arguments:
- ScriptFileName - name of script file to parse
- OutFptr - output to dump binary data
- CapsuleHeader - capsule header to update with size info
- of parsed fields in the script file
-
-Returns:
- STATUS_SUCCESS - if all went well
-
---*/
-{
-#if 0
- STATUS Status;
- SOURCE_FILE SourceFile;
- WCHAR *WScriptFileName;
- BOOLEAN InComment;
-
- if (fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr) != 1) {
- Error (NULL, 0, 0, "failed to write capsule header to output file", NULL);
- return STATUS_ERROR;
- }
-
- memset (&SourceFile, 0, sizeof (SOURCE_FILE));
- strcpy (SourceFile.FileName, ScriptFileName);
-
- Status = STATUS_ERROR;
- //
- // Open the input unicode script file and read it into a buffer
- //
- WScriptFileName = (WCHAR *) malloc ((strlen (ScriptFileName) + 1) * sizeof (WCHAR));
- if (WScriptFileName == NULL) {
- Error (__FILE__, __LINE__, 0, "failed to allocate memory", NULL);
- return STATUS_ERROR;
- }
-
- swprintf (WScriptFileName, L"%S", ScriptFileName);
- if ((SourceFile.FilePtr = _wfopen (WScriptFileName, L"r")) == NULL) {
- free (WScriptFileName);
- Error (NULL, 0, 0, ScriptFileName, "failed to open script file for reading");
- goto Done;
- }
-
- free (WScriptFileName);
- fseek (SourceFile.FilePtr, 0, SEEK_END);
- SourceFile.FileSize = ftell (SourceFile.FilePtr);
- rewind (SourceFile.FilePtr);
- SourceFile.FileBuffer = (WCHAR *) malloc (SourceFile.FileSize + sizeof (WCHAR));
- if (SourceFile.FileBuffer == NULL) {
- Error (__FILE__, __LINE__, 0, ScriptFileName, "failed to allocate memory to read in file contents");
- goto Done;
- }
-
- if (fread (SourceFile.FileBuffer, SourceFile.FileSize, 1, SourceFile.FilePtr) != 1) {
- Error (NULL, 0, 0, ScriptFileName, "failed to read file contents");
- goto Done;
- }
-
- SourceFile.FileBufferPtr = SourceFile.FileBuffer;
- SourceFile.LineNum = 1;
- if (SourceFile.FileBuffer[0] != UNICODE_FILE_START) {
- Error (ScriptFileName, 1, 0, "file does not appear to be a unicode file", NULL);
- goto Done;
- }
-
- SourceFile.FileBufferPtr++;
- SourceFile.FileBuffer[SourceFile.FileSize / sizeof (WCHAR)] = 0;
- //
- // Walk the source file buffer and replace all carriage returns with 0 so
- // we can print from the file contents on parse errors.
- //
- InComment = 0;
- while (!EndOfFile (&SourceFile)) {
- if (SourceFile.FileBufferPtr[0] == UNICODE_CR) {
- SourceFile.FileBufferPtr[0] = 0;
- InComment = 0;
- } else if (SourceFile.FileBufferPtr[0] == UNICODE_LF) {
- InComment = 0;
- } else if (InComment) {
- SourceFile.FileBufferPtr[0] = UNICODE_SPACE;
- } else if ((SourceFile.FileBufferPtr[0] == UNICODE_SLASH) && (SourceFile.FileBufferPtr[1] == UNICODE_SLASH)) {
- InComment = 1;
- SourceFile.FileBufferPtr[0] = UNICODE_SPACE;
- }
-
- SourceFile.FileBufferPtr++;
- }
- //
- // Reposition to the start of the file, but skip over the unicode file start
- //
- SourceFile.FileBufferPtr = SourceFile.FileBuffer;
- SourceFile.FileBufferPtr++;
- SourceFile.EndOfFile = 0;
- CapsuleHeader->OffsetToOemDefinedHeader = ftell (OutFptr);
- //
- // Parse the OEM bytes
- //
- if (ParseOemInfo (&SourceFile, OutFptr) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Parse the author information
- //
- CapsuleHeader->OffsetToAuthorInformation = ftell (OutFptr);
- if (ParseCapsuleInfo (&SourceFile, OutFptr, AUTHOR_INFO_STRING) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Parse the revision information
- //
- CapsuleHeader->OffsetToRevisionInformation = ftell (OutFptr);
- if (ParseCapsuleInfo (&SourceFile, OutFptr, REVISION_INFO_STRING) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Parse the short description
- //
- CapsuleHeader->OffsetToShortDescription = ftell (OutFptr);
- if (ParseCapsuleInfo (&SourceFile, OutFptr, SHORT_DESCRIPTION_STRING) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Parse the long description
- //
- CapsuleHeader->OffsetToLongDescription = ftell (OutFptr);
- if (ParseCapsuleInfo (&SourceFile, OutFptr, LONG_DESCRIPTION_STRING) != STATUS_SUCCESS) {
- goto Done;
- }
- //
- // Better be end of contents
- //
- SkipWhiteSpace (&SourceFile);
- if (!EndOfFile (&SourceFile)) {
- Error (ScriptFileName, SourceFile.LineNum, 0, NULL, "expected end-of-file, not %.20S", SourceFile.FileBufferPtr);
- goto Done;
- }
-
- CapsuleHeader->OffsetToCapsuleBody = ftell (OutFptr);
- rewind (OutFptr);
- fwrite (CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, OutFptr);
- fseek (OutFptr, 0, SEEK_END);
- Status = STATUS_SUCCESS;
-Done:
- if (SourceFile.FilePtr != NULL) {
- fclose (SourceFile.FilePtr);
- }
-
- if (SourceFile.FileBuffer != NULL) {
- free (SourceFile.FileBuffer);
- }
-
- return Status;
-
-#endif
- return STATUS_SUCCESS;
-}
-//
-// Parse the OEM data of format:
-// OemInfo {
-// GUID = 12345676-1234-1234-123456789ABC
-// DATA = 0x01, 0x02, 0x03...
-// }
-//
-static
-STATUS
-ParseOemInfo (
- SOURCE_FILE *SourceFile,
- FILE *OutFptr
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- SourceFile - GC_TODO: add argument description
- OutFptr - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- long OemHeaderOffset;
- UINT32 Data;
- EFI_CAPSULE_OEM_HEADER OemHeader;
- STATUS Status;
- UINT32 DigitCount;
- WCHAR *SaveFilePos;
- UINT8 ByteData;
-
- Status = STATUS_ERROR;
- memset (&OemHeader, 0, sizeof (EFI_CAPSULE_OEM_HEADER));
- OemHeaderOffset = ftell (OutFptr);
- OemHeader.HeaderSize = sizeof (EFI_CAPSULE_OEM_HEADER);
- if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) {
- Error (NULL, 0, 0, "failed to write OEM header to output file", NULL);
- goto Done;
- }
-
- if (!IsToken (SourceFile, OEM_HEADER_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- OEM_HEADER_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, EQUAL_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- EQUAL_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, OPEN_BRACE_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- OPEN_BRACE_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- //
- // Look for: GUID = xxxxxxx-xxxx-xxxx-xxxxxxxxxxxxx
- //
- if (!IsToken (SourceFile, GUID_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- GUID_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, EQUAL_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- EQUAL_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- //
- // Parse the xxxxxxxx-xxxx-xxxx-xxxx portion of the GUID
- //
- SkipWhiteSpace (SourceFile);
- if (GetHexValue (SourceFile, &Data, 8) != STATUS_SUCCESS) {
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);
- goto Done;
- }
-
- OemHeader.OemGuid.Data1 = Data;
- if (!IsToken (SourceFile, L"-")) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected dash in GUID, not %S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- //
- // Get 3 word values
- //
- for (DigitCount = 0; DigitCount < 3; DigitCount++) {
- if (GetHexValue (SourceFile, &Data, 4) != STATUS_SUCCESS) {
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);
- goto Done;
- }
-
- switch (DigitCount) {
- case 0:
- OemHeader.OemGuid.Data2 = (UINT16) Data;
- break;
-
- case 1:
- OemHeader.OemGuid.Data3 = (UINT16) Data;
- break;
-
- case 2:
- OemHeader.OemGuid.Data4[1] = (UINT8) Data;
- OemHeader.OemGuid.Data4[0] = (UINT8) (Data >> 8);
- break;
- }
-
- if (!IsToken (SourceFile, L"-")) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected dash in GUID, not %S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- }
- //
- // Pick up the last 6 bytes of the GUID
- //
- SaveFilePos = SourceFile->FileBufferPtr;
- for (DigitCount = 0; DigitCount < 6; DigitCount++) {
- if (GetHexValue (SourceFile, &Data, 2) != STATUS_SUCCESS) {
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "invalid GUID", NULL);
- goto Done;
- }
-
- OemHeader.OemGuid.Data4[DigitCount + 2] = (UINT8) Data;
- }
- //
- // Now read raw OEM data bytes. May or may not be present.
- // DATA = 0x01, 0x02, 0x02...
- //
- if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {
- Status = STATUS_SUCCESS;
- goto Done;
- }
-
- if (!IsToken (SourceFile, DATA_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- DATA_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, EQUAL_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- EQUAL_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- while (!EndOfFile (SourceFile)) {
- if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {
- Status = STATUS_SUCCESS;
- goto Done;
- }
-
- if (IsToken (SourceFile, L"0x")) {
- if (swscanf (SourceFile->FileBufferPtr, L"%x", &Data) != 1) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected hex byte value, not %.20S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (Data &~0xFF) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected byte hex byte value at %.20S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- //
- // Skip over the hex digits, then write the data
- //
- while (iswxdigit (SourceFile->FileBufferPtr[0])) {
- SourceFile->FileBufferPtr++;
- }
-
- ByteData = (UINT8) Data;
- if (fwrite (&ByteData, 1, 1, OutFptr) != 1) {
- Error (NULL, 0, 0, "failed to write OEM data to output file", NULL);
- goto Done;
- }
-
- OemHeader.HeaderSize++;
- //
- // Optional comma
- //
- IsToken (SourceFile, L",");
- } else {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected hex OEM data, not %.20S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- }
-
- if (EndOfFile (SourceFile)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S close to OEM header data",
- CLOSE_BRACE_STRING
- );
- goto Done;
- }
-
- Status = STATUS_SUCCESS;
-Done:
- //
- // re-write the oem header if no errors
- //
- if (Status == STATUS_SUCCESS) {
- fseek (OutFptr, OemHeaderOffset, SEEK_SET);
- if (fwrite (&OemHeader, sizeof (EFI_CAPSULE_OEM_HEADER), 1, OutFptr) != 1) {
- Error (NULL, 0, 0, "failed to write OEM header to output file", NULL);
- goto Done;
- }
-
- fseek (OutFptr, 0, SEEK_END);
- }
-
- return Status;
-}
-
-static
-STATUS
-ParseCapsuleInfo (
- SOURCE_FILE *SourceFile,
- FILE *OutFptr,
- WCHAR *SectionName
- )
-// GC_TODO: function comment should start with '/*++'
-//
-// GC_TODO: function comment is missing 'Routine Description:'
-// GC_TODO: function comment is missing 'Arguments:'
-// GC_TODO: function comment is missing 'Returns:'
-// GC_TODO: SourceFile - add argument and description to function comment
-// GC_TODO: OutFptr - add argument and description to function comment
-// GC_TODO: SectionName - add argument and description to function comment
-// Parse: eng "string " "parts"
-// spa "string " "parts"
-// Write out: "eng string parts\0spa string parts\0\0
-//
-{
- STATUS Status;
- int StringCount;
- WCHAR Zero;
- WCHAR Spacebar;
-
- Status = STATUS_ERROR;
- Zero = 0;
- Spacebar = UNICODE_SPACE;
-
- if (!IsToken (SourceFile, SectionName)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- SectionName,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, EQUAL_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- EQUAL_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- if (!IsToken (SourceFile, OPEN_BRACE_STRING)) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %S, not %.20S",
- OPEN_BRACE_STRING,
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
-
- while (!EndOfFile (SourceFile)) {
- if (IsToken (SourceFile, CLOSE_BRACE_STRING)) {
- break;
- }
- //
- // Look for language identifier (3 lowercase chars)
- //
- if ((SourceFile->FileBufferPtr[0] >= UNICODE_a) &&
- (SourceFile->FileBufferPtr[0] <= UNICODE_z) &&
- (SourceFile->FileBufferPtr[1] >= UNICODE_a) &&
- (SourceFile->FileBufferPtr[1] <= UNICODE_z) &&
- (SourceFile->FileBufferPtr[2] >= UNICODE_a) &&
- (SourceFile->FileBufferPtr[2] <= UNICODE_z) &&
- IsWhiteSpace (SourceFile->FileBufferPtr[3])
- ) {
- //
- // Write the 3 chars followed by a spacebar, and then look for opening quote
- //
- fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);
- SourceFile->FileBufferPtr++;
- fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);
- SourceFile->FileBufferPtr++;
- fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);
- SourceFile->FileBufferPtr++;
- fwrite (&Spacebar, sizeof (WCHAR), 1, OutFptr);
- StringCount = 0;
- while (IsToken (SourceFile, L"\"")) {
- StringCount++;
- while (!EndOfFile (SourceFile)) {
- if (SourceFile->FileBufferPtr[0] == UNICODE_DOUBLE_QUOTE) {
- SourceFile->FileBufferPtr++;
- break;
- } else if ((SourceFile->FileBufferPtr[0] == UNICODE_LF) || (SourceFile->FileBufferPtr[0] == 0)) {
- Error (SourceFile->FileName, SourceFile->LineNum, 0, "missing closing quote on string", NULL);
- goto Done;
- } else {
- fwrite (SourceFile->FileBufferPtr, sizeof (WCHAR), 1, OutFptr);
- SourceFile->FileBufferPtr++;
- }
- }
- }
-
- if (StringCount == 0) {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected quoted string, not %.20S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- //
- // This string's null terminator
- //
- fwrite (&Zero, sizeof (WCHAR), 1, OutFptr);
- } else {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected valid language identifer, not %.20S",
- SourceFile->FileBufferPtr
- );
- goto Done;
- }
- }
- //
- // Double null terminator
- //
- fwrite (&Zero, sizeof (WCHAR), 1, OutFptr);
- Status = STATUS_SUCCESS;
-Done:
- return Status;
-}
-
-static
-STATUS
-SplitCapsule (
- INT8 *CapsuleFileName
- )
-/*++
-
-Routine Description:
- We've created an entire capsule image. Now split it up into the
- size pieces they requested.
-
-Arguments:
- CapsuleFileName - name of an existing capsule file on disk
-
-Returns:
- STATUS_SUCCESS - if no problems
-
-Notes:
- This implementation reads in the entire capsule image from
- disk, then overwrites the original file with the first
- in the series.
-
---*/
-{
-#if 0
- EFI_CAPSULE_HEADER *CapHdr;
-
- EFI_CAPSULE_HEADER Hdr;
- FILE *CapFptr;
- FILE *OutFptr;
- UINT32 SizeLeft;
- UINT32 CurrentSize;
- UINT32 DataSize;
- UINT32 SequenceNumber;
- INT8 *Buffer;
- INT8 FileName[MAX_PATH];
- STATUS Status;
- UINT32 FileSize;
- //
- // Figure out the total size, then rewind the input file and
- // read the entire thing in
- //
- if ((CapFptr = fopen (CapsuleFileName, "rb")) == NULL) {
- Error (NULL, 0, 0, CapsuleFileName, "failed to open capsule image for reading");
- return STATUS_ERROR;
- }
-
- OutFptr = NULL;
- Status = STATUS_SUCCESS;
- fseek (CapFptr, 0, SEEK_END);
- SizeLeft = ftell (CapFptr);
- fseek (CapFptr, 0, SEEK_SET);
- CapHdr = (EFI_CAPSULE_HEADER *) malloc (SizeLeft);
- if (CapHdr == NULL) {
- Error (NULL, 0, 0, "memory allocation failure", NULL);
- goto FailDone;
- }
-
- if (fread (CapHdr, SizeLeft, 1, CapFptr) != 1) {
- Error (NULL, 0, 0, "failed to read capsule contents", "split failed");
- goto FailDone;
- }
-
- fclose (CapFptr);
- CapFptr = NULL;
- //
- // Get a GUID to fill in the InstanceId GUID in the header
- //
- CreateGuid (&CapHdr->InstanceId);
- SequenceNumber = 0;
- //
- // If the split size is larger than the original capsule image, then
- // we're done.
- //
- if (mOptions.SizeList->Size >= SizeLeft) {
- mOptions.SizeList->Size = SizeLeft;
- goto Done;
- }
- //
- // First size has to be big enough for the original header
- //
- if (mOptions.SizeList->Size < CapHdr->OffsetToCapsuleBody) {
- Error (NULL, 0, 0, "first split size is insufficient for the original capsule header", NULL);
- goto FailDone;
- }
- //
- // Initialize the header we'll use on all but the first part
- //
- memset (&Hdr, 0, sizeof (Hdr));
- Hdr.CapsuleGuid = CapHdr->CapsuleGuid;
- Hdr.HeaderSize = sizeof (Hdr);
- Hdr.Flags = CapHdr->Flags;
- Hdr.InstanceId = CapHdr->InstanceId;
- Hdr.CapsuleImageSize = CapHdr->CapsuleImageSize;
- Hdr.OffsetToCapsuleBody = Hdr.HeaderSize;
- Hdr.SequenceNumber = 1;
- //
- // printf ("Created %s - 0x%X bytes\n", CapsuleFileName, mOptions.SizeList->Size);
- //
- Buffer = (UINT8 *) CapHdr;
- //
- // Walk the list of sizes and write out a capsule header, and
- // then the raw capsule data.
- //
- // SizeLeft -= mOptions.SizeList->Size;
- //
- mOptions.CurrentSize = mOptions.SizeList;
- while (SizeLeft) {
- CurrentSize = mOptions.CurrentSize->Size;
- GetSplitFileName (mOptions.OutputFileName, FileName, SequenceNumber);
- if ((OutFptr = fopen (FileName, "wb")) == NULL) {
- Error (NULL, 0, 0, FileName, "failed to open split file for writing");
- goto FailDone;
- }
-
- if (Buffer == (UINT8 *) CapHdr) {
- //
- // First part -- write out original header and data
- //
- if (fwrite (Buffer, CurrentSize, 1, OutFptr) != 1) {
- Error (NULL, 0, 0, FileName, "failed to write to split image file");
- goto FailDone;
- }
-
- SizeLeft -= CurrentSize;
- Buffer += CurrentSize;
- DataSize = CurrentSize;
- FileSize = CurrentSize;
- } else {
- //
- // Not the first part. Write the default header, and then the raw bytes from the
- // original image.
- //
- if (CurrentSize <= sizeof (Hdr)) {
- Error (NULL, 0, 0, "split size too small for capsule header + data", "0x%X", CurrentSize);
- goto FailDone;
- }
-
- DataSize = CurrentSize - sizeof (Hdr);
- if (DataSize > SizeLeft) {
- DataSize = SizeLeft;
- }
-
- if (fwrite (&Hdr, sizeof (Hdr), 1, OutFptr) != 1) {
- Error (NULL, 0, 0, FileName, "failed to write capsule header to output file");
- fclose (OutFptr);
- goto FailDone;
- }
-
- if (fwrite (Buffer, DataSize, 1, OutFptr) != 1) {
- Error (NULL, 0, 0, FileName, "failed to write capsule data to output file");
- fclose (OutFptr);
- goto FailDone;
- }
-
- Hdr.SequenceNumber++;
- Buffer += DataSize;
- SizeLeft -= DataSize;
- FileSize = DataSize + sizeof (Hdr);
- }
- //
- // Next size in list if there is one
- //
- if (mOptions.CurrentSize->Next != NULL) {
- mOptions.CurrentSize = mOptions.CurrentSize->Next;
- }
-
- SequenceNumber++;
- fclose (OutFptr);
- OutFptr = NULL;
- printf ("Created %s - 0x%X bytes (0x%X bytes of data)\n", FileName, FileSize, DataSize);
- }
-
- goto Done;
-FailDone:
- Status = STATUS_ERROR;
-Done:
- if (CapHdr != NULL) {
- free (CapHdr);
- }
-
- if (CapFptr != NULL) {
- fclose (CapFptr);
- }
-
- if (OutFptr != NULL) {
- fclose (OutFptr);
- }
-
- return Status;
-
-#endif
- return STATUS_SUCCESS;
-}
-
-static
-BOOLEAN
-GetSplitFileName (
- INT8 *BaseFileName,
- INT8 *NewFileName,
- UINT32 SequenceNumber
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- BaseFileName - GC_TODO: add argument description
- NewFileName - GC_TODO: add argument description
- SequenceNumber - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- /*++
-
-Routine Description:
- Given an initial split capsule file name and a sequence number,
- create an appropriate file name for this split of a capsule image.
-
-Arguments:
- BaseFileName - name of of the first split file in the series
- NewFileName - output name of the split file
- SequenceNumber - 0-based sequence number of split images
-
-Returns:
- TRUE - name created successfully
- FALSE - otherwise
-
---*/
- INT8 *Ptr;
- INT8 *Part2Start;
- UINT32 Digits;
- UINT32 Len;
- UINT32 BaseOffset;
- //
- // Work back from the end of the file name and see if there is a number somewhere
- //
- for (Ptr = BaseFileName + strlen (BaseFileName) - 1; (Ptr > BaseFileName) && !isdigit (*Ptr); Ptr--)
- ;
- if ((Ptr == BaseFileName) && (!isdigit (*Ptr))) {
- //
- // Found no number, so just add it to the end
- //
- sprintf (NewFileName, "%s%d", BaseFileName, SequenceNumber);
- return TRUE;
- } else {
- //
- // Found a number. Look back to find the first digit.
- //
- Part2Start = Ptr + 1;
- for (Digits = 1; isdigit (*Ptr) && (Ptr > BaseFileName); Ptr--, Digits++)
- ;
- if (!isdigit (*Ptr)) {
- Ptr++;
- Digits--;
- }
-
- BaseOffset = atoi (Ptr);
- SequenceNumber = SequenceNumber + BaseOffset;
- if (Digits > 1) {
- //
- // Copy the first part of the original file name to the new filename
- // This is the path for filenames with format path\name001.cap
- //
- Len = (UINT32) Ptr - (UINT32) BaseFileName;
- strncpy (NewFileName, BaseFileName, Len);
- sprintf (NewFileName + Len, "%0*d", Digits, SequenceNumber);
- strcat (NewFileName, Part2Start);
- return TRUE;
- } else {
- //
- // Only one digit found. This is the path for filenames with
- // format path\name1.cap
- //
- Len = (UINT32) Ptr - (UINT32) BaseFileName + 1;
- strncpy (NewFileName, BaseFileName, Len);
- sprintf (NewFileName + Len - 1, "%d", SequenceNumber);
- strcat (NewFileName, Part2Start);
- return TRUE;
- }
- }
-}
-
-static
-BOOLEAN
-IsWhiteSpace (
- WCHAR Char
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- Char - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- switch (Char) {
- case UNICODE_SPACE:
- case UNICODE_TAB:
- case UNICODE_NULL:
- case UNICODE_CR:
- case UNICODE_LF:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-static
-BOOLEAN
-IsToken (
- SOURCE_FILE *File,
- WCHAR *Token
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- File - GC_TODO: add argument description
- Token - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- SkipWhiteSpace (File);
- if (EndOfFile (File)) {
- return FALSE;
- }
-
- if (wcsncmp (Token, File->FileBufferPtr, wcslen (Token)) == 0) {
- File->FileBufferPtr += wcslen (Token);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static
-STATUS
-CheckFirmwareVolumeHeader (
- INT8 *FileName,
- INT8 *Buffer,
- UINT32 BufferSize
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- FileName - GC_TODO: add argument description
- Buffer - GC_TODO: add argument description
- BufferSize - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- EFI_FIRMWARE_VOLUME_HEADER *Hdr;
- EFI_GUID FVHeaderGuid = EFI_FIRMWARE_FILE_SYSTEM_GUID;
-
- Hdr = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
- if (Hdr->Signature != EFI_FVH_SIGNATURE) {
- Error (NULL, 0, 0, FileName, "file does not appear to be a firmware volume (bad signature)");
- return STATUS_ERROR;
- }
-
- if (Hdr->Revision != EFI_FVH_REVISION) {
- Error (NULL, 0, 0, FileName, "unsupported firmware volume header version");
- return STATUS_ERROR;
- }
-
- if (Hdr->FvLength > BufferSize) {
- Error (NULL, 0, 0, FileName, "malformed firmware volume -- FvLength > file size");
- return STATUS_ERROR;
- }
-
- if (memcmp (&Hdr->FileSystemGuid, &FVHeaderGuid, sizeof (EFI_GUID)) != 0) {
- Error (NULL, 0, 0, FileName, "invalid FFS GUID in firmware volume header");
- return STATUS_ERROR;
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-void
-DumpCapsule (
- VOID
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- None
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
-#if 0
- FILE *InFptr;
- FILE_LIST *FileList;
- EFI_CAPSULE_HEADER CapsuleHeader;
- EFI_FIRMWARE_VOLUME_HEADER FVHeader;
- EFI_CAPSULE_OEM_HEADER *OemHeader;
- UINT8 *BPtr;
- UINT32 FileSize;
- UINT32 CapsuleHeaderDataSize;
- UINT8 ByteCount;
- UINT8 *CapsuleHeaderData;
- BOOLEAN SplitImage;
-
- InFptr = NULL;
- CapsuleHeaderData = NULL;
- FileList = mOptions.FileList;
- while (FileList != NULL) {
- if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {
- Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");
- goto Done;
- }
-
- if (fread (&CapsuleHeader, sizeof (EFI_CAPSULE_HEADER), 1, InFptr) != 1) {
- Error (NULL, 0, 0, FileList->FileName, "failed to read capsule header");
- goto Done;
- }
-
- fseek (InFptr, 0, SEEK_END);
- FileSize = ftell (InFptr);
- if (CapsuleHeader.CapsuleImageSize > FileSize) {
- SplitImage = TRUE;
- } else {
- SplitImage = FALSE;
- }
-
- printf (
- "Capsule %s Size=0x%X CargoSize=0x%X\n",
- FileList->FileName,
- FileSize,
- FileSize - CapsuleHeader.OffsetToCapsuleBody
- );
- printf (
- " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- CapsuleHeader.CapsuleGuid.Data1,
- (UINT32) CapsuleHeader.CapsuleGuid.Data2,
- (UINT32) CapsuleHeader.CapsuleGuid.Data3,
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[0],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[1],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[2],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[3],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[4],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[5],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[6],
- (UINT32) CapsuleHeader.CapsuleGuid.Data4[7]
- );
- if (memcmp (&CapsuleHeader.CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) {
- printf (" INVALID GUID");
- }
-
- printf ("\n");
- printf (" Header size 0x%08X\n", CapsuleHeader.HeaderSize);
- printf (" Flags 0x%08X\n", CapsuleHeader.Flags);
- if (!SplitImage) {
- printf (" Capsule image size 0x%08X\n", CapsuleHeader.CapsuleImageSize);
- } else {
- printf (" Capsule image size 0x%08X (split)\n", CapsuleHeader.CapsuleImageSize);
- }
-
- printf (" Sequence number %d\n", CapsuleHeader.SequenceNumber);
- printf (
- " InstanceId %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
- CapsuleHeader.InstanceId.Data1,
- (UINT32) CapsuleHeader.InstanceId.Data2,
- (UINT32) CapsuleHeader.InstanceId.Data3,
- (UINT32) CapsuleHeader.InstanceId.Data4[0],
- (UINT32) CapsuleHeader.InstanceId.Data4[1],
- (UINT32) CapsuleHeader.InstanceId.Data4[2],
- (UINT32) CapsuleHeader.InstanceId.Data4[3],
- (UINT32) CapsuleHeader.InstanceId.Data4[4],
- (UINT32) CapsuleHeader.InstanceId.Data4[5],
- (UINT32) CapsuleHeader.InstanceId.Data4[6],
- (UINT32) CapsuleHeader.InstanceId.Data4[7]
- );
- printf (" Offset to capsule 0x%X\n", CapsuleHeader.OffsetToCapsuleBody);
- //
- // Dump header data if there
- //
- CapsuleHeaderDataSize = CapsuleHeader.OffsetToCapsuleBody - CapsuleHeader.HeaderSize;
- if (CapsuleHeaderDataSize != 0) {
- CapsuleHeaderData = (UINT8 *) malloc (CapsuleHeaderDataSize);
- if (CapsuleHeaderData == NULL) {
- Error (
- NULL,
- 0,
- 0,
- "failed to allocate memory to read in capsule header data",
- "0x%X bytes",
- CapsuleHeaderDataSize
- );
- goto Done;
- }
-
- fseek (InFptr, CapsuleHeader.HeaderSize, SEEK_SET);
- if (fread (CapsuleHeaderData, CapsuleHeaderDataSize, 1, InFptr) != 1) {
- Error (
- NULL,
- 0,
- 0,
- "failed to read capsule header data contents from file",
- "0x%X bytes",
- CapsuleHeaderDataSize
- );
- goto Done;
- }
- //
- // ************************************************************************
- //
- // OEM HEADER
- //
- // ************************************************************************
- //
- if (CapsuleHeader.OffsetToOemDefinedHeader != 0) {
- OemHeader = (EFI_CAPSULE_OEM_HEADER *) (CapsuleHeaderData + CapsuleHeader.OffsetToOemDefinedHeader - CapsuleHeader.HeaderSize);
- printf (" OEM Header\n");
- printf (
- " GUID %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
- OemHeader->OemGuid.Data1,
- (UINT32) OemHeader->OemGuid.Data2,
- (UINT32) OemHeader->OemGuid.Data3,
- (UINT32) OemHeader->OemGuid.Data4[0],
- (UINT32) OemHeader->OemGuid.Data4[1],
- (UINT32) OemHeader->OemGuid.Data4[2],
- (UINT32) OemHeader->OemGuid.Data4[3],
- (UINT32) OemHeader->OemGuid.Data4[4],
- (UINT32) OemHeader->OemGuid.Data4[5],
- (UINT32) OemHeader->OemGuid.Data4[6],
- (UINT32) OemHeader->OemGuid.Data4[7]
- );
- printf (" Header size: 0x%X\n", OemHeader->HeaderSize);
- printf (" OEM data");
- BPtr = (UINT8 *) (OemHeader + 1);
- for (ByteCount = 0; ByteCount < OemHeader->HeaderSize - sizeof (EFI_CAPSULE_OEM_HEADER); ByteCount++) {
- if ((ByteCount & 0x7) == 0) {
- printf ("\n ");
- }
-
- printf ("%02X ", (UINT32) *BPtr);
- BPtr++;
- }
-
- printf ("\n");
- }
- //
- // ************************************************************************
- //
- // Author, revision, short description, and long description information
- //
- // ************************************************************************
- //
- if (CapsuleHeader.OffsetToAuthorInformation != 0) {
- if (DumpCapsuleHeaderStrings (
- "Author information",
- (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToAuthorInformation - CapsuleHeader.HeaderSize)
- ) != STATUS_SUCCESS) {
- goto Done;
- }
- }
-
- if (CapsuleHeader.OffsetToRevisionInformation != 0) {
- if (DumpCapsuleHeaderStrings (
- "Revision information",
- (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToRevisionInformation - CapsuleHeader.HeaderSize)
- ) != STATUS_SUCCESS) {
- goto Done;
- }
- }
-
- if (CapsuleHeader.OffsetToShortDescription != 0) {
- if (DumpCapsuleHeaderStrings (
- "Short description",
- (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToShortDescription - CapsuleHeader.HeaderSize)
- ) != STATUS_SUCCESS) {
- goto Done;
- }
- }
-
- if (CapsuleHeader.OffsetToLongDescription != 0) {
- if (DumpCapsuleHeaderStrings (
- "Long description",
- (WCHAR *) (CapsuleHeaderData + CapsuleHeader.OffsetToLongDescription - CapsuleHeader.HeaderSize)
- ) != STATUS_SUCCESS) {
- goto Done;
- }
- }
- }
- //
- // If it's not a split image, or it is a split image and this is the first in the series, then
- // dump the cargo volume.
- //
- if ((!SplitImage) || (CapsuleHeader.SequenceNumber == 0)) {
- printf (" Cargo FV dump\n");
- fseek (InFptr, CapsuleHeader.OffsetToCapsuleBody, SEEK_SET);
- if (fread (&FVHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER), 1, InFptr) != 1) {
- Error (NULL, 0, 0, FileList->FileName, "failed to read cargo FV header");
- goto Done;
- }
-
- printf (" FV length 0x%X", FVHeader.FvLength);
- if (FileSize - CapsuleHeader.OffsetToCapsuleBody != FVHeader.FvLength) {
- if (!SplitImage) {
- printf (" ERROR: expected 0x%X to jive with file size on disk", FileSize - CapsuleHeader.OffsetToCapsuleBody);
- }
- }
-
- printf ("\n");
- printf (" Signature 0x%X ", FVHeader.Signature);
- if (FVHeader.Signature == EFI_FVH_SIGNATURE) {
- printf ("_FVH\n");
- } else {
- printf ("INVALID\n");
- }
-
- printf (" FV header length 0x%X\n", (UINT32) FVHeader.HeaderLength);
- printf (" Revision 0x%X\n", (UINT32) FVHeader.Revision);
- printf ("\n");
- }
-
- FileList = FileList->Next;
- }
-
-Done:
- if (InFptr != NULL) {
- fclose (InFptr);
- }
-
- if (CapsuleHeaderData != NULL) {
- free (CapsuleHeaderData);
- }
-#endif
-}
-
-static
-STATUS
-JoinCapsule (
- VOID
- )
-/*++
-
-Routine Description:
- Join split capsule images into a single image. This is the
- support function for the -j command-line option.
-
-Arguments:
- None.
-
-Returns:
- STATUS_SUCCESS - no problems encountered
-
---*/
-{
-#if 0
- UINT32 Size;
- FILE *InFptr;
- FILE *OutFptr;
- INT8 *Buffer;
- FILE_LIST *FileList;
- STATUS Status;
- EFI_CAPSULE_HEADER CapHdr;
- EFI_CAPSULE_HEADER *CapHdrPtr;
- UINT32 SizeLeft;
- UINT32 SequenceNumber;
- //
- // Must have at least two files for join mode
- //
- if ((mOptions.FileList == NULL) || (mOptions.FileList->Next == NULL)) {
- Error (NULL, 0, 0, "must specify at least two file names to join", NULL);
- return STATUS_ERROR;
- }
- //
- // Open the output file
- //
- if ((OutFptr = fopen (mOptions.OutputFileName, "wb")) == NULL) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to open output file for writing");
- return STATUS_ERROR;
- }
-
- FileList = mOptions.FileList;
- Buffer = NULL;
- SequenceNumber = 0;
- InFptr = NULL;
- SizeLeft = 0;
- while (FileList != NULL) {
- if ((InFptr = fopen (FileList->FileName, "rb")) == NULL) {
- Error (NULL, 0, 0, FileList->FileName, "failed to open file for reading");
- goto FailDone;
- }
- //
- // Allocate a buffer into which we can read the file.
- //
- fseek (InFptr, 0, SEEK_END);
- Size = ftell (InFptr);
- rewind (InFptr);
- Buffer = (char *) malloc (Size);
- if (Buffer == NULL) {
- Error (__FILE__, __LINE__, 0, FileList->FileName, "failed to allocate buffer to read file into");
- goto FailDone;
- }
-
- CapHdrPtr = (EFI_CAPSULE_HEADER *) Buffer;
- if (fread ((void *) Buffer, Size, 1, InFptr) != 1) {
- Error (NULL, 0, 0, FileList->FileName, "failed to read file contents");
- goto FailDone;
- }
- //
- // Check the header for validity. Check size first.
- //
- if (Size < sizeof (EFI_CAPSULE_HEADER)) {
- Error (NULL, 0, 0, FileList->FileName, "file size is insufficient for a capsule header");
- goto FailDone;
- }
- //
- // Check GUID
- //
- if (memcmp (&CapHdrPtr->CapsuleGuid, &mEfiCapsuleHeaderGuid, sizeof (EFI_GUID)) != 0) {
- Error (NULL, 0, 0, FileList->FileName, "invalid capsule GUID");
- goto FailDone;
- }
- //
- // Check sequence number
- //
- if (CapHdrPtr->SequenceNumber != SequenceNumber) {
- Error (
- NULL,
- 0,
- 0,
- FileList->FileName,
- "invalid sequence number %d (expected %d)",
- CapHdrPtr->SequenceNumber,
- SequenceNumber
- );
- goto FailDone;
- }
- //
- // If the first file, read save the capsule header
- //
- if (SequenceNumber == 0) {
- memcpy (&CapHdr, CapHdrPtr, sizeof (EFI_CAPSULE_HEADER));
- //
- // Erase the InstanceId GUID
- //
- memset (&CapHdrPtr->InstanceId, 0, sizeof (EFI_GUID));
- if (fwrite (Buffer, Size, 1, OutFptr) != 1) {
- Error (NULL, 0, 0, FileList->FileName, "failed to write contents to output file");
- goto FailDone;
- }
-
- if (CapHdr.CapsuleImageSize < Size) {
- Error (NULL, 0, 0, FileList->FileName, "capsule image size in capsule header < image size");
- goto FailDone;
- }
-
- SizeLeft = CapHdr.CapsuleImageSize - Size;
- } else {
- //
- // Check the GUID against the first file's GUID
- //
- if (memcmp (&CapHdr.CapsuleGuid, &CapHdrPtr->CapsuleGuid, sizeof (EFI_GUID)) != 0) {
- Error (NULL, 0, 0, FileList->FileName, "GUID does not match first file's GUID");
- goto FailDone;
- }
- //
- // Make sure we're not throwing out any header info
- //
- if (CapHdrPtr->OffsetToCapsuleBody > sizeof (EFI_CAPSULE_HEADER)) {
- //
- // Could be the split information, so just emit a warning
- //
- Warning (
- NULL,
- 0,
- 0,
- FileList->FileName,
- "image appears to have additional capsule header information -- ignoring"
- );
- } else if (CapHdrPtr->OffsetToCapsuleBody < sizeof (EFI_CAPSULE_HEADER)) {
- Error (NULL, 0, 0, FileList->FileName, "offset to capsule body in capsule header is insufficient");
- goto FailDone;
- }
-
- if (fwrite (Buffer + CapHdrPtr->OffsetToCapsuleBody, Size - CapHdrPtr->OffsetToCapsuleBody, 1, OutFptr) != 1) {
- Error (NULL, 0, 0, mOptions.OutputFileName, "failed to write to file");
- goto FailDone;
- }
-
- if (SizeLeft < (Size - CapHdrPtr->OffsetToCapsuleBody)) {
- Error (NULL, 0, 0, "sum of image sizes exceeds size specified in initial capsule header", NULL);
- goto FailDone;
- }
- //
- // printf ("FILE: %s OffsetToCapsuleBody=0x%X\n", FileList->FileName, CapHdrPtr->OffsetToCapsuleBody);
- //
- SizeLeft = SizeLeft - (Size - CapHdrPtr->OffsetToCapsuleBody);
- }
- //
- // printf ("FILE: %s sizeleft=0x%X\n", FileList->FileName, SizeLeft);
- //
- fclose (InFptr);
- InFptr = NULL;
- free (Buffer);
- Buffer = NULL;
- FileList = FileList->Next;
- SequenceNumber++;
- }
-
- if (SizeLeft) {
- Error (NULL, 0, 0, "sum of capsule images is insufficient", "0x%X bytes missing", SizeLeft);
- goto FailDone;
- }
-
- Status = STATUS_SUCCESS;
- goto Done;
-FailDone:
- Status = STATUS_ERROR;
-Done:
- if (InFptr != NULL) {
- fclose (InFptr);
- }
-
- if (OutFptr != NULL) {
- fclose (OutFptr);
- }
-
- if (Buffer != NULL) {
- free (Buffer);
- }
-
- return Status;
-
-#endif
-return STATUS_SUCCESS;
-}
-
-static
-STATUS
-DumpCapsuleHeaderStrings (
- UINT8 *SectionName,
- WCHAR *Buffer
- )
-/*++
-
-Routine Description:
- Given a pointer to string data from a capsule header, dump
- the strings.
-
-Arguments:
- SectionName - name of the capsule header section to which
- the string data pertains
- Buffer - pointer to string data from a capsule header
-
-Returns:
- STATUS_SUCCESS - all went well
-
---*/
-{
- printf (" %s\n", SectionName);
- while (*Buffer) {
- printf (" Language: %S\n", Buffer);
- while (*Buffer) {
- Buffer++;
- }
-
- Buffer++;
- while (*Buffer) {
- if (wcslen (Buffer) > 60) {
- printf (" %.60S\n", Buffer);
- Buffer += 60;
- } else {
- printf (" %S\n", Buffer);
- Buffer += wcslen (Buffer);
- }
- }
-
- Buffer++;
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-STATUS
-GetHexValue (
- SOURCE_FILE *SourceFile,
- UINT32 *Value,
- UINT32 NumDigits
- )
-/*++
-
-Routine Description:
- Scan a hex value from the input stream.
-
-Arguments:
- SourceFile - input file contents
- Value - returned value
- NumDigits - number of digits to read
-
-Returns:
- STATUS_SUCCESS - if NumDigits were read from the file
- STATUS_ERROR - otherwise
-
-
---*/
-{
- WCHAR *SaveFilePos;
- UINT32 Digits;
- WCHAR Nibble;
-
- SaveFilePos = SourceFile->FileBufferPtr;
- *Value = 0;
- Digits = NumDigits;
- while (Digits > 0) {
- Nibble = SourceFile->FileBufferPtr[0];
- if ((Nibble >= UNICODE_0) && (Nibble <= UNICODE_9)) {
- *Value = (*Value << 4) | (Nibble - UNICODE_0);
- } else if ((Nibble >= UNICODE_A) && (Nibble <= UNICODE_F)) {
- *Value = (*Value << 4) | (Nibble - UNICODE_A + 0x10);
- } else if ((Nibble >= UNICODE_a) && (Nibble <= UNICODE_f)) {
- *Value = (*Value << 4) | (Nibble - UNICODE_a + 0x10);
- } else {
- Error (
- SourceFile->FileName,
- SourceFile->LineNum,
- 0,
- NULL,
- "expected %d valid hex nibbles at %.20S",
- NumDigits,
- SaveFilePos
- );
- return STATUS_ERROR;
- }
-
- SourceFile->FileBufferPtr++;
- Digits--;
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-BOOLEAN
-EndOfFile (
- SOURCE_FILE *File
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- File - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- if ((UINT32) File->FileBufferPtr - (UINT32) File->FileBuffer >= File->FileSize) {
- File->EndOfFile = TRUE;
- }
- //
- // Reposition to the end of the file if we went beyond
- //
- if (File->EndOfFile) {
- File->FileBufferPtr = File->FileBuffer + File->FileSize / sizeof (WCHAR);
- }
-
- return File->EndOfFile;
-}
-
-static
-void
-SkipWhiteSpace (
- SOURCE_FILE *SourceFile
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- SourceFile - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- while (!EndOfFile (SourceFile)) {
- switch (*SourceFile->FileBufferPtr) {
- case UNICODE_NULL:
- case UNICODE_CR:
- case UNICODE_SPACE:
- case UNICODE_TAB:
- SourceFile->FileBufferPtr++;
- break;
-
- case UNICODE_LF:
- SourceFile->FileBufferPtr++;
- SourceFile->LineNum++;
- break;
-
- default:
- return ;
- }
- }
-}
-//
-// Parse a number. Possible format:
-// 1234
-// 1234k
-// 1234K
-// 1M
-// 1m
-// 0x100
-//
-static
-BOOLEAN
-GetNumber (
- INT8 *Str,
- UINT32 *Value
- )
-/*++
-
-Routine Description:
-
- GC_TODO: Add function description
-
-Arguments:
-
- Str - GC_TODO: add argument description
- Value - GC_TODO: add argument description
-
-Returns:
-
- GC_TODO: add return values
-
---*/
-{
- UINT32 LValue;
-
- *Value = 0;
- LValue = 0;
- if (!isdigit (Str[0])) {
- return FALSE;
- }
- //
- // Look for hex number
- //
- if ((Str[0] == '0') && (tolower (Str[1]) == 'x')) {
- Str += 2;
- if (Str[0] == 0) {
- return FALSE;
- }
-
- while (Str[0]) {
- if ((Str[0] >= '0') && (Str[0] <= '9')) {
- LValue = (LValue << 4) | (Str[0] - '0');
- } else if ((Str[0] >= 'A') && (Str[0] <= 'F')) {
- LValue = (LValue << 4) | (Str[0] - 'A' + 0x10);
- } else if ((Str[0] >= 'a') && (Str[0] <= 'f')) {
- LValue = (LValue << 4) | (Str[0] - 'a' + 0x10);
- } else {
- break;
- }
-
- Str++;
- }
- } else {
- LValue = atoi (Str);
- while (isdigit (*Str)) {
- Str++;
- }
- }
- //
- // If string left over, better be one character we recognize
- //
- if (Str[0]) {
- if (Str[1]) {
- return FALSE;
- }
-
- switch (Str[0]) {
- case 'k':
- case 'K':
- LValue *= 1024;
- break;
-
- case 'm':
- case 'M':
- LValue *= 1024 * 1024;
- break;
-
- default:
- return FALSE;
- }
- }
-
- *Value = LValue;
- return TRUE;
-}
-//
-// Process the command-line arguments
-//
-static
-STATUS
-ProcessArgs (
- int Argc,
- char *Argv[]
- )
-/*++
-
-Routine Description:
-
- Processes command line arguments.
-
-Arguments:
-
- Argc - Number of command line arguments
- Argv[] - Array of files input on command line
-
-Returns:
-
- STATUS_ERROR - Function exited with an error
- STATUS_SUCCESS - Function executed successfully
-
---*/
-{
- FILE_LIST *NewFile;
-
- FILE_LIST *LastFile;
- SIZE_LIST *NewSize;
-
- NewFile = NULL;
- NewSize = NULL;
-
- //
- // Clear our globals
- //
- memset ((char *) &mOptions, 0, sizeof (mOptions));
-
- //
- // Skip program name
- //
- Argc--;
- Argv++;
-
- if (Argc == 0) {
- Usage ();
- return STATUS_ERROR;
- }
-
- if ((strcmp(Argv[0], "-h") == 0) || (strcmp(Argv[0], "--help") == 0) ||
- (strcmp(Argv[0], "-?") == 0) || (strcmp(Argv[0], "/?") == 0)) {
- Usage();
- return STATUS_ERROR;
- }
-
- if ((strcmp(Argv[0], "-V") == 0) || (strcmp(Argv[0], "--version") == 0)) {
- Version();
- return STATUS_ERROR;
- }
-
- if (Argc == 1) {
- Usage ();
- return STATUS_ERROR;
- }
-
- //
- // Process until no more options
- //
- while ((Argc > 0) && (Argv[0][0] == '-')) {
- if (stricmp (Argv[0], "-script") == 0) {
- //
- // Check for one more arg
- //
- if (Argc > 1) {
- //
- // Save the file name
- //
- if (strlen (Argv[1]) >= sizeof (mOptions.ScriptFileName)) {
- Error (NULL, 0, 0, NULL, "input script file name length exceeds internal buffer size");
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- strcpy (mOptions.ScriptFileName, Argv[1]);
- } else {
- Error (NULL, 0, 0, Argv[0], "missing script file name with option");
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- Argc--;
- Argv++;
- //
- // -o outfilename -- specify output file name (required)
- //
- } else if (stricmp (Argv[0], "-o") == 0) {
- //
- // check for one more arg
- //
- if (Argc > 1) {
- //
- // Try to open the file
- //
- // if ((mOptions.OutFptr = fopen (Argv[1], "wb")) == NULL) {
- // Error (NULL, 0, 0, Argv[1], "failed to open output file for writing");
- // return STATUS_ERROR;
- // }
- //
- strcpy (mOptions.OutputFileName, Argv[1]);
- } else {
- Error (NULL, 0, 0, Argv[0], "missing output filename with option");
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- Argc--;
- Argv++;
- } else if (stricmp (Argv[0], "-j") == 0) {
- mOptions.JoinMode = TRUE;
- //
- // -split <size> option (multiple allowed)
- //
- } else if (stricmp (Argv[0], "-split") == 0) {
- if (Argc > 1) {
- NewSize = (SIZE_LIST *) malloc (sizeof (SIZE_LIST));
- if (NewSize == NULL) {
- Error (NULL, 0, 0, "memory allocation failure", NULL);
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- memset (NewSize, 0, sizeof (SIZE_LIST));
- //
- // Get the size from the next arg, and then add this size
- // to our size list
- //
- if (!GetNumber (Argv[1], &NewSize->Size)) {
- Error (NULL, 0, 0, Argv[1], "invalid split size argument");
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- if (mOptions.SizeList == NULL) {
- mOptions.SizeList = NewSize;
- mOptions.CurrentSize = NewSize;
- } else {
- mOptions.LastSize->Next = NewSize;
- }
-
- mOptions.LastSize = NewSize;
- free (NewSize);
- } else {
- Error (NULL, 0, 0, Argv[0], "missing size parameter with option");
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- Argc--;
- Argv++;
- } else if ((stricmp (Argv[0], "-h") == 0) || (strcmp (Argv[0], "-?") == 0)) {
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- //
- // Default minimum header
- //
- } else if (stricmp (Argv[0], "-dump") == 0) {
- mOptions.Dump = TRUE;
- } else if (stricmp (Argv[0], "-v") == 0) {
- mOptions.Verbose = TRUE;
- } else {
- Error (NULL, 0, 0, Argv[0], "unrecognized option");
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- Argc--;
- Argv++;
- }
- //
- // Can't -j join files and -s split output capsule
- //
- if ((mOptions.SizeList != NULL) && (mOptions.JoinMode)) {
- Error (NULL, 0, 0, "cannot specify both -j and -size", NULL);
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
- //
- // Must have specified an output file name if not -dump
- //
- if ((mOptions.Dump == 0) && (mOptions.OutputFileName[0] == 0)) {
- Error (NULL, 0, 0, NULL, "-o OutputFileName must be specified");
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
- //
- // Rest of arguments are input files. The first one is a firmware
- // volume image, and the rest are FFS files that are to be inserted
- // into the firmware volume.
- //
- LastFile = NULL;
- while (Argc > 0) {
- NewFile = (FILE_LIST *) malloc (sizeof (FILE_LIST));
- if (NewFile == NULL) {
- Error (NULL, 0, 0, "memory allocation failure", NULL);
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- memset ((char *) NewFile, 0, sizeof (FILE_LIST));
- strcpy (NewFile->FileName, Argv[0]);
- if (mOptions.FileList == NULL) {
- mOptions.FileList = NewFile;
- } else {
- if (LastFile == NULL) {
- LastFile = NewFile;
- } else {
- LastFile->Next = NewFile;
- }
- }
-
- LastFile = NewFile;
- Argc--;
- Argv++;
- }
-
- //
- // Must have provided at least one file name
- //
- if (mOptions.FileList == NULL) {
- Error (NULL, 0, 0, "must specify at least one file name", NULL);
- Usage ();
-
- if (NewFile != NULL) {
- free (NewFile);
- }
- if (NewSize != NULL) {
- free (NewSize);
- }
-
- return STATUS_ERROR;
- }
-
- return STATUS_SUCCESS;
-}
-
-static
-void
-Version(
- void
- )
-/*++
-
-Routine Description:
-
- Print out version information for this utility.
-
-Arguments:
-
- None
-
-Returns:
-
- None
-
---*/
-{
- printf ("%s v%d.%d -EDK utility to create a capsule header.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
- printf ("Copyright (c) 1999-2006 Intel Corporation. All rights reserved.\n");
-}
-
-static
-void
-Usage (
- VOID
- )
-/*++
-
-Routine Description:
-
- Print usage information for this utility.
-
-Arguments:
-
- None.
-
-Returns:
-
- Nothing.
-
---*/
-{
- int Index;
- static const char *Str[] = {
- "\nUsage: "UTILITY_NAME " {options} [CapsuleFV]",
- //
- // {FfsFileNames}",
- //
- " Options include:",
- " -h,--help,-?,/? to display help messages",
- " -V,--version to display version information",
- " -script fname to take capsule header info from unicode script",
- " file fname",
- " -o fname write output to file fname (required)",
- " -split size split capsule image into multiple output files",
- " -dump to dump a capsule header",
- " -v for verbose output\n",
- " -j to join split capsule images into a single image",
- "",
- " CapsuleFV is the name of an existing well-formed Tiano firmware",
- " volume file.",
- //
- // FfsFileNames are the names of one or more Tiano FFS files to",
- // " insert into the output capsule image.",
- //
- NULL
- };
-
- Version();
-
- for (Index = 0; Str[Index] != NULL; Index++) {
- fprintf (stdout, "%s\n", Str[Index]);
- }
-}