guidchk.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,349 行 · 第 1/4 页

C
2,349
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:  

  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  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",

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?