From 28305207ea586d0b5ceb530b0e2a436cad9fdd8f Mon Sep 17 00:00:00 2001 From: lhauch Date: Thu, 5 Oct 2006 23:16:50 +0000 Subject: More renames for Tool Packages git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1675 6f19259b-4bc3-4df7-8a09-765794883524 --- Tools/CodeTools/Source/GuidChk/CommonUtils.h | 57 + Tools/CodeTools/Source/GuidChk/FileSearch.c | 285 ++++ Tools/CodeTools/Source/GuidChk/FileSearch.h | 108 ++ Tools/CodeTools/Source/GuidChk/GuidChk.c | 2348 ++++++++++++++++++++++++++ Tools/CodeTools/Source/GuidChk/GuidList.c | 186 ++ Tools/CodeTools/Source/GuidChk/UtilsMsgs.c | 490 ++++++ Tools/CodeTools/Source/GuidChk/UtilsMsgs.h | 106 ++ Tools/CodeTools/Source/GuidChk/build.xml | 84 + 8 files changed, 3664 insertions(+) create mode 100644 Tools/CodeTools/Source/GuidChk/CommonUtils.h create mode 100644 Tools/CodeTools/Source/GuidChk/FileSearch.c create mode 100644 Tools/CodeTools/Source/GuidChk/FileSearch.h create mode 100644 Tools/CodeTools/Source/GuidChk/GuidChk.c create mode 100644 Tools/CodeTools/Source/GuidChk/GuidList.c create mode 100644 Tools/CodeTools/Source/GuidChk/UtilsMsgs.c create mode 100644 Tools/CodeTools/Source/GuidChk/UtilsMsgs.h create mode 100644 Tools/CodeTools/Source/GuidChk/build.xml (limited to 'Tools/CodeTools/Source/GuidChk') diff --git a/Tools/CodeTools/Source/GuidChk/CommonUtils.h b/Tools/CodeTools/Source/GuidChk/CommonUtils.h new file mode 100644 index 0000000000..f7a331e5d7 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/CommonUtils.h @@ -0,0 +1,57 @@ +/*++ + +Copyright (c) 2004, 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: + + CommonUtils.h + +Abstract: + + Common utility defines and structure definitions. + +--*/ + +#ifndef _COMMON_UTILS_H_ +#define _COMMON_UTILS_H_ + +// +// Basic types +// +typedef unsigned char UINT8; +typedef char INT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; + +typedef UINT8 BOOLEAN; +typedef UINT32 STATUS; + +#define TRUE 1 +#define FALSE 0 + +#define STATUS_SUCCESS 0 +#define STATUS_WARNING 1 +#define STATUS_ERROR 2 + +// +// Linked list of strings +// +typedef struct _STRING_LIST { + struct _STRING_LIST *Next; + char *Str; +} STRING_LIST; + +int +CreateGuidList ( + INT8 *OutFileName + ) +; + +#endif // #ifndef _COMMON_UTILS_H_ diff --git a/Tools/CodeTools/Source/GuidChk/FileSearch.c b/Tools/CodeTools/Source/GuidChk/FileSearch.c new file mode 100644 index 0000000000..8b5b58fddf --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/FileSearch.c @@ -0,0 +1,285 @@ +/*++ + +Copyright (c) 2004, 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: + + FileSearch.c + +Abstract: + + Module used to support file searches on the system. + +--*/ + +#include + +#include "CommonUtils.h" +#include "FileSearch.h" +#include "UtilsMsgs.h" + +// +// Internal file search flag for sanity checks +// +#define FILE_SEARCH_STARTED 0x8000 +#define FILE_SEARCH_INITED 0x4000 + +static +BOOLEAN +FileSearchMeetsCriteria ( + FILE_SEARCH_DATA *FSData + ); + +/*****************************************************************************/ +STATUS +FileSearchInit ( + FILE_SEARCH_DATA *FSData + ) +{ + memset ((char *) FSData, 0, sizeof (FILE_SEARCH_DATA)); + FSData->Handle = INVALID_HANDLE_VALUE; + FSData->FileSearchFlags = FILE_SEARCH_INITED; + FSData->FileName[0] = 0; + return STATUS_SUCCESS; +} + +STATUS +FileSearchStart ( + FILE_SEARCH_DATA *FSData, + char *FileMask, + UINT32 SearchFlags + ) +{ + BOOLEAN Done; + + // + // Save their flags, and set a flag to indicate that they called this + // start function so we can perform extended checking in the other + // routines we have in this module. + // + FSData->FileSearchFlags |= (SearchFlags | FILE_SEARCH_STARTED); + FSData->FileName[0] = 0; + + // + // Begin the search + // + FSData->Handle = FindFirstFile (FileMask, &(FSData->FindData)); + if (FSData->Handle == INVALID_HANDLE_VALUE) { + return STATUS_ERROR; + } + // + // Keep looping through until we find a file meeting the caller's + // criteria per the search flags + // + Done = FALSE; + while (!Done) { + // + // If we're done (we found a match) copy the file name found and return + // + Done = FileSearchMeetsCriteria (FSData); + if (Done) { + return STATUS_SUCCESS; + } + // + // Go on to next file + // + if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { + return STATUS_NOT_FOUND; + } + } + // + // Not reached + // + return STATUS_NOT_FOUND; +} + +// +// Find the next file meeting their criteria and return it. +// +STATUS +FileSearchFindNext ( + FILE_SEARCH_DATA *FSData + ) +{ + BOOLEAN Done; + + Done = FALSE; + while (!Done) { + if (!FindNextFile (FSData->Handle, &(FSData->FindData))) { + return STATUS_NOT_FOUND; + } + // + // See if it matches their criteria + // + Done = FileSearchMeetsCriteria (FSData); + if (Done) { + return STATUS_SUCCESS; + } + } + // + // Not reached + // + return STATUS_NOT_FOUND; +} +// +// Perform any cleanup necessary to close down a search +// +STATUS +FileSearchDestroy ( + FILE_SEARCH_DATA *FSData + ) +{ + if (FSData->Handle != INVALID_HANDLE_VALUE) { + FindClose (FSData->Handle); + FSData->Handle = INVALID_HANDLE_VALUE; + } + + FSData->FileName[0] = 0; + FSData->FileSearchFlags = 0; + return STATUS_SUCCESS; +} + +static +BOOLEAN +FileSearchMeetsCriteria ( + FILE_SEARCH_DATA *FSData + ) +{ + BOOLEAN Status; + STRING_LIST *StrList; + UINT32 ExtLen; + UINT32 FileNameLen; + + Status = FALSE; + + // + // First clear the flag indicating this is neither a file or a + // directory. + // + FSData->FileFlags &= ~(FILE_SEARCH_DIR | FILE_SEARCH_FILE); + + // + // We found a file. See if it matches the user's search criteria. First + // check for this being a directory, and they want directories, and + // it's not "." and it's not ".." + // + if ((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + (FSData->FileSearchFlags & FILE_SEARCH_DIR) && + (strcmp (FSData->FindData.cFileName, ".")) && + (strcmp (FSData->FindData.cFileName, "..")) + ) { + // + // Assume we'll make it past this check + // + Status = TRUE; + // + // If they have a list of exclude directories, then check for those + // + StrList = FSData->ExcludeDirs; + while (StrList != NULL) { + if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + // + // If we didn't fail due to excluded directories, then set the dir flag + // + if (Status) { + FSData->FileFlags |= FILE_SEARCH_DIR; + } + // + // Else check for a file, and they want files.... + // + } else if (((FSData->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) && + (FSData->FileSearchFlags & FILE_SEARCH_FILE) + ) { + // + // See if it's in our list of excluded files + // + Status = TRUE; + StrList = FSData->ExcludeFiles; + while (StrList != NULL) { + if (stricmp (FSData->FindData.cFileName, StrList->Str) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + + if (Status) { + // + // See if it's in our list of excluded file extensions + // + FileNameLen = strlen (FSData->FindData.cFileName); + StrList = FSData->ExcludeExtensions; + while (StrList != NULL) { + ExtLen = strlen (StrList->Str); + if (stricmp ( + FSData->FindData.cFileName + FileNameLen - ExtLen, + StrList->Str + ) == 0) { + Status = FALSE; + break; + } + + StrList = StrList->Next; + } + } + + if (Status) { + FSData->FileFlags |= FILE_SEARCH_FILE; + } + } + // + // If it's a match, copy the filename into another field of the structure + // for portability. + // + if (Status) { + strcpy (FSData->FileName, FSData->FindData.cFileName); + } + + return Status; +} +// +// Exclude a list of subdirectories. +// +STATUS +FileSearchExcludeDirs ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeDirs = StrList; + return STATUS_SUCCESS; +} + +STATUS +FileSearchExcludeFiles ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeFiles = StrList; + return STATUS_SUCCESS; +} + +STATUS +FileSearchExcludeExtensions ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +{ + FSData->ExcludeExtensions = StrList; + return STATUS_SUCCESS; +} diff --git a/Tools/CodeTools/Source/GuidChk/FileSearch.h b/Tools/CodeTools/Source/GuidChk/FileSearch.h new file mode 100644 index 0000000000..bc40265366 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/FileSearch.h @@ -0,0 +1,108 @@ +/*++ + +Copyright (c) 2004, 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: + + FileSearch.h + +Abstract: + + Header file to support file searching. + +--*/ + +#ifndef _FILE_SEARCH_H_ +#define _FILE_SEARCH_H_ + +// +// Since the file searching routines are OS dependent, put the +// necessary include paths in this header file so that the non-OS-dependent +// files don't need to include these windows-specific header files. +// +#include +#include +#include +#include +#include + +// +// Return codes of some of the file search routines +// +#define STATUS_NOT_FOUND 0x1000 + +// +// Flags for what to search for. Also used in the FileFlags return field. +// +#define FILE_SEARCH_DIR 0x0001 +#define FILE_SEARCH_FILE 0x0002 + +// +// Here's our class definition +// +typedef struct { + HANDLE Handle; + WIN32_FIND_DATA FindData; + UINT32 FileSearchFlags; // DIRS, FILES, etc + UINT32 FileFlags; + INT8 FileName[MAX_PATH]; // for portability + STRING_LIST *ExcludeDirs; + STRING_LIST *ExcludeFiles; + STRING_LIST *ExcludeExtensions; +} FILE_SEARCH_DATA; + +// +// Here's our member functions +// +STATUS +FileSearchInit ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchDestroy ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchStart ( + FILE_SEARCH_DATA *FSData, + char *FileMask, + UINT32 SearchFlags + ) +; + +STATUS +FileSearchFindNext ( + FILE_SEARCH_DATA *FSData + ) +; + +STATUS +FileSearchExcludeDirs ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +STATUS +FileSearchExcludeExtensions ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +STATUS +FileSearchExcludeFiles ( + FILE_SEARCH_DATA *FSData, + STRING_LIST *StrList + ) +; +#endif diff --git a/Tools/CodeTools/Source/GuidChk/GuidChk.c b/Tools/CodeTools/Source/GuidChk/GuidChk.c new file mode 100644 index 0000000000..de88405872 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/GuidChk.c @@ -0,0 +1,2348 @@ +/*++ + +Copyright (c) 2004, 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 +#include +#include +#include + +#include "CommonUtils.h" +#include "FileSearch.h" +#include "UtilsMsgs.h" + +#define MAX_LINE_LEN 180 // we concatenate two lines sometimes +// Define a structure that correlates filename extensions to an enumerated +// type. +// +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[4]; + 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 + ); + +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 + ); + +/**************************** 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 = 1; + 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 + // + FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR); + + // + // 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 + // + Done = FALSE; + 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 + ) +{ + 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; + } + // + // 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; + } + // + // 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, StrDef, "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; + UINT32 LineLen; + + 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)) { + 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 a line continuation, + // and if so, read one more line. + // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx" + // + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + 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 CSave; + 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)) { + 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 a line continuation, + // and if so, read one more line. + // Then truncate after the symbol name, look for the string "GUID", + // and continue. + // + SymName = Cptr; + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + CSavePtr = Cptr + Len; + CSave = *CSavePtr; + *CSavePtr = 0; + while (*Cptr) { + if (strncmp (Cptr, "GUID", 4) == 0) { + break; + } + + Cptr++; + } + // + // If we didn't run out of string, then we found the GUID string. + // Now look for { 0x....... } + // + if (*Cptr) { + Cptr = CSavePtr; + *CSavePtr = CSave; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '{') { + *Cptr = 0; + Cptr++; + // + // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters + // in the string. + // + for (TempCptr = Cptr; *TempCptr; TempCptr++) { + if (*TempCptr == 'L') { + if (*(TempCptr + 1) == ',') { + *TempCptr = ','; + *(TempCptr + 1) = ' '; + } + } + } + + 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); + } + } + } + } + } + } + // + // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... }; + // + } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) { + // + // Read the next line if line continuation + // + LineLen = strlen (Line); + if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) { + fgets (Line + LineLen - 2, sizeof (Line) - LineLen, Fptr); + } else if (Line[LineLen - 1] == '\\') { + fgets (Line + LineLen - 1, sizeof (Line) - LineLen, Fptr); + } + + Cptr = CSavePtr + 8; + Cptr += SkipWhiteSpace (Cptr); + // + // Should be variable name next + // + Len = ValidSymbolName (Cptr); + SymName = Cptr; + Cptr += Len; + Cptr += SkipWhiteSpace (Cptr); + if (*Cptr == '=') { + Cptr++; + Cptr += SkipWhiteSpace (Cptr); + // + // Should be open-brace next to define guid + // + if (*Cptr == '{') { + Cptr++; + // + // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } + // + 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, Cptr); + // + // printf ("Found guid: %s", Cptr); + // + } + } + } + } + } + + 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); + } else { + AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L); + } + // + // 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]; + NewRec->Guid.Data4[1] = (UINT8) (Data[3] >> 8); + for (Index = 2; Index < 8; Index++) { + NewRec->Guid.Data4[Index] = (UINT8) *Data64; + *Data64 >>= 8; + } + // + // 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 "unknown" + // + SymName = CurrentFile->SymName; + if (SymName == NULL) { + SymName = "unknown"; + } + + 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; +} diff --git a/Tools/CodeTools/Source/GuidChk/GuidList.c b/Tools/CodeTools/Source/GuidChk/GuidList.c new file mode 100644 index 0000000000..bb6a44d85e --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/GuidList.c @@ -0,0 +1,186 @@ +/*++ + +Copyright (c) 2004, 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: + + GuidList.c + +Abstract: + + Utility to create a GUID-to-name listing file that can + be used by other utilities. Basic operation is to take the + table of name+GUIDs that we have compiled into this utility, + and create a text file that can be parsed by other utilities + to do replacement of "name" with "GUID". + +Notes: + To add a new GUID to this database: + 1. Add a "#include EFI_GUID_DEFINITION(name)" statement below + 2. Modify the mGuidList[] array below to add the new GUID name + + The only issue that may come up is that, if the source GUID file + is not in the standard GUID directory, then this utility won't + compile because the #include fails. In this case you'd need + to define a new macro (if it's in a standard place) or modify + this utility's makefile to add the path to your new .h file. + +--*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include "EfiUtilityMsgs.h" + + +#define GUID_XREF(varname, guid) { \ + #varname, #guid, guid \ + } + +#define NULL_GUID \ + { \ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 \ + } + +typedef struct { + INT8 *VariableName; + INT8 *DefineName; + EFI_GUID Guid; +} GUID_LIST; + +// +// This is our table of all GUIDs we want to print out to create +// a GUID-to-name cross reference. +// Use the #defined name from the GUID definition's source .h file. +// +static GUID_LIST mGuidList[] = { + GUID_XREF(gAprioriGuid, EFI_APRIORI_GUID), + GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), + // FIXME The next line was removed in the port to R9. + // GUID_XREF(gEfiDefaultBmpLogoGuid, EFI_DEFAULT_BMP_LOGO_GUID), + GUID_XREF(gEfiAcpiTableStorageGuid, EFI_ACPI_TABLE_STORAGE_GUID), + // + // Terminator + // + { + NULL, + NULL, + NULL_GUID + } +}; + +void +PrintGuidText ( + FILE *OutFptr, + INT8 *VariableName, + INT8 *DefineName, + EFI_GUID *Guid + ); + +int +CreateGuidList ( + INT8 *OutFileName + ) +/*++ + +Routine Description: + Print our GUID/name list to the specified output file. + +Arguments: + OutFileName - name of the output file to write our results to. + +Returns: + 0 if successful + nonzero otherwise + +--*/ +{ + FILE *OutFptr; + int Index; + + // + // Open output file for writing. If the name is NULL, then write to stdout + // + if (OutFileName != NULL) { + OutFptr = fopen (OutFileName, "w"); + if (OutFptr == NULL) { + Error (NULL, 0, 0, OutFileName, "failed to open output file for writing"); + return STATUS_ERROR; + } + } else { + OutFptr = stdout; + } + + for (Index = 0; mGuidList[Index].VariableName != NULL; Index++) { + PrintGuidText (OutFptr, mGuidList[Index].VariableName, mGuidList[Index].DefineName, &mGuidList[Index].Guid); + } + // + // Close the output file if they specified one. + // + if (OutFileName != NULL) { + fclose (OutFptr); + } + + return STATUS_SUCCESS; +} + +void +PrintGuidText ( + FILE *OutFptr, + INT8 *VariableName, + INT8 *DefineName, + EFI_GUID *Guid + ) +/*++ + +Routine Description: + Print a GUID/name combo in INF-style format + + guid-guid-guid-guid DEFINE_NAME gName + +Arguments: + OutFptr - file pointer to which to write the output + VariableName - the GUID variable's name + DefineName - the name used in the #define + Guid - pointer to the GUID value + +Returns: + NA + +--*/ +{ + if (OutFptr == NULL) { + OutFptr = stdout; + } + + fprintf ( + OutFptr, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s %s\n", + Guid->Data1, + Guid->Data2, + Guid->Data3, + Guid->Data4[0], + Guid->Data4[1], + Guid->Data4[2], + Guid->Data4[3], + Guid->Data4[4], + Guid->Data4[5], + Guid->Data4[6], + Guid->Data4[7], + DefineName, + VariableName + ); +} diff --git a/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c new file mode 100644 index 0000000000..8aa343fc19 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.c @@ -0,0 +1,490 @@ +/*++ + +Copyright (c) 2004, 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: + + UtilsMsgs.c + +Abstract: + + EFI tools utility functions to display warning, error, and informational + messages. + +--*/ + +#include +#include +#include +#include + +#include + +#include "EfiUtilityMsgs.h" + +#define MAX_LINE_LEN 200 + +// +// Declare module globals for keeping track of the the utility's +// name and other settings. +// +static STATUS mStatus = STATUS_SUCCESS; +static INT8 mUtilityName[50] = { 0 }; +static INT8 *mSourceFileName = NULL; +static UINT32 mSourceFileLineNum = 0; +static UINT32 mErrorCount = 0; +static UINT32 mWarningCount = 0; +static UINT32 mDebugMsgMask = 0; + +static +void +PrintMessage ( + INT8 *Type, + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + va_list List + ); + +void +Error ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Prints an error message. + +Arguments: + All arguments are optional, though the printed message may be useless if + at least something valid is not specified. + + FileName - name of the file or application. If not specified, then the + utilty name (as set by the utility calling SetUtilityName() + earlier) is used. Otherwise "Unknown utility" is used. + + LineNumber - the line number of error, typically used by parsers. If the + utility is not a parser, then 0 should be specified. Otherwise + the FileName and LineNumber info can be used to cause + MS Visual Studio to jump to the error. + + MessageCode - an application-specific error code that can be referenced in + other documentation. + + Text - the text in question, typically used by parsers. + + MsgFmt - the format string for the error message. Can contain formatting + controls for use with the varargs. + +Returns: + None. + +Notes: + We print the following (similar to the Warn() and Debug() + W + Typical error/warning message format: + + bin\VfrCompile.cpp(330) : error C2660: 'AddVfrDataStructField' : function does not take 2 parameters + + BUGBUG -- these three utility functions are almost identical, and + should be modified to share code. + + Visual Studio does not find error messages with: + + " error :" + " error 1:" + " error c1:" + " error 1000:" + " error c100:" + + It does find: + " error c1000:" +--*/ +{ + va_list List; + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserError ( + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser error, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + MessageCode - application-specific error code + Text - text to print in the error message + MsgFmt - format string to print at the end of the error message + ... + +Returns: + NA + +--*/ +{ + va_list List; + mErrorCount++; + va_start (List, MsgFmt); + PrintMessage ("error", mSourceFileName, mSourceFileLineNum, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_ERROR) { + mStatus = STATUS_ERROR; + } +} + +void +ParserWarning ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a parser warning, using the source file name and line number + set by a previous call to SetParserPosition(). + +Arguments: + ErrorCode - application-specific error code + OffendingText - text to print in the warning message + MsgFmt - format string to print at the end of the warning message + ... + +Returns: + NA + +--*/ +{ + va_list List; + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", mSourceFileName, mSourceFileLineNum, ErrorCode, OffendingText, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +Warning ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - the text in question (parsers) + + MsgFmt - the format string for the warning message. Can contain formatting + controls for use with varargs. + + ... + +Returns: + None. + +--*/ +{ + va_list List; + mWarningCount++; + va_start (List, MsgFmt); + PrintMessage ("warning", FileName, LineNumber, MessageCode, Text, MsgFmt, List); + va_end (List); + // + // Set status accordingly + // + if (mStatus < STATUS_WARNING) { + mStatus = STATUS_WARNING; + } +} + +void +DebugMsg ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MsgMask, + INT8 *Text, + INT8 *MsgFmt, + ... + ) +/*++ + +Routine Description: + Print a warning message. + +Arguments: + FileName - typically the name of the utility printing the debug message, but + can be the name of a file being parsed. + + LineNumber - the line number in FileName (parsers) + + MsgMask - an application-specific bitmask that, in combination with mDebugMsgMask, + determines if the debug message gets printed. + + Text - the text in question (parsers) + + MsgFmt - the format string for the debug message. Can contain formatting + controls for use with varargs. + + ... +Returns: + None. + +--*/ +{ + va_list List; + // + // If the debug mask is not applicable, then do nothing. + // + if ((MsgMask != 0) && ((mDebugMsgMask & MsgMask) == 0)) { + return ; + } + + va_start (List, MsgFmt); + PrintMessage ("debug", FileName, LineNumber, 0, Text, MsgFmt, List); + va_end (List); +} + +static +void +PrintMessage ( + INT8 *Type, + INT8 *FileName, + UINT32 LineNumber, + UINT32 MessageCode, + INT8 *Text, + INT8 *MsgFmt, + va_list List + ) +/*++ + +Routine Description: + Worker routine for all the utility printing services. Prints the message in + a format that Visual Studio will find when scanning build outputs for + errors or warnings. + +Arguments: + Type - "warning" or "error" string to insert into the message to be + printed. The first character of this string (converted to uppercase) + is used to preceed the MessageCode value in the output string. + + FileName - name of the file where the warning was detected, or the name + of the application that detected the warning + + LineNumber - the line number where the warning was detected (parsers). + 0 should be specified if the utility is not a parser. + + MessageCode - an application-specific warning code that can be referenced in + other documentation. + + Text - part of the message to print + + MsgFmt - the format string for the message. Can contain formatting + controls for use with varargs. + + List - Variable function parameter list. +Returns: + None. + +Notes: + If FileName == NULL then this utility will use the string passed into SetUtilityName(). + + LineNumber is only used if the caller is a parser, in which case FileName refers to the + file being parsed. + + Text and MsgFmt are both optional, though it would be of little use calling this function with + them both NULL. + + Output will typically be of the form: + () : : : + + Parser (LineNumber != 0) + VfrCompile.cpp(330) : error E2660: AddVfrDataStructField : function does not take 2 parameters + Generic utility (LineNumber == 0) + UtilityName : error E1234 : Text string : MsgFmt string and args + +--*/ +{ + INT8 Line[MAX_LINE_LEN]; + INT8 Line2[MAX_LINE_LEN]; + INT8 *Cptr; + // + // If given a filename, then add it (and the line number) to the string. + // If there's no filename, then use the program name if provided. + // + if (FileName != NULL) { + Cptr = FileName; + } else if (mUtilityName[0] != 0) { + Cptr = mUtilityName; + } else { + Cptr = "Unknown utility"; + } + + strcpy (Line, Cptr); + if (LineNumber != 0) { + sprintf (Line2, "(%d)", LineNumber); + strcat (Line, Line2); + } + // + // Have to print an error code or Visual Studio won't find the + // message for you. It has to be decimal digits too. + // + sprintf (Line2, " : %s %c%04d", Type, toupper (Type[0]), MessageCode); + strcat (Line, Line2); + fprintf (stdout, "%s", Line); + // + // If offending text was provided, then print it + // + if (Text != NULL) { + fprintf (stdout, ": %s ", Text); + } + // + // Print formatted message if provided + // + if (MsgFmt != NULL) { + vsprintf (Line2, MsgFmt, List); + fprintf (stdout, ": %s", Line2); + } + + fprintf (stdout, "\n"); +} + +void +ParserSetPosition ( + INT8 *SourceFileName, + UINT32 LineNum + ) +/*++ + +Routine Description: + Set the position in a file being parsed. This can be used to + print error messages deeper down in a parser. + +Arguments: + SourceFileName - name of the source file being parsed + LineNum - line number of the source file being parsed + +Returns: + NA + +--*/ +{ + mSourceFileName = SourceFileName; + mSourceFileLineNum = LineNum; +} + +void +SetUtilityName ( + INT8 *UtilityName + ) +/*++ + +Routine Description: + All printed error/warning/debug messages follow the same format, and + typically will print a filename or utility name followed by the error + text. However if a filename is not passed to the print routines, then + they'll print the utility name if you call this function early in your + app to set the utility name. + +Arguments: + UtilityName - name of the utility, which will be printed with all + error/warning/debug messags. + +Returns: + NA + +--*/ +{ + // + // Save the name of the utility in our local variable. Make sure its + // length does not exceed our buffer. + // + if (UtilityName != NULL) { + if (strlen (UtilityName) >= sizeof (mUtilityName)) { + Error (UtilityName, 0, 0, "application error", "utility name length exceeds internal buffer size"); + strncpy (mUtilityName, UtilityName, sizeof (mUtilityName) - 1); + mUtilityName[sizeof (mUtilityName) - 1] = 0; + return ; + } else { + strcpy (mUtilityName, UtilityName); + } + } else { + Error (NULL, 0, 0, "application error", "SetUtilityName() called with NULL utility name"); + } +} + +STATUS +GetUtilityStatus ( + VOID + ) +/*++ + +Routine Description: + When you call Error() or Warning(), this module keeps track of it and + sets a local mStatus to STATUS_ERROR or STATUS_WARNING. When the utility + exits, it can call this function to get the status and use it as a return + value. + +Arguments: + None. + +Returns: + Worst-case status reported, as defined by which print function was called. + +--*/ +{ + return mStatus; +} diff --git a/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h new file mode 100644 index 0000000000..5f6c7010b4 --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/UtilsMsgs.h @@ -0,0 +1,106 @@ +/*++ + +Copyright (c) 2004, 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: + + UtilsMsgs.h + +Abstract: + + Prototypes for the EFI tools utility functions. + +--*/ + +#ifndef _UTILS_MESSAGES_H_ +#define _UTILS_MESSAGES_H_ + +STATUS +GetUtilityStatus ( + VOID + ) +; + +// +// If someone prints an error message and didn't specify a source file name, +// then we print the utility name instead. However they must tell us the +// utility name early on via this function. +// +VOID +SetUtilityName ( + INT8 *ProgramName + ) +; + +void +Error ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +Warning ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +DebugMsg ( + INT8 *FileName, + UINT32 LineNumber, + UINT32 MsgLevel, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +SetDebugMsgMask ( + UINT32 MsgMask + ) +; + +void +ParserSetPosition ( + INT8 *SourceFileName, + UINT32 LineNum + ) +; + +void +ParserError ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +void +ParserWarning ( + UINT32 ErrorCode, + INT8 *OffendingText, + INT8 *MsgFmt, + ... + ) +; + +#endif diff --git a/Tools/CodeTools/Source/GuidChk/build.xml b/Tools/CodeTools/Source/GuidChk/build.xml new file mode 100644 index 0000000000..aec3ad1e9c --- /dev/null +++ b/Tools/CodeTools/Source/GuidChk/build.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3