3 Copyright (c) 2004, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Parse files in a directory and subdirectories to find all guid definitions.
19 Then check them against each other to make sure there are no duplicates.
28 #include "CommonUtils.h"
29 #include "FileSearch.h"
30 #include "UtilsMsgs.h"
32 #define MAX_LINE_LEN 180 // we concatenate two lines sometimes
33 // Define a structure that correlates filename extensions to an enumerated
39 } FILE_TYPE_TABLE_ENTRY
;
41 #define FILE_EXTENSION_UNKNOWN 0
42 #define FILE_EXTENSION_C 1
43 #define FILE_EXTENSION_H 2
44 #define FILE_EXTENSION_IA32_ASM 3
45 #define FILE_EXTENSION_IA32_INC 4
46 #define FILE_EXTENSION_IA64_ASM 5
47 #define FILE_EXTENSION_IA64_INC 6
48 #define FILE_EXTENSION_PKG 7
49 #define FILE_EXTENSION_INF 8
51 FILE_TYPE_TABLE_ENTRY FileTypeTable
[] = {
57 FILE_EXTENSION_IA32_INC
,
59 FILE_EXTENSION_IA32_ASM
,
61 FILE_EXTENSION_IA64_ASM
,
67 FILE_EXTENSION_IA64_INC
,
72 typedef struct EFI_GUID
{
84 typedef struct _GUID_RECORD
{
85 struct _GUID_RECORD
*Next
;
92 typedef struct _SIGNATURE_RECORD
{
93 struct _SIGNATURE_RECORD
*Next
;
96 EFI_SIGNATURE Signature
;
103 INT8 DatabaseOutputFileName
[MAX_PATH
]; // with -b option
104 STRING_LIST
*ExcludeDirs
; // list of directory names not to process
105 STRING_LIST
*ExcludeSubDirs
; // list of directory names to not process subdirectories (build)
106 STRING_LIST
*ExcludeFiles
; // list of files to exclude (make.inf)
107 STRING_LIST
*ExcludeExtensions
; // list of filename extensions to exclude (.inf, .pkg)
111 BOOLEAN CheckSignatures
;
112 BOOLEAN GuidXReference
;
182 ProcessINFFileGuids (
188 ProcessPkgFileGuids (
194 ProcessIA32FileGuids (
200 ProcessIA64FileGuids (
241 UINT32 DataHH
, // Upper 32-bits of upper 64 bits of guid
242 UINT32 DataHL
, // Lower 32-bits of upper 64 bits
270 // GUID_RECORD *FileRecord
286 /**************************** GLOBALS ****************************************/
287 static GUID_RECORD
*gGuidList
= NULL
;
288 static SIGNATURE_RECORD
*gSignatureList
= NULL
;
289 static OPTIONS gOptions
;
291 /*****************************************************************************/
301 SetUtilityName ("GuidChk");
303 // Get the current working directory and then process the command line
306 Cwd
= _getcwd (NULL
, 0);
307 Status
= ProcessArgs (Argc
, Argv
);
308 if (Status
!= STATUS_SUCCESS
) {
312 if (gOptions
.CheckGuids
|| gOptions
.CheckSignatures
) {
313 Status
= ProcessDirectory (Cwd
, NULL
);
314 if (Status
== STATUS_SUCCESS
) {
316 // Check for duplicates
318 Status
= CheckDuplicates ();
322 if (gOptions
.DatabaseOutputFileName
[0] != 0) {
323 CreateGuidList (gOptions
.DatabaseOutputFileName
);
326 // Free up the memory
332 return GetUtilityStatus ();
342 STRING_LIST
*StrList
;
344 memset ((char *) &gOptions
, 0, sizeof (gOptions
));
346 // skip over program name
360 if ((Argv
[0][0] == '-') || (Argv
[0][0] == '/')) {
361 switch (Argv
[0][1]) {
373 // Check guids option
377 gOptions
.CheckGuids
= TRUE
;
381 // Check signatures option
385 gOptions
.CheckSignatures
= TRUE
;
389 // Print guids found option
393 gOptions
.PrintFound
= TRUE
;
397 // Exclude files option
402 // Check for another arg
405 Error (NULL
, 0, 0, Argv
[0], "missing argument with option");
410 StrList
= malloc (sizeof (STRING_LIST
));
411 if (StrList
== NULL
) {
412 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
416 memset ((char *) StrList
, 0, sizeof (STRING_LIST
));
417 StrList
->Str
= Argv
[1];
418 StrList
->Next
= gOptions
.ExcludeFiles
;
419 gOptions
.ExcludeFiles
= StrList
;
425 // Exclude directories option
430 // Check for another arg
433 Error (NULL
, 0, 0, Argv
[0], "missing argument with option");
438 StrList
= malloc (sizeof (STRING_LIST
));
439 if (StrList
== NULL
) {
440 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
444 memset ((char *) StrList
, 0, sizeof (STRING_LIST
));
445 StrList
->Str
= Argv
[1];
446 StrList
->Next
= gOptions
.ExcludeDirs
;
447 gOptions
.ExcludeDirs
= StrList
;
453 // -u exclude all subdirectories of a given directory option
458 // Check for another arg
461 Error (NULL
, 0, 0, Argv
[0], "missing argument with option");
466 StrList
= malloc (sizeof (STRING_LIST
));
467 if (StrList
== NULL
) {
468 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
472 memset ((char *) StrList
, 0, sizeof (STRING_LIST
));
473 StrList
->Str
= Argv
[1];
474 StrList
->Next
= gOptions
.ExcludeSubDirs
;
475 gOptions
.ExcludeSubDirs
= StrList
;
481 // -e exclude by filename extension option
486 // Check for another arg
489 Error (NULL
, 0, 0, Argv
[0], "missing argument with option");
494 StrList
= malloc (sizeof (STRING_LIST
));
495 if (StrList
== NULL
) {
496 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
500 memset ((char *) StrList
, 0, sizeof (STRING_LIST
));
502 // Let them put a * in front of the filename extension
504 StrList
->Str
= Argv
[1];
505 if (StrList
->Str
[0] == '*') {
509 StrList
->Next
= gOptions
.ExcludeExtensions
;
510 gOptions
.ExcludeExtensions
= StrList
;
516 // Print guid with matching symbol name for guid definitions found
520 gOptions
.GuidXReference
= 1;
524 // -b Print the internal database list to a file
529 // Check for one more arg
532 Error (NULL
, 0, 0, Argv
[0], "must specify file name with option");
537 strcpy (gOptions
.DatabaseOutputFileName
, Argv
[1]);
543 Error (NULL
, 0, 0, Argv
[0], "invalid option");
558 Error (NULL
, 0, 0, Argv
[0], "invalid argument");
563 // Have to check signatures, GUIDs, or dump the GUID database.
565 if ((!gOptions
.CheckGuids
) && (!gOptions
.CheckSignatures
) && (gOptions
.DatabaseOutputFileName
[0] == 0)) {
566 Error (NULL
, 0, 0, "nothing to do", "must specify -g, -s, and/or -b");
571 return STATUS_SUCCESS
;
574 // Print usage instructions
584 "GuidChk - scan files for duplicate GUID or signature definitions",
586 "Usage: GuidChk {options}\n",
588 " -d dirname exclude searching of a directory",
589 " -f filename exclude searching of a file",
590 " -e extension exclude searching of files by extension",
591 " -p print all GUIDS found",
592 " -g check for duplicate guids",
593 " -s check for duplicate signatures",
594 " -x print guid+defined symbol name",
595 " -b outfile write internal GUID+basename list to outfile",
596 " -u dirname exclude searching all subdirectories of a directory",
597 " -h -? print this help text",
599 " Example: GuidChk -g -u build -d fv -f make.inf -e .pkg",
603 for (Index
= 0; Str
[Index
] != NULL
; Index
++) {
604 fprintf (stdout
, "%s\n", Str
[Index
]);
608 // Process an entire directory by name
617 FILE_SEARCH_DATA FSData
;
625 // Root directory may be null
627 if (DirectoryName
!= NULL
) {
629 // printf ("Processing directory: %s\n", DirectoryName);
633 // Initialize our file searching
635 FileSearchInit (&FSData
);
638 // Exclude some directories, files, and extensions
640 FileSearchExcludeDirs (&FSData
, gOptions
.ExcludeDirs
);
641 FileSearchExcludeExtensions (&FSData
, gOptions
.ExcludeExtensions
);
642 FileSearchExcludeFiles (&FSData
, gOptions
.ExcludeFiles
);
644 // See if this directory is in the list of directories that they
645 // don't want to process subdirectories of
648 if (DirectoryName
!= NULL
) {
649 for (SLPtr
= gOptions
.ExcludeSubDirs
; SLPtr
!= NULL
; SLPtr
= SLPtr
->Next
) {
650 if (stricmp (SLPtr
->Str
, DirectoryName
) == 0) {
652 // printf ("not processing subdirectories of %s\n", DirectoryName);
660 // Create a filemask of files to search for. We'll append "\*.*" on the
661 // end, so allocate some extra bytes.
663 Len
= strlen (Path
) + 10;
664 if (DirectoryName
!= NULL
) {
665 Len
+= strlen (DirectoryName
);
668 FileMask
= malloc (Len
);
669 if (FileMask
== NULL
) {
670 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
674 // Now put it all together
676 strcpy (FileMask
, Path
);
677 if ((DirectoryName
!= NULL
) && (strlen (DirectoryName
) > 0)) {
678 strcat (FileMask
, "\\");
679 strcat (FileMask
, DirectoryName
);
682 strcat (FileMask
, "\\*.*");
685 // Start file searching for files and directories
687 FileSearchStart (&FSData
, FileMask
, FILE_SEARCH_FILE
| FILE_SEARCH_DIR
);
690 // Now hack the "\*.*" off the end of the filemask so we can use it to pass
691 // the full directory path on recursive calls to process directories.
693 FileMask
[strlen (FileMask
) - 4] = 0;
696 // Loop until no more files
701 // printf ("Found %s...", FSData.FileName);
703 if (FSData
.FileFlags
& FILE_SEARCH_DIR
) {
705 // printf ("directory\n");
708 ProcessDirectory (FileMask
, FSData
.FileName
);
710 } else if (FSData
.FileFlags
& FILE_SEARCH_FILE
) {
712 // printf ("file\n");
714 ProcessFile (FileMask
, FSData
.FileName
);
717 // printf ("unknown\n");
721 if (FileSearchFindNext (&FSData
) != STATUS_SUCCESS
) {
726 // Free up allocated memory
731 // Free up our file searching
733 FileSearchDestroy (&FSData
);
735 return STATUS_SUCCESS
;
738 // Process a single file.
748 UINT32 FileExtension
;
749 INT8 FullFileName
[MAX_PATH
];
751 Status
= STATUS_SUCCESS
;
753 sprintf (FullFileName
, "%s\\%s", DirectoryName
, FileName
);
755 // printf ("Found file: %s\n", FullFileName);
757 FileExtension
= GetFileExtension (FileName
);
760 // Process these for GUID checks
762 if (gOptions
.CheckGuids
) {
763 switch (FileExtension
) {
764 case FILE_EXTENSION_C
:
765 case FILE_EXTENSION_H
:
766 Status
= ProcessCFileGuids (FullFileName
);
769 case FILE_EXTENSION_PKG
:
770 Status
= ProcessPkgFileGuids (FullFileName
);
773 case FILE_EXTENSION_IA32_INC
:
774 case FILE_EXTENSION_IA32_ASM
:
775 Status
= ProcessIA32FileGuids (FullFileName
);
778 case FILE_EXTENSION_INF
:
779 Status
= ProcessINFFileGuids (FullFileName
);
782 case FILE_EXTENSION_IA64_INC
:
783 case FILE_EXTENSION_IA64_ASM
:
784 Status
= ProcessIA64FileGuids (FullFileName
);
791 Status
= STATUS_SUCCESS
;
796 if (gOptions
.CheckSignatures
) {
797 switch (FileExtension
) {
798 case FILE_EXTENSION_C
:
799 case FILE_EXTENSION_H
:
800 Status
= ProcessCFileSigs (FullFileName
);
807 Status
= STATUS_SUCCESS
;
815 // Return a code indicating the file name extension.
827 // Look back for a filename extension
829 for (Extension
= FileName
+ strlen (FileName
) - 1; Extension
>= FileName
; Extension
--) {
830 if (*Extension
== '.') {
831 for (Index
= 0; FileTypeTable
[Index
].Extension
!= NULL
; Index
++) {
832 if (stricmp (FileTypeTable
[Index
].Extension
, Extension
) == 0) {
833 return FileTypeTable
[Index
].ExtensionCode
;
839 return FILE_TYPE_UNKNOWN
;
842 // Process a .pkg file.
844 // Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
848 ProcessPkgFileGuids (
853 INT8 Line
[MAX_LINE_LEN
* 2];
859 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
860 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
864 // Read lines from the file until done
866 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
868 Cptr
+= SkipWhiteSpace (Line
);
869 if (strncmp (Cptr
, "FFS_FILEGUID", 12) == 0) {
871 Cptr
+= SkipWhiteSpace (Cptr
);
874 Cptr
+= SkipWhiteSpace (Cptr
+ 1);
876 // Blank out dashes on the line.
878 for (Cptr2
= Cptr
; *Cptr2
; Cptr2
++) {
893 AddPkgGuid (FileName
, GuidScan
, &Guid64
);
895 DebugMsg (NULL
, 0, 0, FileName
, "GUID scan failed");
902 return STATUS_SUCCESS
;
905 // Process an IA32 assembly file.
908 // FIND_FD_GUID_VAL equ 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h
909 // PEI_GUID_FileNameGuid_Gmch815 equ 081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h
913 ProcessIA32FileGuids (
918 INT8 Line
[MAX_LINE_LEN
];
926 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
927 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
931 // Read lines from the file until done
933 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
935 Cptr
+= SkipWhiteSpace (Line
);
937 // Look for xxxGUIDyyy equ 01h, 02h, 03h, ...
939 Len
= ValidSymbolName (Cptr
);
942 // Terminate the line after the symbol name, then look for "guid" in
945 CSavePtr
= Cptr
+ Len
;
949 if (strnicmp (Cptr
, "guid", 4) == 0) {
956 // If we found the string "guid", continue
960 // Restore the character on the line where we null-terminated the symbol
964 Len
= SkipWhiteSpace (Cptr
);
966 // Had to be some white space
971 // now look for "equ"
973 if (strnicmp (Cptr
, "equ", 3) == 0) {
975 Cptr
+= SkipWhiteSpace (Cptr
);
977 // Now scan all the data
979 for (Index
= 0; Index
< 16; Index
++) {
980 if (sscanf (Cptr
, "%X", &GuidData
[Index
]) != 1) {
986 while (isxdigit (*Cptr
)) {
990 if ((*Cptr
!= 'h') && (*Cptr
!= 'H')) {
994 while (*Cptr
&& (isspace (*Cptr
) || (*Cptr
== ','))) {
1000 // Now see which form we had
1003 AddGuid16 (FileName
, GuidData
);
1004 } else if (Index
== 11) {
1005 AddGuid11 (FileName
, GuidData
, NULL
);
1014 return STATUS_SUCCESS
;
1017 // Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list
1027 GUID_RECORD
*NewRec
;
1031 // Sanity check the data
1033 if (!CheckGuidData (Data
, 16)) {
1034 return STATUS_ERROR
;
1037 // Allocate memory for a new guid structure
1039 NewRec
= malloc (sizeof (GUID_RECORD
));
1040 if (NewRec
== NULL
) {
1041 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1042 return STATUS_ERROR
;
1045 memset ((char *) NewRec
, 0, sizeof (GUID_RECORD
));
1046 NewRec
->FileName
= malloc (strlen (FileName
) + 1);
1047 if (NewRec
->FileName
== NULL
) {
1049 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1050 return STATUS_ERROR
;
1053 strcpy (NewRec
->FileName
, FileName
);
1054 NewRec
->Guid
.Data1
= (UINT32
) (Data
[0] | (Data
[1] << 8) | (Data
[2] << 16) | (Data
[3] << 24));
1055 NewRec
->Guid
.Data2
= (UINT16
) (Data
[4] | (Data
[5] << 8));
1056 NewRec
->Guid
.Data3
= (UINT16
) (Data
[6] | (Data
[7] << 8));
1057 for (Index
= 0; Index
< 8; Index
++) {
1058 NewRec
->Guid
.Data4
[Index
] = (UINT8
) Data
[Index
+ 8];
1061 // Add it to the list
1063 NewRec
->Next
= gGuidList
;
1068 // ReportGuid (FileName, NewRec);
1070 return STATUS_SUCCESS
;
1073 // Add a GUID defined as GuidLow: 0x1122334455667788
1074 // GuidHi: 0x99AABBCCDDEEFF00
1076 // These are equivalent:
1077 // { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }
1079 // Low: 00FFEEDDCCBBAA99
1080 // Hi: 7788556611223344
1086 UINT32 DataHH
, // Upper 32-bits of upper 64 bits of guid
1087 UINT32 DataHL
, // Lower 32-bits of upper 64 bits
1092 GUID_RECORD
*NewRec
;
1096 // Allocate memory for a new guid structure
1098 NewRec
= malloc (sizeof (GUID_RECORD
));
1099 if (NewRec
== NULL
) {
1100 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1101 return STATUS_ERROR
;
1104 memset ((char *) NewRec
, 0, sizeof (GUID_RECORD
));
1105 NewRec
->FileName
= malloc (strlen (FileName
) + 1);
1106 if (NewRec
->FileName
== NULL
) {
1108 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1109 return STATUS_ERROR
;
1112 strcpy (NewRec
->FileName
, FileName
);
1113 NewRec
->Guid
.Data1
= DataHL
;
1114 NewRec
->Guid
.Data2
= (UINT16
) DataHH
;
1115 NewRec
->Guid
.Data3
= (UINT16
) (DataHH
>> 16);
1116 for (Index
= 0; Index
< 4; Index
++) {
1117 NewRec
->Guid
.Data4
[Index
] = (UINT8
) DataLL
;
1121 for (Index
= 0; Index
< 4; Index
++) {
1122 NewRec
->Guid
.Data4
[Index
+ 4] = (UINT8
) DataLH
;
1126 // Add it to the list
1128 NewRec
->Next
= gGuidList
;
1133 // ReportGuid (FileName, NewRec);
1135 return STATUS_SUCCESS
;
1138 // Process INF files. Look for:
1139 // FILE_GUID = 240612B6-A063-11d4-9A3A-0090273FC14D
1143 ProcessINFFileGuids (
1148 INT8 Line
[MAX_LINE_LEN
* 2];
1151 UINT32 GuidScan
[11];
1154 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
1155 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
1156 return STATUS_ERROR
;
1159 // Read lines from the file until done
1161 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
1163 Cptr
+= SkipWhiteSpace (Line
);
1164 if (strncmp (Cptr
, "FILE_GUID", 9) == 0) {
1166 Cptr
+= SkipWhiteSpace (Cptr
);
1169 Cptr
+= SkipWhiteSpace (Cptr
+ 1);
1171 // Blank out dashes on the line.
1173 for (Cptr2
= Cptr
; *Cptr2
; Cptr2
++) {
1174 if (*Cptr2
== '-') {
1181 "%X %X %X %X %I64X",
1188 AddPkgGuid (FileName
, GuidScan
, &Guid64
);
1190 DebugMsg (NULL
, 0, 0, FileName
, "GUID scan failed");
1197 return STATUS_SUCCESS
;
1200 // Parse ('g','m','a','p','a','b','c','d')
1210 SIGNATURE_RECORD
*NewRec
;
1216 // Allocate memory for the new record
1219 NewRec
= malloc (sizeof (SIGNATURE_RECORD
));
1220 if (NewRec
== NULL
) {
1221 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1222 return STATUS_ERROR
;
1225 // Allocate memory to save the file name
1227 NewRec
->FileName
= malloc (strlen (FileName
) + 1);
1228 if (NewRec
->FileName
== NULL
) {
1229 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1231 return STATUS_ERROR
;
1234 // Fill in the fields
1236 strcpy (NewRec
->FileName
, FileName
);
1237 NewRec
->Signature
.DataLen
= (UINT8
) SigSize
;
1239 // Skip to open parenthesis
1242 Cptr
+= SkipWhiteSpace (Cptr
);
1250 // Skip to first ' and start processing
1252 while (*Cptr
&& (*Cptr
!= '\'')) {
1256 for (Index
= 0; Index
< SigSize
; Index
++) {
1257 if (*Cptr
== '\'') {
1259 NewRec
->Signature
.Data
[Index
] = (INT8
) *Cptr
;
1261 // Skip to closing quote
1264 if (*Cptr
!= '\'') {
1269 // Skip over closing quote, go to next one
1272 while (*Cptr
&& (*Cptr
!= '\'')) {
1277 DebugMsg (NULL
, 0, 0, StrDef
, "failed to parse signature");
1284 free (NewRec
->FileName
);
1286 return STATUS_ERROR
;
1289 NewRec
->Next
= gSignatureList
;
1290 gSignatureList
= NewRec
;
1291 return STATUS_SUCCESS
;
1295 // #define POOL_HEAD_SIGNATURE EFI_SIGNATURE_16('p','h')
1296 // #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('g','m','a','p')
1297 // #define GCD_MEMORY_MAP_SIGNATURE EFI_SIGNATURE_64('g','m','a','p','a','b','c','d')
1306 INT8 Line
[MAX_LINE_LEN
* 2];
1311 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
1312 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
1313 return STATUS_ERROR
;
1316 // Read lines from the file until done
1318 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
1320 Cptr
+= SkipWhiteSpace (Line
);
1322 // look for #define xxxGUIDxxx value
1326 Cptr
+= SkipWhiteSpace (Cptr
);
1328 // Look for "define"
1330 if (!strncmp (Cptr
, "define", 6)) {
1333 // Better be whitespace
1335 Len
= SkipWhiteSpace (Cptr
);
1339 // See if it's a valid symbol name
1341 Len
= ValidSymbolName (Cptr
);
1344 // It is a valid symbol name. See if there's a line continuation,
1345 // and if so, read one more line.
1346 // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx"
1348 LineLen
= strlen (Line
);
1349 if ((Line
[LineLen
- 1] == '\n') && (Line
[LineLen
- 2] == '\\')) {
1350 fgets (Line
+ LineLen
- 2, sizeof (Line
) - LineLen
, Fptr
);
1351 } else if (Line
[LineLen
- 1] == '\\') {
1352 fgets (Line
+ LineLen
- 1, sizeof (Line
) - LineLen
, Fptr
);
1356 Cptr
+= SkipWhiteSpace (Cptr
);
1357 if (strncmp (Cptr
, "EFI_SIGNATURE_16", 16) == 0) {
1358 AddSignature (FileName
, Cptr
+ 16, 2);
1359 } else if (strncmp (Cptr
, "EFI_SIGNATURE_32", 16) == 0) {
1360 AddSignature (FileName
, Cptr
+ 16, 4);
1361 } else if (strncmp (Cptr
, "EFI_SIGNATURE_64", 16) == 0) {
1362 AddSignature (FileName
, Cptr
+ 16, 8);
1371 return STATUS_SUCCESS
;
1374 // look for #define xxxGUIDyyy { 0x...}
1375 // xxx EFI_GUID GuidName = { 0x... };
1384 INT8 Line
[MAX_LINE_LEN
* 2];
1392 UINT32 GuidScan
[11];
1394 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
1395 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
1396 return STATUS_ERROR
;
1399 // Read lines from the file until done
1401 while (fgets (Line
, sizeof (Line
), Fptr
) != NULL
) {
1403 Cptr
+= SkipWhiteSpace (Line
);
1405 // look for #define xxxGUIDxxx value
1409 Cptr
+= SkipWhiteSpace (Cptr
);
1411 // Look for "define"
1413 if (!strncmp (Cptr
, "define", 6)) {
1416 // Better be whitespace
1418 Len
= SkipWhiteSpace (Cptr
);
1422 // See if it's a valid symbol name
1424 Len
= ValidSymbolName (Cptr
);
1427 // It is a valid symbol name. See if there's a line continuation,
1428 // and if so, read one more line.
1429 // Then truncate after the symbol name, look for the string "GUID",
1433 LineLen
= strlen (Line
);
1434 if ((Line
[LineLen
- 1] == '\n') && (Line
[LineLen
- 2] == '\\')) {
1435 fgets (Line
+ LineLen
- 2, sizeof (Line
) - LineLen
, Fptr
);
1436 } else if (Line
[LineLen
- 1] == '\\') {
1437 fgets (Line
+ LineLen
- 1, sizeof (Line
) - LineLen
, Fptr
);
1440 CSavePtr
= Cptr
+ Len
;
1444 if (strncmp (Cptr
, "GUID", 4) == 0) {
1451 // If we didn't run out of string, then we found the GUID string.
1452 // Now look for { 0x....... }
1457 Cptr
+= SkipWhiteSpace (Cptr
);
1462 // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
1463 // If you have one suffixed with "L", then it doesn't work. So hack off 'L' characters
1466 for (TempCptr
= Cptr
; *TempCptr
; TempCptr
++) {
1467 if (*TempCptr
== 'L') {
1468 if (*(TempCptr
+ 1) == ',') {
1470 *(TempCptr
+ 1) = ' ';
1477 "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",
1490 AddGuid11 (FileName
, GuidScan
, SymName
);
1498 // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... };
1500 } else if ((CSavePtr
= strstr (Line
, "EFI_GUID")) != NULL
) {
1502 // Read the next line if line continuation
1504 LineLen
= strlen (Line
);
1505 if ((Line
[LineLen
- 1] == '\n') && (Line
[LineLen
- 2] == '\\')) {
1506 fgets (Line
+ LineLen
- 2, sizeof (Line
) - LineLen
, Fptr
);
1507 } else if (Line
[LineLen
- 1] == '\\') {
1508 fgets (Line
+ LineLen
- 1, sizeof (Line
) - LineLen
, Fptr
);
1511 Cptr
= CSavePtr
+ 8;
1512 Cptr
+= SkipWhiteSpace (Cptr
);
1514 // Should be variable name next
1516 Len
= ValidSymbolName (Cptr
);
1519 Cptr
+= SkipWhiteSpace (Cptr
);
1522 Cptr
+= SkipWhiteSpace (Cptr
);
1524 // Should be open-brace next to define guid
1529 // 0x665E3FF6, 0x46CC, 0x11d4, 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
1533 "%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X",
1546 AddGuid11 (FileName
, GuidScan
, Cptr
);
1548 // printf ("Found guid: %s", Cptr);
1557 return STATUS_SUCCESS
;
1560 // Process Intel Itanium(TM) GUID definitions. Look for:
1561 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1562 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1564 // This function assumes no blank lines between definitions.
1568 ProcessIA64FileGuids (
1573 INT8 Line
[MAX_LINE_LEN
];
1578 INT8 SymName1
[MAX_LINE_LEN
];
1579 INT8 SymName2
[MAX_LINE_LEN
];
1584 if ((Fptr
= fopen (FileName
, "r")) == NULL
) {
1585 Error (NULL
, 0, 0, FileName
, "could not open input file for reading");
1586 return STATUS_ERROR
;
1590 if (fgets (Line
, sizeof (Line
), Fptr
) == NULL
) {
1594 // Read lines from the file until done. Since the guid definition takes
1595 // two lines, we read lines in different places to recover gracefully
1596 // from mismatches. For example, if you thought you found the first half,
1597 // but the next line had a symbol mismatch, then you have to process the
1598 // line again in case it's the start of a new definition.
1602 // Check current line for GUID definition. Assume low define first.
1604 if (IsIA64GuidLine (Line
, &Guid1H
, &Guid1L
, &FoundLow
, SymName1
)) {
1606 // Might have to swap guids later. Save off if we found the LOW first
1614 // Read the next line and try for the rest of the guid definition
1616 if (fgets (Line
, sizeof (Line
), Fptr
) == NULL
) {
1619 if (IsIA64GuidLine (Line
, &Guid2H
, &Guid2L
, &FoundLow
, SymName2
)) {
1621 // Found another. If the symbol names match, then save it off.
1623 if (strcmp (SymName1
, SymName2
) == 0) {
1625 // Yea, found one. Save it off.
1628 AddGuid64x2 (FileName
, Guid2H
, Guid2L
, Guid1H
, Guid1L
);
1630 AddGuid64x2 (FileName
, Guid1H
, Guid1L
, Guid2H
, Guid2L
);
1633 // Read the next line for processing
1635 if (fgets (Line
, sizeof (Line
), Fptr
) == NULL
) {
1640 // Don't get another line so that we reprocess this line in case it
1641 // contains the start of a new definition.
1642 // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n",
1643 // FileName, SymName1, SymName2);
1648 // Second line was not a guid definition. Get the next line from the
1651 if (fgets (Line
, sizeof (Line
), Fptr
) == NULL
) {
1658 // Not a guid define line. Next.
1660 if (fgets (Line
, sizeof (Line
), Fptr
) == NULL
) {
1667 return STATUS_SUCCESS
;
1670 // Given a line from an Itanium-based assembly file, check the line for a guid
1671 // defininition. One of either:
1672 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1673 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1674 // Return the defined value as two 32-bit values, and whether it's a high
1694 Cptr
+= SkipWhiteSpace (Cptr
);
1696 // look for #define xxxGUID[L|H] 0xHexValue
1700 Cptr
+= SkipWhiteSpace (Cptr
);
1702 // Look for "define"
1704 if (!strncmp (Cptr
, "define", 6)) {
1707 // Better be whitespace
1709 Len
= SkipWhiteSpace (Cptr
);
1713 // See if it's a valid symbol name
1715 Len
= ValidSymbolName (Cptr
);
1718 // Save the start so we can copy it to their string if later checks are ok
1722 // It is a valid symbol name, look for the string GuidL or GuidH
1724 CSavePtr
= Cptr
+ Len
;
1728 if (strncmp (Cptr
, "GuidL", 5) == 0) {
1731 } else if (strncmp (Cptr
, "GuidH", 5) == 0) {
1739 // If we didn't run out of string, then we found the GUID string.
1740 // Restore the null character we inserted above and continue.
1741 // Now look for 0x.......
1745 // Return symbol name less the "L" or "H"
1747 strcpy (SymName
, SymStart
);
1748 SymName
[strlen (SymName
) - 1] = 0;
1751 Cptr
+= SkipWhiteSpace (Cptr
);
1752 if ((*Cptr
== '0') && (*(Cptr
+ 1) == 'x')) {
1758 // 0x0123456789ABCDEF -- null terminate after 8 characters,
1759 // scan, replace the character and scan at that point.
1761 CSave
= *(Cptr
+ 8);
1763 if (sscanf (Cptr
, "%X", GuidHigh
) == 1) {
1764 *(Cptr
+ 8) = CSave
;
1765 if (sscanf (Cptr
+ 8, "%X", GuidLow
) == 1) {
1779 // Look at the characters in the string and determine if it's a valid
1780 // symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]*
1793 // Test first character
1795 if (((*Name
>= 'a') && (*Name
<= 'z')) || ((*Name
>= 'A') && (*Name
<= 'Z')) || (*Name
== '_')) {
1799 if (((*Name
>= 'a') && (*Name
<= 'z')) ||
1800 ((*Name
>= 'A') && (*Name
<= 'Z')) ||
1801 ((*Name
>= '0') && (*Name
<= '9')) ||
1823 while (isspace (*Str
) && *Str
) {
1831 // found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
1841 GUID_RECORD
*NewRec
;
1845 // Sanity check the data
1847 if ((Data
[1] | Data
[2] | Data
[3]) & 0xFFFF0000) {
1848 Error (NULL
, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL
);
1849 return STATUS_ERROR
;
1852 // More checks for Data64?
1853 // Allocate memory for a new one guid structure
1855 NewRec
= malloc (sizeof (GUID_RECORD
));
1856 if (NewRec
== NULL
) {
1857 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1858 return STATUS_ERROR
;
1861 memset ((char *) NewRec
, 0, sizeof (GUID_RECORD
));
1862 NewRec
->FileName
= malloc (strlen (FileName
) + 1);
1863 if (NewRec
->FileName
== NULL
) {
1865 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1866 return STATUS_ERROR
;
1869 strcpy (NewRec
->FileName
, FileName
);
1870 NewRec
->Guid
.Data1
= Data
[0];
1871 NewRec
->Guid
.Data2
= (UINT16
) Data
[1];
1872 NewRec
->Guid
.Data3
= (UINT16
) Data
[2];
1873 NewRec
->Guid
.Data4
[0] = (UINT8
) Data
[3];
1874 NewRec
->Guid
.Data4
[1] = (UINT8
) (Data
[3] >> 8);
1875 for (Index
= 2; Index
< 8; Index
++) {
1876 NewRec
->Guid
.Data4
[Index
] = (UINT8
) *Data64
;
1880 // Add it to the list
1882 NewRec
->Next
= gGuidList
;
1887 // ReportGuid (FileName, NewRec);
1889 return STATUS_SUCCESS
;
1892 // Add a guid consisting of 11 fields to our list of guids
1902 GUID_RECORD
*NewRec
;
1906 // Sanity check the data
1908 if (!CheckGuidData (Data
, 11)) {
1909 return STATUS_ERROR
;
1912 // Allocate memory for a new one guid structure
1914 NewRec
= malloc (sizeof (GUID_RECORD
));
1915 if (NewRec
== NULL
) {
1916 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1917 return STATUS_ERROR
;
1920 memset ((char *) NewRec
, 0, sizeof (GUID_RECORD
));
1921 NewRec
->FileName
= malloc (strlen (FileName
) + 1);
1922 if (NewRec
->FileName
== NULL
) {
1924 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1925 return STATUS_ERROR
;
1928 strcpy (NewRec
->FileName
, FileName
);
1929 if (SymName
!= NULL
) {
1930 NewRec
->SymName
= malloc (strlen (SymName
) + 1);
1931 if (NewRec
->SymName
== NULL
) {
1933 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
1934 return STATUS_ERROR
;
1938 strcpy (NewRec
->SymName
, SymName
);
1940 NewRec
->Guid
.Data1
= Data
[0];
1941 NewRec
->Guid
.Data2
= (UINT16
) Data
[1];
1942 NewRec
->Guid
.Data3
= (UINT16
) Data
[2];
1943 for (Index
= 0; Index
< 8; Index
++) {
1944 NewRec
->Guid
.Data4
[Index
] = (UINT8
) Data
[3 + Index
];
1947 // Add it to the list
1949 NewRec
->Next
= gGuidList
;
1954 // ReportGuid (FileName, NewRec);
1956 return STATUS_SUCCESS
;
1959 // For debug purposes, print each guid found
1965 // GUID_RECORD *NewGuid
1968 // //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1);
1971 // Free up memory we allocated to keep track of guids defined.
1979 GUID_RECORD
*NextRec
;
1980 while (gGuidList
!= NULL
) {
1981 NextRec
= gGuidList
->Next
;
1982 if (gGuidList
->FileName
!= NULL
) {
1983 free (gGuidList
->FileName
);
1986 if (gGuidList
->SymName
!= NULL
) {
1987 free (gGuidList
->SymName
);
1991 gGuidList
= NextRec
;
2001 SIGNATURE_RECORD
*NextRec
;
2002 while (gSignatureList
!= NULL
) {
2003 NextRec
= gSignatureList
->Next
;
2004 if (gSignatureList
->FileName
!= NULL
) {
2005 free (gSignatureList
->FileName
);
2008 free (gSignatureList
);
2009 gSignatureList
= NextRec
;
2013 // Scan through all guids defined and compare each for duplicates.
2021 GUID_RECORD
*CurrentFile
;
2023 GUID_RECORD
*TempFile
;
2024 SIGNATURE_RECORD
*CurrentSig
;
2025 SIGNATURE_RECORD
*TempSig
;
2034 Status
= STATUS_SUCCESS
;
2037 // If we're checking guids.....
2039 if (gOptions
.CheckGuids
) {
2041 // If -p option, print all guids found
2043 if (gOptions
.PrintFound
) {
2044 CurrentFile
= gGuidList
;
2045 while (CurrentFile
!= NULL
) {
2048 "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",
2049 (UINT32
) CurrentFile
->Guid
.Data1
,
2050 (UINT32
) CurrentFile
->Guid
.Data2
,
2051 (UINT32
) CurrentFile
->Guid
.Data3
,
2052 (UINT32
) CurrentFile
->Guid
.Data4
[0],
2053 (UINT32
) CurrentFile
->Guid
.Data4
[1],
2054 (UINT32
) CurrentFile
->Guid
.Data4
[2],
2055 (UINT32
) CurrentFile
->Guid
.Data4
[3],
2056 (UINT32
) CurrentFile
->Guid
.Data4
[4],
2057 (UINT32
) CurrentFile
->Guid
.Data4
[5],
2058 (UINT32
) CurrentFile
->Guid
.Data4
[6],
2059 (UINT32
) CurrentFile
->Guid
.Data4
[7],
2060 CurrentFile
->FileName
2062 CurrentFile
= CurrentFile
->Next
;
2066 if (gOptions
.GuidXReference
) {
2067 CurrentFile
= gGuidList
;
2068 while (CurrentFile
!= NULL
) {
2070 // If no symbol name, print "unknown"
2072 SymName
= CurrentFile
->SymName
;
2073 if (SymName
== NULL
) {
2074 SymName
= "unknown";
2079 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n",
2080 (UINT32
) CurrentFile
->Guid
.Data1
,
2081 (UINT32
) CurrentFile
->Guid
.Data2
,
2082 (UINT32
) CurrentFile
->Guid
.Data3
,
2083 (UINT32
) CurrentFile
->Guid
.Data4
[0],
2084 (UINT32
) CurrentFile
->Guid
.Data4
[1],
2085 (UINT32
) CurrentFile
->Guid
.Data4
[2],
2086 (UINT32
) CurrentFile
->Guid
.Data4
[3],
2087 (UINT32
) CurrentFile
->Guid
.Data4
[4],
2088 (UINT32
) CurrentFile
->Guid
.Data4
[5],
2089 (UINT32
) CurrentFile
->Guid
.Data4
[6],
2090 (UINT32
) CurrentFile
->Guid
.Data4
[7],
2093 CurrentFile
= CurrentFile
->Next
;
2097 // Now go through all guids and report duplicates.
2099 CurrentFile
= gGuidList
;
2100 while (CurrentFile
!= NULL
) {
2102 TempFile
= CurrentFile
->Next
;
2105 // Compare the guids
2107 if ((CurrentFile
->Guid
.Data1
== TempFile
->Guid
.Data1
) &&
2108 (CurrentFile
->Guid
.Data2
== TempFile
->Guid
.Data2
) &&
2109 (CurrentFile
->Guid
.Data3
== TempFile
->Guid
.Data3
)
2112 // OR in all the guid bytes so we can ignore NULL-guid definitions.
2114 GuidSum
= CurrentFile
->Guid
.Data1
| CurrentFile
->Guid
.Data2
| CurrentFile
->Guid
.Data3
;
2116 for (Index
= 0; Index
< 8; Index
++) {
2117 GuidSum
|= CurrentFile
->Guid
.Data4
[Index
];
2118 if (CurrentFile
->Guid
.Data4
[Index
] != TempFile
->Guid
.Data4
[Index
]) {
2124 // If they're the same, and the guid was non-zero, print a message.
2126 if (Same
&& GuidSum
) {
2127 if (DupCount
== 0) {
2128 Error (NULL
, 0, 0, "duplicate GUIDS found", NULL
);
2129 fprintf (stdout
, " FILE1: %s\n", CurrentFile
->FileName
);
2133 fprintf (stdout
, " FILE%d: %s\n", DupCount
+ 1, TempFile
->FileName
);
2135 // Flag it as reported so we don't report it again if there's three or more
2137 TempFile
->Reported
= TRUE
;
2143 TempFile
= TempFile
->Next
;
2146 // Print the guid if we found duplicates
2151 " GUID: 0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
2152 (UINT32
) CurrentFile
->Guid
.Data1
,
2153 (UINT32
) CurrentFile
->Guid
.Data2
,
2154 (UINT32
) CurrentFile
->Guid
.Data3
,
2155 (UINT32
) CurrentFile
->Guid
.Data4
[0],
2156 (UINT32
) CurrentFile
->Guid
.Data4
[1],
2157 (UINT32
) CurrentFile
->Guid
.Data4
[2],
2158 (UINT32
) CurrentFile
->Guid
.Data4
[3],
2159 (UINT32
) CurrentFile
->Guid
.Data4
[4],
2160 (UINT32
) CurrentFile
->Guid
.Data4
[5],
2161 (UINT32
) CurrentFile
->Guid
.Data4
[6],
2162 (UINT32
) CurrentFile
->Guid
.Data4
[7]
2165 // return STATUS_ERROR;
2169 // Find the next one that hasn't been reported
2172 CurrentFile
= CurrentFile
->Next
;
2173 } while ((CurrentFile
!= NULL
) && (CurrentFile
->Reported
));
2177 if (gOptions
.CheckSignatures
) {
2179 // Print ones found if specified
2181 if (gOptions
.PrintFound
) {
2182 CurrentSig
= gSignatureList
;
2183 while (CurrentSig
!= NULL
) {
2184 Len
= CurrentSig
->Signature
.DataLen
;
2185 for (Index
= 0; Index
< Len
; Index
++) {
2186 fprintf (stdout
, "%c", CurrentSig
->Signature
.Data
[Index
]);
2189 fprintf (stdout
, " %s\n", CurrentSig
->FileName
);
2190 CurrentSig
= CurrentSig
->Next
;
2194 CurrentSig
= gSignatureList
;
2195 while (CurrentSig
!= NULL
) {
2197 TempSig
= CurrentSig
->Next
;
2198 Len
= CurrentSig
->Signature
.DataLen
;
2201 // Check for same length, then do string compare
2203 if (Len
== TempSig
->Signature
.DataLen
) {
2204 if (strncmp (CurrentSig
->Signature
.Data
, TempSig
->Signature
.Data
, Len
) == 0) {
2206 // Print header message if first failure for this sig
2208 if (DupCount
== 0) {
2209 Error (NULL
, 0, 0, "duplicate signatures found", NULL
);
2210 fprintf (stdout
, " FILE1: %s\n", CurrentSig
->FileName
);
2214 fprintf (stdout
, " FILE%d: %s\n", DupCount
+ 1, TempSig
->FileName
);
2215 TempSig
->Reported
= TRUE
;
2219 TempSig
= TempSig
->Next
;
2223 fprintf (stdout
, " SIG: ");
2224 for (Index
= 0; Index
< Len
; Index
++) {
2225 fprintf (stdout
, "%c", CurrentSig
->Signature
.Data
[Index
]);
2228 fprintf (stdout
, "\n");
2231 // On to the next one that hasn't been reported
2234 CurrentSig
= CurrentSig
->Next
;
2235 } while ((CurrentSig
!= NULL
) && (CurrentSig
->Reported
));
2249 Routine Description:
2250 Free up any memory we allocated when processing command-line options.
2259 We don't free up the ->Str fields because we did not allocate them.
2260 Instead, we just set the pointer to point to the actual parameter
2261 from the command line.
2266 while (gOptions
.ExcludeDirs
!= NULL
) {
2267 Ptr
= gOptions
.ExcludeDirs
->Next
;
2269 // free (gOptions.ExcludeDirs->Str);
2271 free (gOptions
.ExcludeDirs
);
2272 gOptions
.ExcludeDirs
= Ptr
;
2275 while (gOptions
.ExcludeSubDirs
!= NULL
) {
2276 Ptr
= gOptions
.ExcludeSubDirs
->Next
;
2278 // free (gOptions.ExcludeSubDirs->Str);
2280 free (gOptions
.ExcludeSubDirs
);
2281 gOptions
.ExcludeSubDirs
= Ptr
;
2284 while (gOptions
.ExcludeExtensions
!= NULL
) {
2285 Ptr
= gOptions
.ExcludeExtensions
->Next
;
2287 // free (gOptions.ExcludeExtensions->Str);
2289 free (gOptions
.ExcludeExtensions
);
2290 gOptions
.ExcludeExtensions
= Ptr
;
2293 while (gOptions
.ExcludeFiles
!= NULL
) {
2294 Ptr
= gOptions
.ExcludeFiles
->Next
;
2296 // free (gOptions.ExcludeFiles->Str);
2298 free (gOptions
.ExcludeFiles
);
2299 gOptions
.ExcludeFiles
= Ptr
;
2303 // Given an array of 32-bit data, validate the data for the given number of
2304 // guid data. For example, it might have been scanned as 16 bytes of data, or
2305 // 11 fields of data.
2316 if (DataCount
== 16) {
2317 for (Index
= 0; Index
< 16; Index
++) {
2318 if (Data
[Index
] &~0xFF) {
2324 } else if (DataCount
== 11) {
2326 // Data[0] never out of range (32-bit)
2328 if ((Data
[1] | Data
[2]) &~0xFFFF) {
2330 // Error ("Out of range value for GUID data word(s) [1] and/or [2]");
2335 for (Index
= 0; Index
< 8; Index
++) {
2336 if (Data
[Index
+ 3] &~0xFF) {
2338 // Error ("Out of range value for GUID data byte(s) [4] - [11]");