| /*++ | |
| 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 180 // we concatenate two lines sometimes | |
| // Define a structure that correlates filename extensions to an enumerated | |
| // type. | |
| // | |
| #define UTILITY_NAME "GuidChk" | |
| #define UTILITY_MAJOR_VERSION 1 | |
| #define UTILITY_MINOR_VERSION 0 | |
| 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 | |
| Version ( | |
| VOID | |
| ); | |
| 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; | |
| } | |
| if ((strcmp(Argv[0], "-h") == 0) || (strcmp(Argv[0], "--help") == 0) || | |
| (strcmp(Argv[0], "-?") == 0) || (strcmp(Argv[0], "/?") == 0)) { | |
| Usage(); | |
| return STATUS_ERROR; | |
| } | |
| if ((strcmp(Argv[0], "-V") == 0) || (strcmp(Argv[0], "--version") == 0)) { | |
| Version(); | |
| return STATUS_ERROR; | |
| } | |
| 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; | |
| } | |
| static | |
| void | |
| Version( | |
| void | |
| ) | |
| /*++ | |
| Routine Description: | |
| Displays the standard utility information to SDTOUT | |
| Arguments: | |
| None | |
| Returns: | |
| None | |
| --*/ | |
| { | |
| printf ("%s v%d.%d -Utility for checking guid duplication for files in a given directory.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION); | |
| printf ("Copyright (c) 1999-2007 Intel Corporation. All rights reserved.\n"); | |
| } | |
| // | |
| // 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,--help,-?,/? display help messages", | |
| " -V,--version display version information", | |
| " ", | |
| " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg", | |
| "", | |
| NULL | |
| }; | |
| Version(); | |
| 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; | |
| } |