summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c')
-rw-r--r--EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c2417
1 files changed, 2417 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c b/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c
new file mode 100644
index 0000000000..97d58925b4
--- /dev/null
+++ b/EdkCompatibilityPkg/Sample/Tools/Source/GuidChk/GuidChk.c
@@ -0,0 +1,2417 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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:
+
+ GuidChk.c
+
+Abstract:
+
+ Parse files in a directory and subdirectories to find all guid definitions.
+ Then check them against each other to make sure there are no duplicates.
+
+--*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "CommonUtils.h"
+#include "FileSearch.h"
+#include "UtilsMsgs.h"
+
+#define MAX_LINE_LEN 1024 // we concatenate lines sometimes
+// Define a structure that correlates filename extensions to an enumerated
+// type.
+//
+#ifdef MAX_PATH
+#undef MAX_PATH
+#define MAX_PATH 1024
+#endif
+
+typedef struct {
+ INT8 *Extension;
+ INT8 ExtensionCode;
+} FILE_TYPE_TABLE_ENTRY;
+
+#define FILE_EXTENSION_UNKNOWN 0
+#define FILE_EXTENSION_C 1
+#define FILE_EXTENSION_H 2
+#define FILE_EXTENSION_IA32_ASM 3
+#define FILE_EXTENSION_IA32_INC 4
+#define FILE_EXTENSION_IA64_ASM 5
+#define FILE_EXTENSION_IA64_INC 6
+#define FILE_EXTENSION_PKG 7
+#define FILE_EXTENSION_INF 8
+
+FILE_TYPE_TABLE_ENTRY FileTypeTable[] = {
+ ".c",
+ FILE_EXTENSION_C,
+ ".h",
+ FILE_EXTENSION_H,
+ ".inc",
+ FILE_EXTENSION_IA32_INC,
+ ".asm",
+ FILE_EXTENSION_IA32_ASM,
+ ".s",
+ FILE_EXTENSION_IA64_ASM,
+ ".pkg",
+ FILE_EXTENSION_PKG,
+ ".inf",
+ FILE_EXTENSION_INF,
+ ".i",
+ FILE_EXTENSION_IA64_INC,
+ NULL,
+ 0
+};
+
+typedef struct EFI_GUID {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} EFI_GUID;
+
+typedef struct {
+ INT8 Data[8];
+ INT8 DataLen;
+} EFI_SIGNATURE;
+
+typedef struct _GUID_RECORD {
+ struct _GUID_RECORD *Next;
+ BOOLEAN Reported;
+ INT8 *FileName;
+ INT8 *SymName;
+ EFI_GUID Guid;
+} GUID_RECORD;
+
+typedef struct _SIGNATURE_RECORD {
+ struct _SIGNATURE_RECORD *Next;
+ BOOLEAN Reported;
+ INT8 *FileName;
+ EFI_SIGNATURE Signature;
+} SIGNATURE_RECORD;
+
+//
+// Utility options
+//
+typedef struct {
+ INT8 DatabaseOutputFileName[MAX_PATH]; // with -b option
+ STRING_LIST *ExcludeDirs; // list of directory names not to process
+ STRING_LIST *ExcludeSubDirs; // list of directory names to not process subdirectories (build)
+ STRING_LIST *ExcludeFiles; // list of files to exclude (make.inf)
+ STRING_LIST *ExcludeExtensions; // list of filename extensions to exclude (.inf, .pkg)
+ BOOLEAN Verbose;
+ BOOLEAN PrintFound;
+ BOOLEAN CheckGuids;
+ BOOLEAN CheckSignatures;
+ BOOLEAN GuidXReference;
+} OPTIONS;
+
+static
+STATUS
+ProcessArgs (
+ int Argc,
+ char *Argv[]
+ );
+
+static
+VOID
+Usage (
+ VOID
+ );
+
+static
+STATUS
+ProcessDirectory (
+ INT8 *Path,
+ INT8 *DirectoryName
+ );
+
+static
+STATUS
+ProcessFile (
+ INT8 *DirectoryName,
+ INT8 *FileName
+ );
+
+static
+UINT32
+GetFileExtension (
+ INT8 *FileName
+ );
+
+static
+UINT32
+SkipWhiteSpace (
+ INT8 *Str
+ );
+
+static
+UINT32
+ValidSymbolName (
+ INT8 *Name
+ );
+
+static
+STATUS
+ProcessCFileGuids (
+ INT8 *FileName
+ );
+
+static
+STATUS
+AddSignature (
+ INT8 *FileName,
+ INT8 *StrDef,
+ UINT32 SigSize
+ );
+
+static
+STATUS
+ProcessCFileSigs (
+ INT8 *FileName
+ );
+
+static
+STATUS
+ProcessINFFileGuids (
+ INT8 *FileName
+ );
+
+static
+STATUS
+ProcessPkgFileGuids (
+ INT8 *FileName
+ );
+
+static
+STATUS
+ProcessIA32FileGuids (
+ INT8 *FileName
+ );
+
+static
+STATUS
+ProcessIA64FileGuids (
+ INT8 *FileName
+ );
+
+static
+BOOLEAN
+IsIA64GuidLine (
+ INT8 *Line,
+ UINT32 *GuidHigh,
+ UINT32 *GuidLow,
+ BOOLEAN *Low,
+ INT8 *SymName
+ );
+
+static
+STATUS
+AddGuid11 (
+ INT8 *FileName,
+ UINT32 *Data,
+ INT8 *SymName
+ );
+
+static
+STATUS
+AddPkgGuid (
+ INT8 *FileName,
+ UINT32 *Data,
+ UINT64 *Data64
+ );
+
+static
+STATUS
+AddGuid16 (
+ INT8 *FileName,
+ UINT32 *Data
+ );
+
+static
+STATUS
+AddGuid64x2 (
+ INT8 *FileName,
+ UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid
+ UINT32 DataHL, // Lower 32-bits of upper 64 bits
+ UINT32 DataLH,
+ UINT32 DataLL,
+ INT8 *SymName
+ );
+
+static
+VOID
+FreeGuids (
+ VOID
+ );
+
+static
+VOID
+FreeSigs (
+ VOID
+ );
+
+static
+STATUS
+CheckDuplicates (
+ VOID
+ );
+
+//
+// static
+// VOID
+// ReportGuid (
+// INT8 *FileName,
+// GUID_RECORD *FileRecord
+// );
+//
+static
+VOID
+FreeOptions (
+ VOID
+ );
+
+static
+BOOLEAN
+CheckGuidData (
+ UINT32 *GuidData,
+ UINT32 DataCount
+ );
+
+static
+VOID
+ConcatenateLines (
+ FILE *Fptr,
+ INT8 *Line,
+ UINT32 Len
+ );
+
+/**************************** GLOBALS ****************************************/
+static GUID_RECORD *gGuidList = NULL;
+static SIGNATURE_RECORD *gSignatureList = NULL;
+static OPTIONS gOptions;
+
+/*****************************************************************************/
+int
+main (
+ int Argc,
+ char *Argv[]
+ )
+{
+ INT8 *Cwd;
+ STATUS Status;
+
+ SetUtilityName ("GuidChk");
+ //
+ // Get the current working directory and then process the command line
+ // arguments.
+ //
+ Cwd = _getcwd (NULL, 0);
+ Status = ProcessArgs (Argc, Argv);
+ if (Status != STATUS_SUCCESS) {
+ return Status;
+ }
+
+ if (gOptions.CheckGuids || gOptions.CheckSignatures) {
+ Status = ProcessDirectory (Cwd, NULL);
+ if (Status == STATUS_SUCCESS) {
+ //
+ // Check for duplicates
+ //
+ Status = CheckDuplicates ();
+ }
+ }
+
+ if (gOptions.DatabaseOutputFileName[0] != 0) {
+ CreateGuidList (gOptions.DatabaseOutputFileName);
+ }
+ //
+ // Free up the memory
+ //
+ free (Cwd);
+ FreeGuids ();
+ FreeSigs ();
+ FreeOptions ();
+ return GetUtilityStatus ();
+}
+
+static
+STATUS
+ProcessArgs (
+ int Argc,
+ char *Argv[]
+ )
+{
+ STRING_LIST *StrList;
+
+ memset ((char *) &gOptions, 0, sizeof (gOptions));
+ //
+ // skip over program name
+ //
+ Argc--;
+ Argv++;
+
+ if (Argc == 0) {
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ while (Argc > 0) {
+ //
+ // Look for options
+ //
+ if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {
+ switch (Argv[0][1]) {
+ //
+ // Help option
+ //
+ case 'h':
+ case 'H':
+ case '?':
+ Usage ();
+ return STATUS_ERROR;
+ break;
+
+ //
+ // Check guids option
+ //
+ case 'g':
+ case 'G':
+ gOptions.CheckGuids = TRUE;
+ break;
+
+ //
+ // Check signatures option
+ //
+ case 's':
+ case 'S':
+ gOptions.CheckSignatures = TRUE;
+ break;
+
+ //
+ // Print guids found option
+ //
+ case 'p':
+ case 'P':
+ gOptions.PrintFound = TRUE;
+ break;
+
+ //
+ // Exclude files option
+ //
+ case 'f':
+ case 'F':
+ //
+ // Check for another arg
+ //
+ if (Argc < 2) {
+ Error (NULL, 0, 0, Argv[0], "missing argument with option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ StrList = malloc (sizeof (STRING_LIST));
+ if (StrList == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) StrList, 0, sizeof (STRING_LIST));
+ StrList->Str = Argv[1];
+ StrList->Next = gOptions.ExcludeFiles;
+ gOptions.ExcludeFiles = StrList;
+ Argc--;
+ Argv++;
+ break;
+
+ //
+ // Exclude directories option
+ //
+ case 'd':
+ case 'D':
+ //
+ // Check for another arg
+ //
+ if (Argc < 2) {
+ Error (NULL, 0, 0, Argv[0], "missing argument with option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ StrList = malloc (sizeof (STRING_LIST));
+ if (StrList == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) StrList, 0, sizeof (STRING_LIST));
+ StrList->Str = Argv[1];
+ StrList->Next = gOptions.ExcludeDirs;
+ gOptions.ExcludeDirs = StrList;
+ Argc--;
+ Argv++;
+ break;
+
+ //
+ // -u exclude all subdirectories of a given directory option
+ //
+ case 'u':
+ case 'U':
+ //
+ // Check for another arg
+ //
+ if (Argc < 2) {
+ Error (NULL, 0, 0, Argv[0], "missing argument with option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ StrList = malloc (sizeof (STRING_LIST));
+ if (StrList == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) StrList, 0, sizeof (STRING_LIST));
+ StrList->Str = Argv[1];
+ StrList->Next = gOptions.ExcludeSubDirs;
+ gOptions.ExcludeSubDirs = StrList;
+ Argc--;
+ Argv++;
+ break;
+
+ //
+ // -e exclude by filename extension option
+ //
+ case 'e':
+ case 'E':
+ //
+ // Check for another arg
+ //
+ if (Argc < 2) {
+ Error (NULL, 0, 0, Argv[0], "missing argument with option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ StrList = malloc (sizeof (STRING_LIST));
+ if (StrList == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) StrList, 0, sizeof (STRING_LIST));
+ //
+ // Let them put a * in front of the filename extension
+ //
+ StrList->Str = Argv[1];
+ if (StrList->Str[0] == '*') {
+ StrList->Str++;
+ }
+
+ StrList->Next = gOptions.ExcludeExtensions;
+ gOptions.ExcludeExtensions = StrList;
+ Argc--;
+ Argv++;
+ break;
+
+ //
+ // Print guid with matching symbol name for guid definitions found
+ //
+ case 'x':
+ case 'X':
+ gOptions.GuidXReference = TRUE;
+ break;
+
+ //
+ // -b Print the internal database list to a file
+ //
+ case 'b':
+ case 'B':
+ //
+ // Check for one more arg
+ //
+ if (Argc < 2) {
+ Error (NULL, 0, 0, Argv[0], "must specify file name with option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ strcpy (gOptions.DatabaseOutputFileName, Argv[1]);
+ Argc--;
+ Argv++;
+ break;
+
+ default:
+ Error (NULL, 0, 0, Argv[0], "invalid option");
+ Usage ();
+ return STATUS_ERROR;
+ }
+ } else {
+ break;
+ }
+ //
+ // Next arg
+ //
+ Argc--;
+ Argv++;
+ }
+
+ if (Argc > 0) {
+ Error (NULL, 0, 0, Argv[0], "invalid argument");
+ Usage ();
+ return STATUS_ERROR;
+ }
+ //
+ // Have to check signatures, GUIDs, or dump the GUID database.
+ //
+ if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) {
+ Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b");
+ Usage ();
+ return STATUS_ERROR;
+ }
+
+ return STATUS_SUCCESS;
+}
+//
+// Print usage instructions
+//
+static
+VOID
+Usage (
+ VOID
+ )
+{
+ int Index;
+ char *Str[] = {
+ "GuidChk - scan files for duplicate GUID or signature definitions",
+ "",
+ "Usage: GuidChk {options}\n",
+ " Options: ",
+ " -d dirname exclude searching of a directory",
+ " -f filename exclude searching of a file",
+ " -e extension exclude searching of files by extension",
+ " -p print all GUIDS found",
+ " -g check for duplicate guids",
+ " -s check for duplicate signatures",
+ " -x print guid+defined symbol name",
+ " -b outfile write internal GUID+basename list to outfile",
+ " -u dirname exclude searching all subdirectories of a directory",
+ " -h -? print this help text",
+ " ",
+ " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg",
+ "",
+ NULL
+ };
+ for (Index = 0; Str[Index] != NULL; Index++) {
+ fprintf (stdout, "%s\n", Str[Index]);
+ }
+}
+//
+// Process an entire directory by name
+//
+static
+STATUS
+ProcessDirectory (
+ INT8 *Path,
+ INT8 *DirectoryName
+ )
+{
+ FILE_SEARCH_DATA FSData;
+ char *FileMask;
+ BOOLEAN Done;
+ UINT32 Len;
+ BOOLEAN NoSubdirs;
+ STRING_LIST *SLPtr;
+
+ //
+ // Root directory may be null
+ //
+ if (DirectoryName != NULL) {
+ //
+ // printf ("Processing directory: %s\n", DirectoryName);
+ //
+ }
+ //
+ // Initialize our file searching
+ //
+ FileSearchInit (&FSData);
+
+ //
+ // Exclude some directories, files, and extensions
+ //
+ FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs);
+ FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions);
+ FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles);
+ //
+ // See if this directory is in the list of directories that they
+ // don't want to process subdirectories of
+ //
+ NoSubdirs = FALSE;
+ if (DirectoryName != NULL) {
+ for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) {
+ if (_stricmp (SLPtr->Str, DirectoryName) == 0) {
+ //
+ // printf ("not processing subdirectories of %s\n", DirectoryName);
+ //
+ NoSubdirs = TRUE;
+ break;
+ }
+ }
+ }
+ //
+ // Create a filemask of files to search for. We'll append "\*.*" on the
+ // end, so allocate some extra bytes.
+ //
+ Len = strlen (Path) + 10;
+ if (DirectoryName != NULL) {
+ Len += strlen (DirectoryName);
+ }
+
+ FileMask = malloc (Len);
+ if (FileMask == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+ //
+ // Now put it all together
+ //
+ strcpy (FileMask, Path);
+ if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) {
+ strcat (FileMask, "\\");
+ strcat (FileMask, DirectoryName);
+ }
+
+ strcat (FileMask, "\\*.*");
+
+ //
+ // Start file searching for files and directories
+ //
+ if (FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR) == STATUS_SUCCESS) {
+ Done = FALSE;
+ } else {
+ Done = TRUE;
+ }
+
+ //
+ // Now hack the "\*.*" off the end of the filemask so we can use it to pass
+ // the full directory path on recursive calls to process directories.
+ //
+ FileMask[strlen (FileMask) - 4] = 0;
+
+ //
+ // Loop until no more files
+ //
+ while (!Done) {
+ //
+ // printf ("Found %s...", FSData.FileName);
+ //
+ if (FSData.FileFlags & FILE_SEARCH_DIR) {
+ //
+ // printf ("directory\n");
+ //
+ if (!NoSubdirs) {
+ ProcessDirectory (FileMask, FSData.FileName);
+ }
+ } else if (FSData.FileFlags & FILE_SEARCH_FILE) {
+ //
+ // printf ("file\n");
+ //
+ ProcessFile (FileMask, FSData.FileName);
+ } else {
+ //
+ // printf ("unknown\n");
+ //
+ }
+
+ if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) {
+ Done = TRUE;
+ }
+ }
+ //
+ // Free up allocated memory
+ //
+ free (FileMask);
+
+ //
+ // Free up our file searching
+ //
+ FileSearchDestroy (&FSData);
+
+ return STATUS_SUCCESS;
+}
+//
+// Process a single file.
+//
+static
+STATUS
+ProcessFile (
+ INT8 *DirectoryName,
+ INT8 *FileName
+ )
+{
+ STATUS Status;
+ UINT32 FileExtension;
+ INT8 FullFileName[MAX_PATH];
+
+ Status = STATUS_SUCCESS;
+
+ sprintf (FullFileName, "%s\\%s", DirectoryName, FileName);
+ //
+ // printf ("Found file: %s\n", FullFileName);
+ //
+ FileExtension = GetFileExtension (FileName);
+
+ //
+ // Process these for GUID checks
+ //
+ if (gOptions.CheckGuids) {
+ switch (FileExtension) {
+ case FILE_EXTENSION_C:
+ case FILE_EXTENSION_H:
+ Status = ProcessCFileGuids (FullFileName);
+ break;
+
+ case FILE_EXTENSION_PKG:
+ Status = ProcessPkgFileGuids (FullFileName);
+ break;
+
+ case FILE_EXTENSION_IA32_INC:
+ case FILE_EXTENSION_IA32_ASM:
+ Status = ProcessIA32FileGuids (FullFileName);
+ break;
+
+ case FILE_EXTENSION_INF:
+ Status = ProcessINFFileGuids (FullFileName);
+ break;
+
+ case FILE_EXTENSION_IA64_INC:
+ case FILE_EXTENSION_IA64_ASM:
+ Status = ProcessIA64FileGuids (FullFileName);
+ break;
+
+ default:
+ //
+ // No errors anyway
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ }
+
+ if (gOptions.CheckSignatures) {
+ switch (FileExtension) {
+ case FILE_EXTENSION_C:
+ case FILE_EXTENSION_H:
+ Status = ProcessCFileSigs (FullFileName);
+ break;
+
+ default:
+ //
+ // No errors anyway
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ }
+
+ return Status;
+}
+//
+// Return a code indicating the file name extension.
+//
+static
+UINT32
+GetFileExtension (
+ INT8 *FileName
+ )
+{
+ INT8 *Extension;
+ int Index;
+
+ //
+ // Look back for a filename extension
+ //
+ for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) {
+ if (*Extension == '.') {
+ for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) {
+ if (_stricmp (FileTypeTable[Index].Extension, Extension) == 0) {
+ return FileTypeTable[Index].ExtensionCode;
+ }
+ }
+ }
+ }
+
+ return FILE_TYPE_UNKNOWN;
+}
+//
+// Process a .pkg file.
+//
+// Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
+//
+static
+STATUS
+ProcessPkgFileGuids (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN * 2];
+ INT8 *Cptr;
+ INT8 *Cptr2;
+ UINT32 GuidScan[11];
+ UINT64 Guid64;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Read lines from the file until done
+ //
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Line);
+ if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) {
+ Cptr += 12;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr == '=') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr + 1);
+ //
+ // Blank out dashes on the line.
+ //
+ for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
+ if (*Cptr2 == '-') {
+ *Cptr2 = ' ';
+ }
+ }
+
+ if (sscanf (
+ Cptr,
+ "%X %X %X %X %I64X",
+ &GuidScan[0],
+ &GuidScan[1],
+ &GuidScan[2],
+ &GuidScan[3],
+ &Guid64
+ ) == 5) {
+ AddPkgGuid (FileName, GuidScan, &Guid64);
+ } else {
+ DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
+ }
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// Process an IA32 assembly file.
+//
+// Look for:
+// FIND_FD_GUID_VAL equ 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h
+// PEI_GUID_FileNameGuid_Gmch815 equ 081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h
+//
+static
+STATUS
+ProcessIA32FileGuids (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN];
+ INT8 *Cptr;
+ INT8 CSave;
+ INT8 *CSavePtr;
+ UINT32 Len;
+ UINT32 GuidData[16];
+ UINT32 Index;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Read lines from the file until done
+ //
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Line);
+ //
+ // Look for xxxGUIDyyy equ 01h, 02h, 03h, ...
+ //
+ Len = ValidSymbolName (Cptr);
+ if (Len) {
+ //
+ // Terminate the line after the symbol name, then look for "guid" in
+ // the name.
+ //
+ CSavePtr = Cptr + Len;
+ CSave = *CSavePtr;
+ *CSavePtr = 0;
+ while (*Cptr) {
+ if (_strnicmp (Cptr, "guid", 4) == 0) {
+ break;
+ }
+
+ Cptr++;
+ }
+ //
+ // If we found the string "guid", continue
+ //
+ if (*Cptr) {
+ //
+ // Restore the character on the line where we null-terminated the symbol
+ //
+ *CSavePtr = CSave;
+ Cptr = CSavePtr;
+ Len = SkipWhiteSpace (Cptr);
+ //
+ // Had to be some white space
+ //
+ if (Len) {
+ Cptr += Len;
+ //
+ // now look for "equ"
+ //
+ if (_strnicmp (Cptr, "equ", 3) == 0) {
+ Cptr += 3;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Now scan all the data
+ //
+ for (Index = 0; Index < 16; Index++) {
+ if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) {
+ break;
+ }
+ //
+ // Skip to next
+ //
+ while (isxdigit (*Cptr)) {
+ Cptr++;
+ }
+
+ if ((*Cptr != 'h') && (*Cptr != 'H')) {
+ break;
+ } else {
+ Cptr++;
+ while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) {
+ Cptr++;
+ }
+ }
+ }
+ //
+ // Now see which form we had
+ //
+ if (Index == 16) {
+ AddGuid16 (FileName, GuidData);
+ } else if (Index == 11) {
+ AddGuid11 (FileName, GuidData, NULL);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list
+// of guids.
+//
+static
+STATUS
+AddGuid16 (
+ INT8 *FileName,
+ UINT32 *Data
+ )
+{
+ GUID_RECORD *NewRec;
+ int Index;
+
+ //
+ // Sanity check the data
+ //
+ if (!CheckGuidData (Data, 16)) {
+ return STATUS_ERROR;
+ }
+ //
+ // Allocate memory for a new guid structure
+ //
+ NewRec = malloc (sizeof (GUID_RECORD));
+ if (NewRec == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
+ NewRec->FileName = malloc (strlen (FileName) + 1);
+ if (NewRec->FileName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ strcpy (NewRec->FileName, FileName);
+ NewRec->Guid.Data1 = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24));
+ NewRec->Guid.Data2 = (UINT16) (Data[4] | (Data[5] << 8));
+ NewRec->Guid.Data3 = (UINT16) (Data[6] | (Data[7] << 8));
+ for (Index = 0; Index < 8; Index++) {
+ NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8];
+ }
+ //
+ // Add it to the list
+ //
+ NewRec->Next = gGuidList;
+ gGuidList = NewRec;
+
+ //
+ // Report it
+ // ReportGuid (FileName, NewRec);
+ //
+ return STATUS_SUCCESS;
+}
+//
+// Add a GUID defined as GuidLow: 0x1122334455667788
+// GuidHi: 0x99AABBCCDDEEFF00
+//
+// These are equivalent:
+// { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }
+// and:
+// Low: 00FFEEDDCCBBAA99
+// Hi: 7788556611223344
+//
+static
+STATUS
+AddGuid64x2 (
+ INT8 *FileName,
+ UINT32 DataHH, // Upper 32-bits of upper 64 bits of guid
+ UINT32 DataHL, // Lower 32-bits of upper 64 bits
+ UINT32 DataLH,
+ UINT32 DataLL,
+ INT8 *SymName
+ )
+{
+ GUID_RECORD *NewRec;
+ int Index;
+
+ //
+ // Allocate memory for a new guid structure
+ //
+ NewRec = malloc (sizeof (GUID_RECORD));
+ if (NewRec == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
+ NewRec->FileName = malloc (strlen (FileName) + 1);
+ if (NewRec->FileName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ strcpy (NewRec->FileName, FileName);
+ NewRec->Guid.Data1 = DataHL;
+ NewRec->Guid.Data2 = (UINT16) DataHH;
+ NewRec->Guid.Data3 = (UINT16) (DataHH >> 16);
+ for (Index = 0; Index < 4; Index++) {
+ NewRec->Guid.Data4[Index] = (UINT8) DataLL;
+ DataLL >>= 8;
+ }
+
+ for (Index = 0; Index < 4; Index++) {
+ NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH;
+ DataLH >>= 8;
+ }
+
+ if (SymName != NULL) {
+ NewRec->SymName = malloc (strlen (SymName) + 1);
+ if (NewRec->SymName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+ strcpy (NewRec->SymName, SymName);
+ }
+
+ //
+ // Add it to the list
+ //
+ NewRec->Next = gGuidList;
+ gGuidList = NewRec;
+
+ //
+ // Report it
+ // ReportGuid (FileName, NewRec);
+ //
+ return STATUS_SUCCESS;
+}
+//
+// Process INF files. Look for:
+// FILE_GUID = 240612B6-A063-11d4-9A3A-0090273FC14D
+//
+static
+STATUS
+ProcessINFFileGuids (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN * 2];
+ INT8 *Cptr;
+ INT8 *Cptr2;
+ UINT32 GuidScan[11];
+ UINT64 Guid64;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Read lines from the file until done
+ //
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Line);
+ if (strncmp (Cptr, "FILE_GUID", 9) == 0) {
+ Cptr += 9;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr == '=') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr + 1);
+ //
+ // Blank out dashes on the line.
+ //
+ for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
+ if (*Cptr2 == '-') {
+ *Cptr2 = ' ';
+ }
+ }
+
+ if (sscanf (
+ Cptr,
+ "%X %X %X %X %I64X",
+ &GuidScan[0],
+ &GuidScan[1],
+ &GuidScan[2],
+ &GuidScan[3],
+ &Guid64
+ ) == 5) {
+ AddPkgGuid (FileName, GuidScan, &Guid64);
+ } else {
+ DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
+ }
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// Parse ('g','m','a','p','a','b','c','d')
+//
+static
+STATUS
+AddSignature (
+ INT8 *FileName,
+ INT8 *StrDef,
+ UINT32 SigSize
+ )
+{
+ SIGNATURE_RECORD *NewRec;
+ INT8 *Cptr;
+ UINT32 Index;
+ BOOLEAN Fail;
+
+ //
+ // Allocate memory for the new record
+ //
+ Fail = FALSE;
+ NewRec = malloc (sizeof (SIGNATURE_RECORD));
+
+ if (NewRec == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+ memset ((char *) NewRec, 0, sizeof (SIGNATURE_RECORD));
+
+ //
+ // Allocate memory to save the file name
+ //
+ NewRec->FileName = malloc (strlen (FileName) + 1);
+ if (NewRec->FileName == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ free (NewRec);
+ return STATUS_ERROR;
+ }
+ //
+ // Fill in the fields
+ //
+ strcpy (NewRec->FileName, FileName);
+ NewRec->Signature.DataLen = (UINT8) SigSize;
+ //
+ // Skip to open parenthesis
+ //
+ Cptr = StrDef;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr != '(') {
+ Fail = TRUE;
+ goto Done;
+ }
+
+ Cptr++;
+ //
+ // Skip to first ' and start processing
+ //
+ while (*Cptr && (*Cptr != '\'')) {
+ Cptr++;
+ }
+
+ for (Index = 0; Index < SigSize; Index++) {
+ if (*Cptr == '\'') {
+ Cptr++;
+ NewRec->Signature.Data[Index] = (INT8) *Cptr;
+ //
+ // Skip to closing quote
+ //
+ Cptr++;
+ if (*Cptr != '\'') {
+ Fail = TRUE;
+ break;
+ }
+ //
+ // Skip over closing quote, go to next one
+ //
+ Cptr++;
+ while (*Cptr && (*Cptr != '\'')) {
+ Cptr++;
+ }
+ } else {
+ Fail = TRUE;
+ DebugMsg (NULL, 0, 0, FileName, "failed to parse signature");
+ break;
+ }
+ }
+
+Done:
+ if (Fail) {
+ free (NewRec->FileName);
+ free (NewRec);
+ return STATUS_ERROR;
+ }
+
+ NewRec->Next = gSignatureList;
+ gSignatureList = NewRec;
+ return STATUS_SUCCESS;
+}
+//
+// Look for:
+// #define POOL_HEAD_SIGNATURE EFI_SIGNATURE_16('p','h')
+// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('g','m','a','p')
+// #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_64('g','m','a','p','a','b','c','d')
+//
+static
+STATUS
+ProcessCFileSigs (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN * 2];
+ INT8 *Cptr;
+ UINT32 Len;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Read lines from the file until done
+ //
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Line);
+ //
+ // look for #define EFI_SIGNATURE_xx value
+ //
+ if (*Cptr == '#') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Look for "define"
+ //
+ if (!strncmp (Cptr, "define", 6)) {
+ Cptr += 6;
+ //
+ // Better be whitespace
+ //
+ Len = SkipWhiteSpace (Cptr);
+ if (Len) {
+ Cptr += Len;
+ //
+ // See if it's a valid symbol name
+ //
+ Len = ValidSymbolName (Cptr);
+ if (Len) {
+ //
+ // It is a valid symbol name. See if there's line continuation,
+ // and if so, read more lines.
+ // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx"
+ //
+ ConcatenateLines (Fptr, Line, sizeof(Line));
+
+ Cptr += Len;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) {
+ AddSignature (FileName, Cptr + 16, 2);
+ } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) {
+ AddSignature (FileName, Cptr + 16, 4);
+ } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) {
+ AddSignature (FileName, Cptr + 16, 8);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// look for #define xxxGUIDyyy { 0x...}
+// xxx EFI_GUID GuidName = { 0x... };
+//
+static
+STATUS
+ProcessCFileGuids (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN * 2];
+ INT8 *Cptr;
+ INT8 *CSavePtr;
+ INT8 *TempCptr;
+ INT8 *SymName;
+ UINT32 Len;
+ UINT32 LineLen;
+ UINT32 GuidScan[11];
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+ //
+ // Read lines from the file until done
+ //
+ while (fgets (Line, sizeof (Line), Fptr) != NULL) {
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Line);
+ //
+ // look for #define xxxGUIDxxx value
+ //
+ if (*Cptr == '#') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Look for "define"
+ //
+ if (!strncmp (Cptr, "define", 6)) {
+DefineLine:
+ Cptr += 6;
+ //
+ // Better be whitespace
+ //
+ Len = SkipWhiteSpace (Cptr);
+ if (Len) {
+ Cptr += Len;
+ //
+ // See if it's a valid symbol name
+ //
+ Len = ValidSymbolName (Cptr);
+ if (Len) {
+ //
+ // It is a valid symbol name. See if there's line continuation,
+ // and if so, read more lines.
+ // Then truncate after the symbol name, look for the string "GUID",
+ // and continue.
+ //
+ SymName = Cptr;
+ ConcatenateLines (Fptr, Line, sizeof(Line));
+
+ //
+ // Now look for { 0x....... }
+ //
+ CSavePtr = Cptr + Len;
+ Cptr += Len;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr == '{') {
+ Cptr++;
+ //
+ // Blank out 'L', 'l', '{', '}', ',' on the line.
+ //
+ for (TempCptr = Cptr; *TempCptr; TempCptr++) {
+ if ((*TempCptr == 'L') || (*TempCptr == 'l') || (*TempCptr == '{') ||
+ (*TempCptr == '}') || (*TempCptr == ',')) {
+ *TempCptr = ' ';
+ }
+ }
+
+ if (sscanf (
+ Cptr,
+ "%X %X %X %X %X %X %X %X %X %X %X",
+ &GuidScan[0],
+ &GuidScan[1],
+ &GuidScan[2],
+ &GuidScan[3],
+ &GuidScan[4],
+ &GuidScan[5],
+ &GuidScan[6],
+ &GuidScan[7],
+ &GuidScan[8],
+ &GuidScan[9],
+ &GuidScan[10]
+ ) == 11) {
+ *CSavePtr = '\0';
+ AddGuid11 (FileName, GuidScan, SymName);
+ }
+ }
+ }
+ }
+ }
+ //
+ // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... };
+ //
+ } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) {
+ //
+ // Read more lines until met ';'
+ //
+ ConcatenateLines (Fptr, Line, sizeof(Line));
+ while (strstr (Line, ";") == NULL) {
+ LineLen = strlen (Line);
+ Len = sizeof(Line) - LineLen;
+ if (Len <= 1) {
+ break;
+ }
+ if (Line[LineLen - 1] == '\n') {
+ Cptr = Line + LineLen - 1;
+ *Cptr = '\0';
+ if (fgets (Cptr, Len, Fptr) == NULL){
+ break;
+ }
+ ConcatenateLines (Fptr, Line, sizeof(Line));
+ } else {
+ Cptr = Line + LineLen;
+ *Cptr = '\0';
+ if (fgets (Cptr, Len, Fptr) == NULL) {
+ break;
+ }
+ ConcatenateLines (Fptr, Line, sizeof(Line));
+ }
+
+ //
+ // EFI_GUID may appear in comments wihout end of ';' which may cause
+ // ignoring of new #define, so handle it here.
+ //
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr == '#') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (!strncmp (Cptr, "define", 6)) {
+ goto DefineLine;
+ }
+ }
+ }
+
+ Cptr = CSavePtr + 8;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Should be variable name next
+ //
+ Len = ValidSymbolName (Cptr);
+ SymName = Cptr;
+ Cptr += Len;
+ CSavePtr = Cptr;
+ Cptr += SkipWhiteSpace (Cptr);
+ if (*Cptr == '=') {
+ *CSavePtr = '\0';
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Should be open-brace next to define guid
+ //
+ if (*Cptr == '{') {
+ Cptr++;
+ //
+ // Blank out 'L', 'l', '{', '}', ',' on the line.
+ //
+ for (TempCptr = Cptr; *TempCptr; TempCptr++) {
+ if ((*TempCptr == 'L') || (*TempCptr == 'l') || (*TempCptr == '{') ||
+ (*TempCptr == '}') || (*TempCptr == ',')) {
+ *TempCptr = ' ';
+ }
+ }
+
+ if (sscanf (
+ Cptr,
+ "%X %X %X %X %X %X %X %X %X %X %X",
+ &GuidScan[0],
+ &GuidScan[1],
+ &GuidScan[2],
+ &GuidScan[3],
+ &GuidScan[4],
+ &GuidScan[5],
+ &GuidScan[6],
+ &GuidScan[7],
+ &GuidScan[8],
+ &GuidScan[9],
+ &GuidScan[10]
+ ) == 11) {
+ AddGuid11 (FileName, GuidScan, SymName);
+ }
+ }
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// Process Intel Itanium(TM) GUID definitions. Look for:
+// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
+// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
+// in either order.
+// This function assumes no blank lines between definitions.
+//
+static
+STATUS
+ProcessIA64FileGuids (
+ INT8 *FileName
+ )
+{
+ FILE *Fptr;
+ INT8 Line[MAX_LINE_LEN];
+ UINT32 Guid1H;
+ UINT32 Guid1L;
+ UINT32 Guid2H;
+ UINT32 Guid2L;
+ INT8 SymName1[MAX_LINE_LEN];
+ INT8 SymName2[MAX_LINE_LEN];
+ BOOLEAN Done;
+ BOOLEAN LowFirst;
+ BOOLEAN FoundLow;
+
+ if ((Fptr = fopen (FileName, "r")) == NULL) {
+ Error (NULL, 0, 0, FileName, "could not open input file for reading");
+ return STATUS_ERROR;
+ }
+
+ Done = FALSE;
+ if (fgets (Line, sizeof (Line), Fptr) == NULL) {
+ Done = 1;
+ }
+ //
+ // Read lines from the file until done. Since the guid definition takes
+ // two lines, we read lines in different places to recover gracefully
+ // from mismatches. For example, if you thought you found the first half,
+ // but the next line had a symbol mismatch, then you have to process the
+ // line again in case it's the start of a new definition.
+ //
+ while (!Done) {
+ //
+ // Check current line for GUID definition. Assume low define first.
+ //
+ if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) {
+ //
+ // Might have to swap guids later. Save off if we found the LOW first
+ //
+ if (FoundLow) {
+ LowFirst = TRUE;
+ } else {
+ LowFirst = FALSE;
+ }
+ //
+ // Read the next line and try for the rest of the guid definition
+ //
+ if (fgets (Line, sizeof (Line), Fptr) == NULL) {
+ Done = 1;
+ } else {
+ if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) {
+ //
+ // Found another. If the symbol names match, then save it off.
+ //
+ if (strcmp (SymName1, SymName2) == 0) {
+ //
+ // Yea, found one. Save it off.
+ //
+ if (LowFirst) {
+ AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L, SymName1);
+ } else {
+ AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L, SymName1);
+ }
+ //
+ // Read the next line for processing
+ //
+ if (fgets (Line, sizeof (Line), Fptr) == NULL) {
+ Done = 1;
+ }
+ } else {
+ //
+ // Don't get another line so that we reprocess this line in case it
+ // contains the start of a new definition.
+ // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n",
+ // FileName, SymName1, SymName2);
+ //
+ }
+ } else {
+ //
+ // Second line was not a guid definition. Get the next line from the
+ // file.
+ //
+ if (fgets (Line, sizeof (Line), Fptr) == NULL) {
+ Done = 1;
+ }
+ }
+ }
+ } else {
+ //
+ // Not a guid define line. Next.
+ //
+ if (fgets (Line, sizeof (Line), Fptr) == NULL) {
+ Done = 1;
+ }
+ }
+ }
+
+ fclose (Fptr);
+ return STATUS_SUCCESS;
+}
+//
+// Given a line from an Itanium-based assembly file, check the line for a guid
+// defininition. One of either:
+// #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
+// #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
+// Return the defined value as two 32-bit values, and whether it's a high
+// or low guid.
+//
+static
+BOOLEAN
+IsIA64GuidLine (
+ INT8 *Line,
+ UINT32 *GuidHigh,
+ UINT32 *GuidLow,
+ BOOLEAN *FoundLow,
+ INT8 *SymName
+ )
+{
+ INT8 *Cptr;
+ INT8 CSave;
+ INT8 *CSavePtr;
+ INT8 *SymStart;
+ UINT32 Len;
+
+ Cptr = Line;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // look for #define xxxGUID[L|H] 0xHexValue
+ //
+ if (*Cptr == '#') {
+ Cptr++;
+ Cptr += SkipWhiteSpace (Cptr);
+ //
+ // Look for "define"
+ //
+ if (!strncmp (Cptr, "define", 6)) {
+ Cptr += 6;
+ //
+ // Better be whitespace
+ //
+ Len = SkipWhiteSpace (Cptr);
+ if (Len) {
+ Cptr += Len;
+ //
+ // See if it's a valid symbol name
+ //
+ Len = ValidSymbolName (Cptr);
+ if (Len) {
+ //
+ // Save the start so we can copy it to their string if later checks are ok
+ //
+ SymStart = Cptr;
+ //
+ // It is a valid symbol name, look for the string GuidL or GuidH
+ //
+ CSavePtr = Cptr + Len;
+ CSave = *CSavePtr;
+ *CSavePtr = 0;
+ while (*Cptr) {
+ if (strncmp (Cptr, "GuidL", 5) == 0) {
+ *FoundLow = 1;
+ break;
+ } else if (strncmp (Cptr, "GuidH", 5) == 0) {
+ *FoundLow = 0;
+ break;
+ }
+
+ Cptr++;
+ }
+ //
+ // If we didn't run out of string, then we found the GUID string.
+ // Restore the null character we inserted above and continue.
+ // Now look for 0x.......
+ //
+ if (*Cptr) {
+ //
+ // Return symbol name less the "L" or "H"
+ //
+ strcpy (SymName, SymStart);
+ SymName[strlen (SymName) - 1] = 0;
+ Cptr = CSavePtr;
+ *CSavePtr = CSave;
+ Cptr += SkipWhiteSpace (Cptr);
+ if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) {
+ //
+ // skip over "0x"
+ //
+ Cptr += 2;
+ //
+ // 0x0123456789ABCDEF -- null terminate after 8 characters,
+ // scan, replace the character and scan at that point.
+ //
+ CSave = *(Cptr + 8);
+ *(Cptr + 8) = 0;
+ if (sscanf (Cptr, "%X", GuidHigh) == 1) {
+ *(Cptr + 8) = CSave;
+ if (sscanf (Cptr + 8, "%X", GuidLow) == 1) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+//
+// Look at the characters in the string and determine if it's a valid
+// symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]*
+//
+static
+UINT32
+ValidSymbolName (
+ INT8 *Name
+ )
+{
+ int Len;
+
+ Len = 0;
+
+ //
+ // Test first character
+ //
+ if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) {
+ Name++;
+ Len = 1;
+ while (*Name) {
+ if (((*Name >= 'a') && (*Name <= 'z')) ||
+ ((*Name >= 'A') && (*Name <= 'Z')) ||
+ ((*Name >= '0') && (*Name <= '9')) ||
+ (*Name == '_')
+ ) {
+ Name++;
+ Len++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ return Len;
+}
+
+static
+UINT32
+SkipWhiteSpace (
+ INT8 *Str
+ )
+{
+ UINT32 Len;
+ Len = 0;
+ while (isspace (*Str) && *Str) {
+ Len++;
+ Str++;
+ }
+
+ return Len;
+}
+//
+// found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
+//
+static
+STATUS
+AddPkgGuid (
+ INT8 *FileName,
+ UINT32 *Data,
+ UINT64 *Data64
+ )
+{
+ GUID_RECORD *NewRec;
+ int Index;
+
+ //
+ // Sanity check the data
+ //
+ if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) {
+ Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL);
+ return STATUS_ERROR;
+ }
+ //
+ // More checks for Data64?
+ // Allocate memory for a new one guid structure
+ //
+ NewRec = malloc (sizeof (GUID_RECORD));
+ if (NewRec == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
+ NewRec->FileName = malloc (strlen (FileName) + 1);
+ if (NewRec->FileName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ strcpy (NewRec->FileName, FileName);
+ NewRec->Guid.Data1 = Data[0];
+ NewRec->Guid.Data2 = (UINT16) Data[1];
+ NewRec->Guid.Data3 = (UINT16) Data[2];
+ NewRec->Guid.Data4[0] = (UINT8) (Data[3] >> 8);
+ NewRec->Guid.Data4[1] = (UINT8) Data[3];
+ for (Index = 2; Index < 8; Index++) {
+ NewRec->Guid.Data4[Index] = ((UINT8*)Data64)[7-Index];
+ }
+ //
+ // Add it to the list
+ //
+ NewRec->Next = gGuidList;
+ gGuidList = NewRec;
+
+ //
+ // Report it
+ // ReportGuid (FileName, NewRec);
+ //
+ return STATUS_SUCCESS;
+}
+//
+// Add a guid consisting of 11 fields to our list of guids
+//
+static
+STATUS
+AddGuid11 (
+ INT8 *FileName,
+ UINT32 *Data,
+ INT8 *SymName
+ )
+{
+ GUID_RECORD *NewRec;
+ int Index;
+
+ //
+ // Sanity check the data
+ //
+ if (!CheckGuidData (Data, 11)) {
+ return STATUS_ERROR;
+ }
+ //
+ // Allocate memory for a new one guid structure
+ //
+ NewRec = malloc (sizeof (GUID_RECORD));
+ if (NewRec == NULL) {
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
+ NewRec->FileName = malloc (strlen (FileName) + 1);
+ if (NewRec->FileName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+
+ strcpy (NewRec->FileName, FileName);
+ if (SymName != NULL) {
+ NewRec->SymName = malloc (strlen (SymName) + 1);
+ if (NewRec->SymName == NULL) {
+ free (NewRec);
+ Error (NULL, 0, 0, "memory allocation failure", NULL);
+ return STATUS_ERROR;
+ }
+ strcpy (NewRec->SymName, SymName);
+ }
+
+ NewRec->Guid.Data1 = Data[0];
+ NewRec->Guid.Data2 = (UINT16) Data[1];
+ NewRec->Guid.Data3 = (UINT16) Data[2];
+ for (Index = 0; Index < 8; Index++) {
+ NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index];
+ }
+ //
+ // Add it to the list
+ //
+ NewRec->Next = gGuidList;
+ gGuidList = NewRec;
+
+ //
+ // Report it
+ // ReportGuid (FileName, NewRec);
+ //
+ return STATUS_SUCCESS;
+}
+//
+// For debug purposes, print each guid found
+//
+// static
+// VOID
+// ReportGuid (
+// INT8 *FileName,
+// GUID_RECORD *NewGuid
+// )
+// {
+// //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1);
+// }
+//
+// Free up memory we allocated to keep track of guids defined.
+//
+static
+VOID
+FreeGuids (
+ VOID
+ )
+{
+ GUID_RECORD *NextRec;
+ while (gGuidList != NULL) {
+ NextRec = gGuidList->Next;
+ if (gGuidList->FileName != NULL) {
+ free (gGuidList->FileName);
+ }
+
+ if (gGuidList->SymName != NULL) {
+ free (gGuidList->SymName);
+ }
+
+ free (gGuidList);
+ gGuidList = NextRec;
+ }
+}
+
+static
+VOID
+FreeSigs (
+ VOID
+ )
+{
+ SIGNATURE_RECORD *NextRec;
+ while (gSignatureList != NULL) {
+ NextRec = gSignatureList->Next;
+ if (gSignatureList->FileName != NULL) {
+ free (gSignatureList->FileName);
+ }
+
+ free (gSignatureList);
+ gSignatureList = NextRec;
+ }
+}
+//
+// Scan through all guids defined and compare each for duplicates.
+//
+static
+STATUS
+CheckDuplicates (
+ VOID
+ )
+{
+ GUID_RECORD *CurrentFile;
+
+ GUID_RECORD *TempFile;
+ SIGNATURE_RECORD *CurrentSig;
+ SIGNATURE_RECORD *TempSig;
+ STATUS Status;
+ int Index;
+ int DupCount;
+ int Len;
+ BOOLEAN Same;
+ UINT32 GuidSum;
+ INT8 *SymName;
+
+ Status = STATUS_SUCCESS;
+
+ //
+ // If we're checking guids.....
+ //
+ if (gOptions.CheckGuids) {
+ //
+ // If -p option, print all guids found
+ //
+ if (gOptions.PrintFound) {
+ CurrentFile = gGuidList;
+ while (CurrentFile != NULL) {
+ fprintf (
+ stdout,
+ "GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X %s\n",
+ (UINT32) CurrentFile->Guid.Data1,
+ (UINT32) CurrentFile->Guid.Data2,
+ (UINT32) CurrentFile->Guid.Data3,
+ (UINT32) CurrentFile->Guid.Data4[0],
+ (UINT32) CurrentFile->Guid.Data4[1],
+ (UINT32) CurrentFile->Guid.Data4[2],
+ (UINT32) CurrentFile->Guid.Data4[3],
+ (UINT32) CurrentFile->Guid.Data4[4],
+ (UINT32) CurrentFile->Guid.Data4[5],
+ (UINT32) CurrentFile->Guid.Data4[6],
+ (UINT32) CurrentFile->Guid.Data4[7],
+ CurrentFile->FileName
+ );
+ CurrentFile = CurrentFile->Next;
+ }
+ }
+
+ if (gOptions.GuidXReference) {
+ CurrentFile = gGuidList;
+ while (CurrentFile != NULL) {
+ //
+ // If no symbol name, print FileName
+ //
+ SymName = CurrentFile->SymName;
+ if (SymName == NULL) {
+ //
+ // Assume file name will not be NULL and strlen > 0
+ //
+ SymName = CurrentFile->FileName + strlen (CurrentFile->FileName) - 1;
+ while ((*SymName != '\\') && (SymName > CurrentFile->FileName)) SymName --;
+ if (*SymName == '\\') SymName ++;
+ }
+
+ fprintf (
+ stdout,
+ "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n",
+ (UINT32) CurrentFile->Guid.Data1,
+ (UINT32) CurrentFile->Guid.Data2,
+ (UINT32) CurrentFile->Guid.Data3,
+ (UINT32) CurrentFile->Guid.Data4[0],
+ (UINT32) CurrentFile->Guid.Data4[1],
+ (UINT32) CurrentFile->Guid.Data4[2],
+ (UINT32) CurrentFile->Guid.Data4[3],
+ (UINT32) CurrentFile->Guid.Data4[4],
+ (UINT32) CurrentFile->Guid.Data4[5],
+ (UINT32) CurrentFile->Guid.Data4[6],
+ (UINT32) CurrentFile->Guid.Data4[7],
+ SymName
+ );
+ CurrentFile = CurrentFile->Next;
+ }
+ }
+ //
+ // Now go through all guids and report duplicates.
+ //
+ CurrentFile = gGuidList;
+ while (CurrentFile != NULL) {
+ DupCount = 0;
+ TempFile = CurrentFile->Next;
+ while (TempFile) {
+ //
+ // Compare the guids
+ //
+ if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) &&
+ (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) &&
+ (CurrentFile->Guid.Data3 == TempFile->Guid.Data3)
+ ) {
+ //
+ // OR in all the guid bytes so we can ignore NULL-guid definitions.
+ //
+ GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3;
+ Same = TRUE;
+ for (Index = 0; Index < 8; Index++) {
+ GuidSum |= CurrentFile->Guid.Data4[Index];
+ if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) {
+ Same = FALSE;
+ break;
+ }
+ }
+ //
+ // If they're the same, and the guid was non-zero, print a message.
+ //
+ if (Same && GuidSum) {
+ if (DupCount == 0) {
+ Error (NULL, 0, 0, "duplicate GUIDS found", NULL);
+ fprintf (stdout, " FILE1: %s\n", CurrentFile->FileName);
+ }
+
+ DupCount++;
+ fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempFile->FileName);
+ //
+ // Flag it as reported so we don't report it again if there's three or more
+ //
+ TempFile->Reported = TRUE;
+ }
+ }
+ //
+ // Next one
+ //
+ TempFile = TempFile->Next;
+ }
+ //
+ // Print the guid if we found duplicates
+ //
+ if (DupCount) {
+ fprintf (
+ stdout,
+ " GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
+ (UINT32) CurrentFile->Guid.Data1,
+ (UINT32) CurrentFile->Guid.Data2,
+ (UINT32) CurrentFile->Guid.Data3,
+ (UINT32) CurrentFile->Guid.Data4[0],
+ (UINT32) CurrentFile->Guid.Data4[1],
+ (UINT32) CurrentFile->Guid.Data4[2],
+ (UINT32) CurrentFile->Guid.Data4[3],
+ (UINT32) CurrentFile->Guid.Data4[4],
+ (UINT32) CurrentFile->Guid.Data4[5],
+ (UINT32) CurrentFile->Guid.Data4[6],
+ (UINT32) CurrentFile->Guid.Data4[7]
+ );
+ //
+ // return STATUS_ERROR;
+ //
+ }
+ //
+ // Find the next one that hasn't been reported
+ //
+ do {
+ CurrentFile = CurrentFile->Next;
+ } while ((CurrentFile != NULL) && (CurrentFile->Reported));
+ }
+ }
+
+ if (gOptions.CheckSignatures) {
+ //
+ // Print ones found if specified
+ //
+ if (gOptions.PrintFound) {
+ CurrentSig = gSignatureList;
+ while (CurrentSig != NULL) {
+ Len = CurrentSig->Signature.DataLen;
+ for (Index = 0; Index < Len; Index++) {
+ fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
+ }
+
+ fprintf (stdout, " %s\n", CurrentSig->FileName);
+ CurrentSig = CurrentSig->Next;
+ }
+ }
+
+ CurrentSig = gSignatureList;
+ while (CurrentSig != NULL) {
+ DupCount = 0;
+ TempSig = CurrentSig->Next;
+ Len = CurrentSig->Signature.DataLen;
+ while (TempSig) {
+ //
+ // Check for same length, then do string compare
+ //
+ if (Len == TempSig->Signature.DataLen) {
+ if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) {
+ //
+ // Print header message if first failure for this sig
+ //
+ if (DupCount == 0) {
+ Error (NULL, 0, 0, "duplicate signatures found", NULL);
+ fprintf (stdout, " FILE1: %s\n", CurrentSig->FileName);
+ }
+
+ DupCount++;
+ fprintf (stdout, " FILE%d: %s\n", DupCount + 1, TempSig->FileName);
+ TempSig->Reported = TRUE;
+ }
+ }
+
+ TempSig = TempSig->Next;
+ }
+
+ if (DupCount) {
+ fprintf (stdout, " SIG: ");
+ for (Index = 0; Index < Len; Index++) {
+ fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
+ }
+
+ fprintf (stdout, "\n");
+ }
+ //
+ // On to the next one that hasn't been reported
+ //
+ do {
+ CurrentSig = CurrentSig->Next;
+ } while ((CurrentSig != NULL) && (CurrentSig->Reported));
+ }
+ }
+
+ return Status;
+}
+
+static
+VOID
+FreeOptions (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Free up any memory we allocated when processing command-line options.
+
+Arguments:
+ None.
+
+Returns:
+ NA
+
+Notes:
+ We don't free up the ->Str fields because we did not allocate them.
+ Instead, we just set the pointer to point to the actual parameter
+ from the command line.
+
+--*/
+{
+ STRING_LIST *Ptr;
+ while (gOptions.ExcludeDirs != NULL) {
+ Ptr = gOptions.ExcludeDirs->Next;
+ //
+ // free (gOptions.ExcludeDirs->Str);
+ //
+ free (gOptions.ExcludeDirs);
+ gOptions.ExcludeDirs = Ptr;
+ }
+
+ while (gOptions.ExcludeSubDirs != NULL) {
+ Ptr = gOptions.ExcludeSubDirs->Next;
+ //
+ // free (gOptions.ExcludeSubDirs->Str);
+ //
+ free (gOptions.ExcludeSubDirs);
+ gOptions.ExcludeSubDirs = Ptr;
+ }
+
+ while (gOptions.ExcludeExtensions != NULL) {
+ Ptr = gOptions.ExcludeExtensions->Next;
+ //
+ // free (gOptions.ExcludeExtensions->Str);
+ //
+ free (gOptions.ExcludeExtensions);
+ gOptions.ExcludeExtensions = Ptr;
+ }
+
+ while (gOptions.ExcludeFiles != NULL) {
+ Ptr = gOptions.ExcludeFiles->Next;
+ //
+ // free (gOptions.ExcludeFiles->Str);
+ //
+ free (gOptions.ExcludeFiles);
+ gOptions.ExcludeFiles = Ptr;
+ }
+}
+//
+// Given an array of 32-bit data, validate the data for the given number of
+// guid data. For example, it might have been scanned as 16 bytes of data, or
+// 11 fields of data.
+//
+static
+BOOLEAN
+CheckGuidData (
+ UINT32 *Data,
+ UINT32 DataCount
+ )
+{
+ UINT32 Index;
+
+ if (DataCount == 16) {
+ for (Index = 0; Index < 16; Index++) {
+ if (Data[Index] &~0xFF) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ } else if (DataCount == 11) {
+ //
+ // Data[0] never out of range (32-bit)
+ //
+ if ((Data[1] | Data[2]) &~0xFFFF) {
+ //
+ // Error ("Out of range value for GUID data word(s) [1] and/or [2]");
+ //
+ return FALSE;
+ }
+
+ for (Index = 0; Index < 8; Index++) {
+ if (Data[Index + 3] &~0xFF) {
+ //
+ // Error ("Out of range value for GUID data byte(s) [4] - [11]");
+ //
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static
+VOID
+ConcatenateLines (
+ FILE *Fptr,
+ INT8 *Line,
+ UINT32 Len
+ )
+{
+ UINT32 LineLen;
+ BOOLEAN NeedCheck;
+
+ NeedCheck = TRUE;
+ while (NeedCheck) {
+ LineLen = strlen (Line);
+ if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {
+ Line[LineLen - 2] = '\0';
+ fgets (Line + LineLen - 2, Len - LineLen, Fptr);
+ } else if (Line[LineLen - 1] == '\\') {
+ Line[LineLen - 1] = '\0';
+ fgets (Line + LineLen - 1, Len - LineLen, Fptr);
+ } else {
+ NeedCheck = FALSE;
+ }
+ }
+} \ No newline at end of file