• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*++
2 
3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
4 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
8 
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.
11 
12 Module Name:
13 
14   GuidChk.c
15 
16 Abstract:
17 
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.
20 
21 --*/
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 
28 #include "CommonUtils.h"
29 #include "FileSearch.h"
30 #include "UtilsMsgs.h"
31 
32 #define MAX_LINE_LEN  1024 // we concatenate lines sometimes
33 // Define a structure that correlates filename extensions to an enumerated
34 // type.
35 //
36 #ifdef MAX_PATH
37 #undef MAX_PATH
38 #define MAX_PATH  1024
39 #endif
40 
41 #define UTILITY_NAME    "GuidChk"
42 #define UTILITY_VERSION "v1.0"
43 
44 typedef struct {
45   INT8  *Extension;
46   INT8  ExtensionCode;
47 } FILE_TYPE_TABLE_ENTRY;
48 
49 #define FILE_EXTENSION_UNKNOWN  0
50 #define FILE_EXTENSION_C        1
51 #define FILE_EXTENSION_H        2
52 #define FILE_EXTENSION_IA32_ASM 3
53 #define FILE_EXTENSION_IA32_INC 4
54 #define FILE_EXTENSION_IA64_ASM 5
55 #define FILE_EXTENSION_IA64_INC 6
56 #define FILE_EXTENSION_PKG      7
57 #define FILE_EXTENSION_INF      8
58 
59 FILE_TYPE_TABLE_ENTRY FileTypeTable[] = {
60   ".c",
61   FILE_EXTENSION_C,
62   ".h",
63   FILE_EXTENSION_H,
64   ".inc",
65   FILE_EXTENSION_IA32_INC,
66   ".asm",
67   FILE_EXTENSION_IA32_ASM,
68   ".s",
69   FILE_EXTENSION_IA64_ASM,
70   ".pkg",
71   FILE_EXTENSION_PKG,
72   ".inf",
73   FILE_EXTENSION_INF,
74   ".i",
75   FILE_EXTENSION_IA64_INC,
76   NULL,
77   0
78 };
79 
80 typedef struct EFI_GUID {
81   UINT32  Data1;
82   UINT16  Data2;
83   UINT16  Data3;
84   UINT8   Data4[8];
85 } EFI_GUID;
86 
87 typedef struct {
88   INT8  Data[8];
89   INT8  DataLen;
90 } EFI_SIGNATURE;
91 
92 typedef struct _GUID_RECORD {
93   struct _GUID_RECORD *Next;
94   BOOLEAN             Reported;
95   INT8                *FileName;
96   INT8                *SymName;
97   EFI_GUID            Guid;
98 } GUID_RECORD;
99 
100 typedef struct _SIGNATURE_RECORD {
101   struct _SIGNATURE_RECORD  *Next;
102   BOOLEAN                   Reported;
103   INT8                      *FileName;
104   EFI_SIGNATURE             Signature;
105 } SIGNATURE_RECORD;
106 
107 //
108 // Utility options
109 //
110 typedef struct {
111   INT8        DatabaseOutputFileName[MAX_PATH]; // with -b option
112   STRING_LIST *ExcludeDirs;                     // list of directory names not to process
113   STRING_LIST *ExcludeSubDirs;                  // list of directory names to not process subdirectories (build)
114   STRING_LIST *ExcludeFiles;                    // list of files to exclude (make.inf)
115   STRING_LIST *ExcludeExtensions;               // list of filename extensions to exclude (.inf, .pkg)
116   BOOLEAN     Verbose;
117   BOOLEAN     PrintFound;
118   BOOLEAN     CheckGuids;
119   BOOLEAN     CheckSignatures;
120   BOOLEAN     GuidXReference;
121 } OPTIONS;
122 
123 static
124 STATUS
125 ProcessArgs (
126   int     Argc,
127   char    *Argv[]
128   );
129 
130 static
131 VOID
132 Usage (
133   VOID
134   );
135 
136 static
137 STATUS
138 ProcessDirectory (
139   INT8        *Path,
140   INT8        *DirectoryName
141   );
142 
143 static
144 STATUS
145 ProcessFile (
146   INT8                *DirectoryName,
147   INT8                *FileName
148   );
149 
150 static
151 UINT32
152 GetFileExtension (
153   INT8        *FileName
154   );
155 
156 static
157 UINT32
158 SkipWhiteSpace (
159   INT8    *Str
160   );
161 
162 static
163 UINT32
164 ValidSymbolName (
165   INT8    *Name
166   );
167 
168 static
169 STATUS
170 ProcessCFileGuids (
171   INT8    *FileName
172   );
173 
174 static
175 STATUS
176 AddSignature (
177   INT8      *FileName,
178   INT8      *StrDef,
179   UINT32    SigSize
180   );
181 
182 static
183 STATUS
184 ProcessCFileSigs (
185   INT8    *FileName
186   );
187 
188 static
189 STATUS
190 ProcessINFFileGuids (
191   INT8    *FileName
192   );
193 
194 static
195 STATUS
196 ProcessPkgFileGuids (
197   INT8    *FileName
198   );
199 
200 static
201 STATUS
202 ProcessIA32FileGuids (
203   INT8    *FileName
204   );
205 
206 static
207 STATUS
208 ProcessIA64FileGuids (
209   INT8    *FileName
210   );
211 
212 static
213 BOOLEAN
214 IsIA64GuidLine (
215   INT8      *Line,
216   UINT32    *GuidHigh,
217   UINT32    *GuidLow,
218   BOOLEAN   *Low,
219   INT8      *SymName
220   );
221 
222 static
223 STATUS
224 AddGuid11 (
225   INT8      *FileName,
226   UINT32    *Data,
227   INT8      *SymName
228   );
229 
230 static
231 STATUS
232 AddPkgGuid (
233   INT8      *FileName,
234   UINT32    *Data,
235   UINT64    *Data64
236   );
237 
238 static
239 STATUS
240 AddGuid16 (
241   INT8      *FileName,
242   UINT32    *Data
243   );
244 
245 static
246 STATUS
247 AddGuid64x2 (
248   INT8      *FileName,
249   UINT32    DataHH,                             // Upper 32-bits of upper 64 bits of guid
250   UINT32    DataHL,                             // Lower 32-bits of upper 64 bits
251   UINT32    DataLH,
252   UINT32    DataLL,
253   INT8      *SymName
254   );
255 
256 static
257 VOID
258 FreeGuids (
259   VOID
260   );
261 
262 static
263 VOID
264 FreeSigs (
265   VOID
266   );
267 
268 static
269 STATUS
270 CheckDuplicates (
271   VOID
272   );
273 
274 //
275 // static
276 // VOID
277 // ReportGuid (
278 //  INT8        *FileName,
279 //  GUID_RECORD *FileRecord
280 //  );
281 //
282 static
283 VOID
284 FreeOptions (
285   VOID
286   );
287 
288 static
289 BOOLEAN
290 CheckGuidData (
291   UINT32    *GuidData,
292   UINT32    DataCount
293   );
294 
295 static
296 VOID
297 ConcatenateLines (
298   FILE        *Fptr,
299   INT8        *Line,
300   UINT32      Len
301   );
302 
303 /**************************** GLOBALS ****************************************/
304 static GUID_RECORD      *gGuidList      = NULL;
305 static SIGNATURE_RECORD *gSignatureList = NULL;
306 static OPTIONS          gOptions;
307 
308 /*****************************************************************************/
309 int
main(int Argc,char * Argv[])310 main (
311   int     Argc,
312   char    *Argv[]
313   )
314 {
315   INT8    *Cwd;
316   STATUS  Status;
317 
318   SetUtilityName ("GuidChk");
319   //
320   // Get the current working directory and then process the command line
321   // arguments.
322   //
323   Cwd     = _getcwd (NULL, 0);
324   Status  = ProcessArgs (Argc, Argv);
325   if (Status != STATUS_SUCCESS) {
326     return Status;
327   }
328 
329   if (gOptions.CheckGuids || gOptions.CheckSignatures) {
330     Status = ProcessDirectory (Cwd, NULL);
331     if (Status == STATUS_SUCCESS) {
332       //
333       // Check for duplicates
334       //
335       Status = CheckDuplicates ();
336     }
337   }
338 
339   if (gOptions.DatabaseOutputFileName[0] != 0) {
340     CreateGuidList (gOptions.DatabaseOutputFileName);
341   }
342   //
343   // Free up the memory
344   //
345   free (Cwd);
346   FreeGuids ();
347   FreeSigs ();
348   FreeOptions ();
349   return GetUtilityStatus ();
350 }
351 
352 static
353 STATUS
ProcessArgs(int Argc,char * Argv[])354 ProcessArgs (
355   int     Argc,
356   char    *Argv[]
357   )
358 {
359   STRING_LIST *StrList;
360 
361   memset ((char *) &gOptions, 0, sizeof (gOptions));
362   //
363   // skip over program name
364   //
365   Argc--;
366   Argv++;
367 
368   if (Argc == 0) {
369     Usage ();
370     return STATUS_ERROR;
371   }
372 
373   while (Argc > 0) {
374     //
375     // Look for options
376     //
377     if ((Argv[0][0] == '-') || (Argv[0][0] == '/')) {
378       switch (Argv[0][1]) {
379       //
380       // Help option
381       //
382       case 'h':
383       case 'H':
384       case '?':
385         Usage ();
386         return STATUS_ERROR;
387         break;
388 
389       //
390       // Check guids option
391       //
392       case 'g':
393       case 'G':
394         gOptions.CheckGuids = TRUE;
395         break;
396 
397       //
398       // Check signatures option
399       //
400       case 's':
401       case 'S':
402         gOptions.CheckSignatures = TRUE;
403         break;
404 
405       //
406       // Print guids found option
407       //
408       case 'p':
409       case 'P':
410         gOptions.PrintFound = TRUE;
411         break;
412 
413       //
414       // Exclude files option
415       //
416       case 'f':
417       case 'F':
418         //
419         // Check for another arg
420         //
421         if (Argc < 2) {
422           Error (NULL, 0, 0, Argv[0], "missing argument with option");
423           Usage ();
424           return STATUS_ERROR;
425         }
426 
427         StrList = malloc (sizeof (STRING_LIST));
428         if (StrList == NULL) {
429           Error (NULL, 0, 0, "memory allocation failure", NULL);
430           return STATUS_ERROR;
431         }
432 
433         memset ((char *) StrList, 0, sizeof (STRING_LIST));
434         StrList->Str          = Argv[1];
435         StrList->Next         = gOptions.ExcludeFiles;
436         gOptions.ExcludeFiles = StrList;
437         Argc--;
438         Argv++;
439         break;
440 
441       //
442       // Exclude directories option
443       //
444       case 'd':
445       case 'D':
446         //
447         // Check for another arg
448         //
449         if (Argc < 2) {
450           Error (NULL, 0, 0, Argv[0], "missing argument with option");
451           Usage ();
452           return STATUS_ERROR;
453         }
454 
455         StrList = malloc (sizeof (STRING_LIST));
456         if (StrList == NULL) {
457           Error (NULL, 0, 0, "memory allocation failure", NULL);
458           return STATUS_ERROR;
459         }
460 
461         memset ((char *) StrList, 0, sizeof (STRING_LIST));
462         StrList->Str          = Argv[1];
463         StrList->Next         = gOptions.ExcludeDirs;
464         gOptions.ExcludeDirs  = StrList;
465         Argc--;
466         Argv++;
467         break;
468 
469       //
470       // -u  exclude all subdirectories of a given directory option
471       //
472       case 'u':
473       case 'U':
474         //
475         // Check for another arg
476         //
477         if (Argc < 2) {
478           Error (NULL, 0, 0, Argv[0], "missing argument with option");
479           Usage ();
480           return STATUS_ERROR;
481         }
482 
483         StrList = malloc (sizeof (STRING_LIST));
484         if (StrList == NULL) {
485           Error (NULL, 0, 0, "memory allocation failure", NULL);
486           return STATUS_ERROR;
487         }
488 
489         memset ((char *) StrList, 0, sizeof (STRING_LIST));
490         StrList->Str            = Argv[1];
491         StrList->Next           = gOptions.ExcludeSubDirs;
492         gOptions.ExcludeSubDirs = StrList;
493         Argc--;
494         Argv++;
495         break;
496 
497       //
498       // -e  exclude by filename extension option
499       //
500       case 'e':
501       case 'E':
502         //
503         // Check for another arg
504         //
505         if (Argc < 2) {
506           Error (NULL, 0, 0, Argv[0], "missing argument with option");
507           Usage ();
508           return STATUS_ERROR;
509         }
510 
511         StrList = malloc (sizeof (STRING_LIST));
512         if (StrList == NULL) {
513           Error (NULL, 0, 0, "memory allocation failure", NULL);
514           return STATUS_ERROR;
515         }
516 
517         memset ((char *) StrList, 0, sizeof (STRING_LIST));
518         //
519         // Let them put a * in front of the filename extension
520         //
521         StrList->Str = Argv[1];
522         if (StrList->Str[0] == '*') {
523           StrList->Str++;
524         }
525 
526         StrList->Next               = gOptions.ExcludeExtensions;
527         gOptions.ExcludeExtensions  = StrList;
528         Argc--;
529         Argv++;
530         break;
531 
532       //
533       // Print guid with matching symbol name for guid definitions found
534       //
535       case 'x':
536       case 'X':
537         gOptions.GuidXReference = TRUE;
538         break;
539 
540       //
541       // -b   Print the internal database list to a file
542       //
543       case 'b':
544       case 'B':
545         //
546         // Check for one more arg
547         //
548         if (Argc < 2) {
549           Error (NULL, 0, 0, Argv[0], "must specify file name with option");
550           Usage ();
551           return STATUS_ERROR;
552         }
553 
554         strcpy (gOptions.DatabaseOutputFileName, Argv[1]);
555         Argc--;
556         Argv++;
557         break;
558 
559       default:
560         Error (NULL, 0, 0, Argv[0], "invalid option");
561         Usage ();
562         return STATUS_ERROR;
563       }
564     } else {
565       break;
566     }
567     //
568     // Next arg
569     //
570     Argc--;
571     Argv++;
572   }
573 
574   if (Argc > 0) {
575     Error (NULL, 0, 0, Argv[0], "invalid argument");
576     Usage ();
577     return STATUS_ERROR;
578   }
579   //
580   // Have to check signatures, GUIDs, or dump the GUID database.
581   //
582   if ((!gOptions.CheckGuids) && (!gOptions.CheckSignatures) && (gOptions.DatabaseOutputFileName[0] == 0)) {
583     Error (NULL, 0, 0, "nothing to do", "must specify -g, -s, and/or -b");
584     Usage ();
585     return STATUS_ERROR;
586   }
587 
588   return STATUS_SUCCESS;
589 }
590 //
591 // Print usage instructions
592 //
593 static
594 VOID
Usage(VOID)595 Usage (
596   VOID
597   )
598 {
599   int         Index;
600   const char  *Str[] = {
601     UTILITY_NAME" "UTILITY_VERSION" - Intel GUID Check Utility",
602     "  Copyright (C), 2004 - 2008 Intel Corporation",
603 
604 #if ( defined(UTILITY_BUILD) && defined(UTILITY_VENDOR) )
605     "  Built from "UTILITY_BUILD", project of "UTILITY_VENDOR,
606 #endif
607     "",
608     "Usage:",
609     "  "UTILITY_NAME" [OPTION]...",
610     "Description:",
611     "  Scan files for duplicate GUID or signature definitions.",
612     "Options:",
613     "  -d dirname     exclude searching of a directory",
614     "  -f filename    exclude searching of a file",
615     "  -e extension   exclude searching of files by extension",
616     "  -p             print all GUIDS found",
617     "  -g             check for duplicate guids",
618     "  -s             check for duplicate signatures",
619     "  -x             print guid+defined symbol name",
620     "  -b outfile     write internal GUID+basename list to outfile",
621     "  -u dirname     exclude searching all subdirectories of a directory",
622     "  -h -?          print this help text",
623     "Example Usage:",
624     "  GuidChk -g -u build -d fv -f make.inf -e .pkg",
625     NULL
626   };
627   for (Index = 0; Str[Index] != NULL; Index++) {
628     fprintf (stdout, "%s\n", Str[Index]);
629   }
630 }
631 //
632 // Process an entire directory by name
633 //
634 static
635 STATUS
ProcessDirectory(INT8 * Path,INT8 * DirectoryName)636 ProcessDirectory (
637   INT8          *Path,
638   INT8          *DirectoryName
639   )
640 {
641   FILE_SEARCH_DATA  FSData;
642   char              *FileMask;
643   BOOLEAN           Done;
644   UINT32            Len;
645   BOOLEAN           NoSubdirs;
646   STRING_LIST       *SLPtr;
647 
648   //
649   // Root directory may be null
650   //
651   if (DirectoryName != NULL) {
652     //
653     // printf ("Processing directory: %s\n", DirectoryName);
654     //
655   }
656   //
657   // Initialize our file searching
658   //
659   FileSearchInit (&FSData);
660 
661   //
662   // Exclude some directories, files, and extensions
663   //
664   FileSearchExcludeDirs (&FSData, gOptions.ExcludeDirs);
665   FileSearchExcludeExtensions (&FSData, gOptions.ExcludeExtensions);
666   FileSearchExcludeFiles (&FSData, gOptions.ExcludeFiles);
667   //
668   // See if this directory is in the list of directories that they
669   // don't want to process subdirectories of
670   //
671   NoSubdirs = FALSE;
672   if (DirectoryName != NULL) {
673     for (SLPtr = gOptions.ExcludeSubDirs; SLPtr != NULL; SLPtr = SLPtr->Next) {
674       if (_stricmp (SLPtr->Str, DirectoryName) == 0) {
675         //
676         // printf ("not processing subdirectories of %s\n", DirectoryName);
677         //
678         NoSubdirs = TRUE;
679         break;
680       }
681     }
682   }
683   //
684   // Create a filemask of files to search for. We'll append "\*.*" on the
685   // end, so allocate some extra bytes.
686   //
687   Len = strlen (Path) + 10;
688   if (DirectoryName != NULL) {
689     Len += strlen (DirectoryName);
690   }
691 
692   FileMask = malloc (Len);
693   if (FileMask == NULL) {
694     Error (NULL, 0, 0, "memory allocation failure", NULL);
695     return STATUS_ERROR;
696   }
697   //
698   // Now put it all together
699   //
700   strcpy (FileMask, Path);
701   if ((DirectoryName != NULL) && (strlen (DirectoryName) > 0)) {
702     strcat (FileMask, "\\");
703     strcat (FileMask, DirectoryName);
704   }
705 
706   strcat (FileMask, "\\*.*");
707 
708   //
709   // Start file searching for files and directories
710   //
711   if (FileSearchStart (&FSData, FileMask, FILE_SEARCH_FILE | FILE_SEARCH_DIR) == STATUS_SUCCESS) {
712     Done = FALSE;
713   } else {
714     Done = TRUE;
715   }
716 
717   //
718   // Now hack the "\*.*" off the end of the filemask so we can use it to pass
719   // the full directory path on recursive calls to process directories.
720   //
721   FileMask[strlen (FileMask) - 4] = 0;
722 
723   //
724   // Loop until no more files
725   //
726   while (!Done) {
727     //
728     // printf ("Found %s...", FSData.FileName);
729     //
730     if (FSData.FileFlags & FILE_SEARCH_DIR) {
731       //
732       // printf ("directory\n");
733       //
734       if (!NoSubdirs) {
735         ProcessDirectory (FileMask, FSData.FileName);
736       }
737     } else if (FSData.FileFlags & FILE_SEARCH_FILE) {
738       //
739       // printf ("file\n");
740       //
741       ProcessFile (FileMask, FSData.FileName);
742     } else {
743       //
744       // printf ("unknown\n");
745       //
746     }
747 
748     if (FileSearchFindNext (&FSData) != STATUS_SUCCESS) {
749       Done = TRUE;
750     }
751   }
752   //
753   // Free up allocated memory
754   //
755   free (FileMask);
756 
757   //
758   // Free up our file searching
759   //
760   FileSearchDestroy (&FSData);
761 
762   return STATUS_SUCCESS;
763 }
764 //
765 // Process a single file.
766 //
767 static
768 STATUS
ProcessFile(INT8 * DirectoryName,INT8 * FileName)769 ProcessFile (
770   INT8                *DirectoryName,
771   INT8                *FileName
772   )
773 {
774   STATUS  Status;
775   UINT32  FileExtension;
776   INT8    FullFileName[MAX_PATH];
777 
778   Status = STATUS_SUCCESS;
779 
780   sprintf (FullFileName, "%s\\%s", DirectoryName, FileName);
781   //
782   // printf ("Found file: %s\n", FullFileName);
783   //
784   FileExtension = GetFileExtension (FileName);
785 
786   //
787   // Process these for GUID checks
788   //
789   if (gOptions.CheckGuids) {
790     switch (FileExtension) {
791     case FILE_EXTENSION_C:
792     case FILE_EXTENSION_H:
793       Status = ProcessCFileGuids (FullFileName);
794       break;
795 
796     case FILE_EXTENSION_PKG:
797       Status = ProcessPkgFileGuids (FullFileName);
798       break;
799 
800     case FILE_EXTENSION_IA32_INC:
801     case FILE_EXTENSION_IA32_ASM:
802       Status = ProcessIA32FileGuids (FullFileName);
803       break;
804 
805     case FILE_EXTENSION_INF:
806       Status = ProcessINFFileGuids (FullFileName);
807       break;
808 
809     case FILE_EXTENSION_IA64_INC:
810     case FILE_EXTENSION_IA64_ASM:
811       Status = ProcessIA64FileGuids (FullFileName);
812       break;
813 
814     default:
815       //
816       // No errors anyway
817       //
818       Status = STATUS_SUCCESS;
819       break;
820     }
821   }
822 
823   if (gOptions.CheckSignatures) {
824     switch (FileExtension) {
825     case FILE_EXTENSION_C:
826     case FILE_EXTENSION_H:
827       Status = ProcessCFileSigs (FullFileName);
828       break;
829 
830     default:
831       //
832       // No errors anyway
833       //
834       Status = STATUS_SUCCESS;
835       break;
836     }
837   }
838 
839   return Status;
840 }
841 //
842 // Return a code indicating the file name extension.
843 //
844 static
845 UINT32
GetFileExtension(INT8 * FileName)846 GetFileExtension (
847   INT8        *FileName
848   )
849 {
850   INT8  *Extension;
851   int   Index;
852 
853   //
854   // Look back for a filename extension
855   //
856   for (Extension = FileName + strlen (FileName) - 1; Extension >= FileName; Extension--) {
857     if (*Extension == '.') {
858       for (Index = 0; FileTypeTable[Index].Extension != NULL; Index++) {
859         if (_stricmp (FileTypeTable[Index].Extension, Extension) == 0) {
860           return FileTypeTable[Index].ExtensionCode;
861         }
862       }
863     }
864   }
865 
866   return FILE_TYPE_UNKNOWN;
867 }
868 //
869 // Process a .pkg file.
870 //
871 // Look for FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
872 //
873 static
874 STATUS
ProcessPkgFileGuids(INT8 * FileName)875 ProcessPkgFileGuids (
876   INT8    *FileName
877   )
878 {
879   FILE    *Fptr;
880   INT8    Line[MAX_LINE_LEN * 2];
881   INT8    *Cptr;
882   INT8    *Cptr2;
883   UINT32  GuidScan[11];
884   UINT64  Guid64;
885 
886   if ((Fptr = fopen (FileName, "r")) == NULL) {
887     Error (NULL, 0, 0, FileName, "could not open input file for reading");
888     return STATUS_ERROR;
889   }
890   //
891   // Read lines from the file until done
892   //
893   while (fgets (Line, sizeof (Line), Fptr) != NULL) {
894     Cptr = Line;
895     Cptr += SkipWhiteSpace (Line);
896     if (strncmp (Cptr, "FFS_FILEGUID", 12) == 0) {
897       Cptr += 12;
898       Cptr += SkipWhiteSpace (Cptr);
899       if (*Cptr == '=') {
900         Cptr++;
901         Cptr += SkipWhiteSpace (Cptr + 1);
902         //
903         // Blank out dashes on the line.
904         //
905         for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
906           if (*Cptr2 == '-') {
907             *Cptr2 = ' ';
908           }
909         }
910 
911         if (sscanf (
912               Cptr,
913               "%X %X %X %X %I64X",
914               &GuidScan[0],
915               &GuidScan[1],
916               &GuidScan[2],
917               &GuidScan[3],
918               &Guid64
919               ) == 5) {
920           AddPkgGuid (FileName, GuidScan, &Guid64);
921         } else {
922           DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
923         }
924       }
925     }
926   }
927 
928   fclose (Fptr);
929   return STATUS_SUCCESS;
930 }
931 //
932 // Process an IA32 assembly file.
933 //
934 // Look for:
935 // FIND_FD_GUID_VAL equ  01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h, 01h
936 // PEI_GUID_FileNameGuid_Gmch815  equ  081818181h, 08181h, 08181h, 081h, 081h, 081h, 081h, 081h, 081h, 081h, 081h
937 //
938 static
939 STATUS
ProcessIA32FileGuids(INT8 * FileName)940 ProcessIA32FileGuids (
941   INT8    *FileName
942   )
943 {
944   FILE    *Fptr;
945   INT8    Line[MAX_LINE_LEN];
946   INT8    *Cptr;
947   INT8    CSave;
948   INT8    *CSavePtr;
949   UINT32  Len;
950   UINT32  GuidData[16];
951   UINT32  Index;
952 
953   if ((Fptr = fopen (FileName, "r")) == NULL) {
954     Error (NULL, 0, 0, FileName, "could not open input file for reading");
955     return STATUS_ERROR;
956   }
957   //
958   // Read lines from the file until done
959   //
960   while (fgets (Line, sizeof (Line), Fptr) != NULL) {
961     Cptr = Line;
962     Cptr += SkipWhiteSpace (Line);
963     //
964     // Look for xxxGUIDyyy equ 01h, 02h, 03h, ...
965     //
966     Len = ValidSymbolName (Cptr);
967     if (Len) {
968       //
969       // Terminate the line after the symbol name, then look for "guid" in
970       // the name.
971       //
972       CSavePtr  = Cptr + Len;
973       CSave     = *CSavePtr;
974       *CSavePtr = 0;
975       while (*Cptr) {
976         if (_strnicmp (Cptr, "guid", 4) == 0) {
977           break;
978         }
979 
980         Cptr++;
981       }
982       //
983       // If we found the string "guid", continue
984       //
985       if (*Cptr) {
986         //
987         // Restore the character on the line where we null-terminated the symbol
988         //
989         *CSavePtr = CSave;
990         Cptr      = CSavePtr;
991         Len       = SkipWhiteSpace (Cptr);
992         //
993         // Had to be some white space
994         //
995         if (Len) {
996           Cptr += Len;
997           //
998           // now look for "equ"
999           //
1000           if (_strnicmp (Cptr, "equ", 3) == 0) {
1001             Cptr += 3;
1002             Cptr += SkipWhiteSpace (Cptr);
1003             //
1004             // Now scan all the data
1005             //
1006             for (Index = 0; Index < 16; Index++) {
1007               if (sscanf (Cptr, "%X", &GuidData[Index]) != 1) {
1008                 break;
1009               }
1010               //
1011               // Skip to next
1012               //
1013               while (isxdigit (*Cptr)) {
1014                 Cptr++;
1015               }
1016 
1017               if ((*Cptr != 'h') && (*Cptr != 'H')) {
1018                 break;
1019               } else {
1020                 Cptr++;
1021                 while (*Cptr && (isspace (*Cptr) || (*Cptr == ','))) {
1022                   Cptr++;
1023                 }
1024               }
1025             }
1026             //
1027             // Now see which form we had
1028             //
1029             if (Index == 16) {
1030               AddGuid16 (FileName, GuidData);
1031             } else if (Index == 11) {
1032               AddGuid11 (FileName, GuidData, NULL);
1033             }
1034           }
1035         }
1036       }
1037     }
1038   }
1039 
1040   fclose (Fptr);
1041   return STATUS_SUCCESS;
1042 }
1043 //
1044 // Found and parsed an IA32 assembly code guid. Save the 16 bytes off in the list
1045 // of guids.
1046 //
1047 static
1048 STATUS
AddGuid16(INT8 * FileName,UINT32 * Data)1049 AddGuid16 (
1050   INT8      *FileName,
1051   UINT32    *Data
1052   )
1053 {
1054   GUID_RECORD *NewRec;
1055   int         Index;
1056 
1057   //
1058   // Sanity check the data
1059   //
1060   if (!CheckGuidData (Data, 16)) {
1061     return STATUS_ERROR;
1062   }
1063   //
1064   // Allocate memory for a new guid structure
1065   //
1066   NewRec = malloc (sizeof (GUID_RECORD));
1067   if (NewRec == NULL) {
1068     Error (NULL, 0, 0, "memory allocation failure", NULL);
1069     return STATUS_ERROR;
1070   }
1071 
1072   memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1073   NewRec->FileName = malloc (strlen (FileName) + 1);
1074   if (NewRec->FileName == NULL) {
1075     free (NewRec);
1076     Error (NULL, 0, 0, "memory allocation failure", NULL);
1077     return STATUS_ERROR;
1078   }
1079 
1080   strcpy (NewRec->FileName, FileName);
1081   NewRec->Guid.Data1  = (UINT32) (Data[0] | (Data[1] << 8) | (Data[2] << 16) | (Data[3] << 24));
1082   NewRec->Guid.Data2  = (UINT16) (Data[4] | (Data[5] << 8));
1083   NewRec->Guid.Data3  = (UINT16) (Data[6] | (Data[7] << 8));
1084   for (Index = 0; Index < 8; Index++) {
1085     NewRec->Guid.Data4[Index] = (UINT8) Data[Index + 8];
1086   }
1087   //
1088   // Add it to the list
1089   //
1090   NewRec->Next  = gGuidList;
1091   gGuidList     = NewRec;
1092 
1093   //
1094   // Report it
1095   // ReportGuid (FileName, NewRec);
1096   //
1097   return STATUS_SUCCESS;
1098 }
1099 //
1100 // Add a GUID defined as GuidLow: 0x1122334455667788
1101 //                       GuidHi:  0x99AABBCCDDEEFF00
1102 //
1103 // These are equivalent:
1104 // { 0x11223344, 0x5566, 0x7788, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00 }
1105 //    and:
1106 // Low: 00FFEEDDCCBBAA99
1107 // Hi:  7788556611223344
1108 //
1109 static
1110 STATUS
AddGuid64x2(INT8 * FileName,UINT32 DataHH,UINT32 DataHL,UINT32 DataLH,UINT32 DataLL,INT8 * SymName)1111 AddGuid64x2 (
1112   INT8      *FileName,
1113   UINT32    DataHH, // Upper 32-bits of upper 64 bits of guid
1114   UINT32    DataHL, // Lower 32-bits of upper 64 bits
1115   UINT32    DataLH,
1116   UINT32    DataLL,
1117   INT8      *SymName
1118   )
1119 {
1120   GUID_RECORD *NewRec;
1121   int         Index;
1122 
1123   //
1124   // Allocate memory for a new guid structure
1125   //
1126   NewRec = malloc (sizeof (GUID_RECORD));
1127   if (NewRec == NULL) {
1128     Error (NULL, 0, 0, "memory allocation failure", NULL);
1129     return STATUS_ERROR;
1130   }
1131 
1132   memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1133   NewRec->FileName = malloc (strlen (FileName) + 1);
1134   if (NewRec->FileName == NULL) {
1135     free (NewRec);
1136     Error (NULL, 0, 0, "memory allocation failure", NULL);
1137     return STATUS_ERROR;
1138   }
1139 
1140   strcpy (NewRec->FileName, FileName);
1141   NewRec->Guid.Data1  = DataHL;
1142   NewRec->Guid.Data2  = (UINT16) DataHH;
1143   NewRec->Guid.Data3  = (UINT16) (DataHH >> 16);
1144   for (Index = 0; Index < 4; Index++) {
1145     NewRec->Guid.Data4[Index] = (UINT8) DataLL;
1146     DataLL >>= 8;
1147   }
1148 
1149   for (Index = 0; Index < 4; Index++) {
1150     NewRec->Guid.Data4[Index + 4] = (UINT8) DataLH;
1151     DataLH >>= 8;
1152   }
1153 
1154   if (SymName != NULL) {
1155     NewRec->SymName = malloc (strlen (SymName) + 1);
1156     if (NewRec->SymName == NULL) {
1157       free (NewRec);
1158       Error (NULL, 0, 0, "memory allocation failure", NULL);
1159       return STATUS_ERROR;
1160     }
1161     strcpy (NewRec->SymName, SymName);
1162   }
1163 
1164   //
1165   // Add it to the list
1166   //
1167   NewRec->Next  = gGuidList;
1168   gGuidList     = NewRec;
1169 
1170   //
1171   // Report it
1172   // ReportGuid (FileName, NewRec);
1173   //
1174   return STATUS_SUCCESS;
1175 }
1176 //
1177 // Process INF files. Look for:
1178 // FILE_GUID            = 240612B6-A063-11d4-9A3A-0090273FC14D
1179 //
1180 static
1181 STATUS
ProcessINFFileGuids(INT8 * FileName)1182 ProcessINFFileGuids (
1183   INT8    *FileName
1184   )
1185 {
1186   FILE    *Fptr;
1187   INT8    Line[MAX_LINE_LEN * 2];
1188   INT8    *Cptr;
1189   INT8    *Cptr2;
1190   UINT32  GuidScan[11];
1191   UINT64  Guid64;
1192 
1193   if ((Fptr = fopen (FileName, "r")) == NULL) {
1194     Error (NULL, 0, 0, FileName, "could not open input file for reading");
1195     return STATUS_ERROR;
1196   }
1197   //
1198   // Read lines from the file until done
1199   //
1200   while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1201     Cptr = Line;
1202     Cptr += SkipWhiteSpace (Line);
1203     if (strncmp (Cptr, "FILE_GUID", 9) == 0) {
1204       Cptr += 9;
1205       Cptr += SkipWhiteSpace (Cptr);
1206       if (*Cptr == '=') {
1207         Cptr++;
1208         Cptr += SkipWhiteSpace (Cptr + 1);
1209         //
1210         // Blank out dashes on the line.
1211         //
1212         for (Cptr2 = Cptr; *Cptr2; Cptr2++) {
1213           if (*Cptr2 == '-') {
1214             *Cptr2 = ' ';
1215           }
1216         }
1217 
1218         if (sscanf (
1219               Cptr,
1220               "%X %X %X %X %I64X",
1221               &GuidScan[0],
1222               &GuidScan[1],
1223               &GuidScan[2],
1224               &GuidScan[3],
1225               &Guid64
1226               ) == 5) {
1227           AddPkgGuid (FileName, GuidScan, &Guid64);
1228         } else {
1229           DebugMsg (NULL, 0, 0, FileName, "GUID scan failed");
1230         }
1231       }
1232     }
1233   }
1234 
1235   fclose (Fptr);
1236   return STATUS_SUCCESS;
1237 }
1238 //
1239 // Parse ('g','m','a','p','a','b','c','d')
1240 //
1241 static
1242 STATUS
AddSignature(INT8 * FileName,INT8 * StrDef,UINT32 SigSize)1243 AddSignature (
1244   INT8      *FileName,
1245   INT8      *StrDef,
1246   UINT32    SigSize
1247   )
1248 {
1249   SIGNATURE_RECORD  *NewRec;
1250   INT8              *Cptr;
1251   UINT32            Index;
1252   BOOLEAN           Fail;
1253 
1254   //
1255   // Allocate memory for the new record
1256   //
1257   Fail    = FALSE;
1258   NewRec  = malloc (sizeof (SIGNATURE_RECORD));
1259 
1260   if (NewRec == NULL) {
1261     Error (NULL, 0, 0, "memory allocation failure", NULL);
1262     return STATUS_ERROR;
1263   }
1264   memset ((char *) NewRec, 0, sizeof (SIGNATURE_RECORD));
1265 
1266   //
1267   // Allocate memory to save the file name
1268   //
1269   NewRec->FileName = malloc (strlen (FileName) + 1);
1270   if (NewRec->FileName == NULL) {
1271     Error (NULL, 0, 0, "memory allocation failure", NULL);
1272     free (NewRec);
1273     return STATUS_ERROR;
1274   }
1275   //
1276   // Fill in the fields
1277   //
1278   strcpy (NewRec->FileName, FileName);
1279   NewRec->Signature.DataLen = (UINT8) SigSize;
1280   //
1281   // Skip to open parenthesis
1282   //
1283   Cptr = StrDef;
1284   Cptr += SkipWhiteSpace (Cptr);
1285   if (*Cptr != '(') {
1286     Fail = TRUE;
1287     goto Done;
1288   }
1289 
1290   Cptr++;
1291   //
1292   // Skip to first ' and start processing
1293   //
1294   while (*Cptr && (*Cptr != '\'')) {
1295     Cptr++;
1296   }
1297 
1298   for (Index = 0; Index < SigSize; Index++) {
1299     if (*Cptr == '\'') {
1300       Cptr++;
1301       NewRec->Signature.Data[Index] = (INT8) *Cptr;
1302       //
1303       // Skip to closing quote
1304       //
1305       Cptr++;
1306       if (*Cptr != '\'') {
1307         Fail = TRUE;
1308         break;
1309       }
1310       //
1311       // Skip over closing quote, go to next one
1312       //
1313       Cptr++;
1314       while (*Cptr && (*Cptr != '\'')) {
1315         Cptr++;
1316       }
1317     } else {
1318       Fail = TRUE;
1319       DebugMsg (NULL, 0, 0, FileName, "failed to parse signature");
1320       break;
1321     }
1322   }
1323 
1324 Done:
1325   if (Fail) {
1326     free (NewRec->FileName);
1327     free (NewRec);
1328     return STATUS_ERROR;
1329   }
1330 
1331   NewRec->Next    = gSignatureList;
1332   gSignatureList  = NewRec;
1333   return STATUS_SUCCESS;
1334 }
1335 //
1336 // Look for:
1337 // #define POOL_HEAD_SIGNATURE         EFI_SIGNATURE_16('p','h')
1338 // #define GCD_MEMORY_MAP_SIGNATURE    EFI_SIGNATURE_32('g','m','a','p')
1339 // #define GCD_MEMORY_MAP_SIGNATURE    EFI_SIGNATURE_64('g','m','a','p','a','b','c','d')
1340 //
1341 static
1342 STATUS
ProcessCFileSigs(INT8 * FileName)1343 ProcessCFileSigs (
1344   INT8    *FileName
1345   )
1346 {
1347   FILE    *Fptr;
1348   INT8    Line[MAX_LINE_LEN * 2];
1349   INT8    *Cptr;
1350   UINT32  Len;
1351 
1352   if ((Fptr = fopen (FileName, "r")) == NULL) {
1353     Error (NULL, 0, 0, FileName, "could not open input file for reading");
1354     return STATUS_ERROR;
1355   }
1356   //
1357   // Read lines from the file until done
1358   //
1359   while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1360     Cptr = Line;
1361     Cptr += SkipWhiteSpace (Line);
1362     //
1363     // look for #define EFI_SIGNATURE_xx value
1364     //
1365     if (*Cptr == '#') {
1366       Cptr++;
1367       Cptr += SkipWhiteSpace (Cptr);
1368       //
1369       // Look for "define"
1370       //
1371       if (!strncmp (Cptr, "define", 6)) {
1372         Cptr += 6;
1373         //
1374         // Better be whitespace
1375         //
1376         Len = SkipWhiteSpace (Cptr);
1377         if (Len) {
1378           Cptr += Len;
1379           //
1380           // See if it's a valid symbol name
1381           //
1382           Len = ValidSymbolName (Cptr);
1383           if (Len) {
1384             //
1385             // It is a valid symbol name. See if there's line continuation,
1386             // and if so, read more lines.
1387             // Skip over the symbol name and look for the string "EFI_SIGNATURE_xx"
1388             //
1389             ConcatenateLines (Fptr, Line, sizeof(Line));
1390 
1391             Cptr += Len;
1392             Cptr += SkipWhiteSpace (Cptr);
1393             if (strncmp (Cptr, "EFI_SIGNATURE_16", 16) == 0) {
1394               AddSignature (FileName, Cptr + 16, 2);
1395             } else if (strncmp (Cptr, "EFI_SIGNATURE_32", 16) == 0) {
1396               AddSignature (FileName, Cptr + 16, 4);
1397             } else if (strncmp (Cptr, "EFI_SIGNATURE_64", 16) == 0) {
1398               AddSignature (FileName, Cptr + 16, 8);
1399             }
1400           }
1401         }
1402       }
1403     }
1404   }
1405 
1406   fclose (Fptr);
1407   return STATUS_SUCCESS;
1408 }
1409 //
1410 // look for #define xxxGUIDyyy { 0x...}
1411 // xxx EFI_GUID  GuidName = { 0x... };
1412 //
1413 static
1414 STATUS
ProcessCFileGuids(INT8 * FileName)1415 ProcessCFileGuids (
1416   INT8    *FileName
1417   )
1418 {
1419   FILE    *Fptr;
1420   INT8    Line[MAX_LINE_LEN * 2];
1421   INT8    *Cptr;
1422   INT8    *CSavePtr;
1423   INT8    *TempCptr;
1424   INT8    *SymName;
1425   UINT32  Len;
1426   UINT32  LineLen;
1427   UINT32  GuidScan[11];
1428 
1429   if ((Fptr = fopen (FileName, "r")) == NULL) {
1430     Error (NULL, 0, 0, FileName, "could not open input file for reading");
1431     return STATUS_ERROR;
1432   }
1433   //
1434   // Read lines from the file until done
1435   //
1436   while (fgets (Line, sizeof (Line), Fptr) != NULL) {
1437     Cptr = Line;
1438     Cptr += SkipWhiteSpace (Line);
1439     //
1440     // look for #define xxxGUIDxxx value
1441     //
1442     if (*Cptr == '#') {
1443       Cptr++;
1444       Cptr += SkipWhiteSpace (Cptr);
1445       //
1446       // Look for "define"
1447       //
1448       if (!strncmp (Cptr, "define", 6)) {
1449 DefineLine:
1450         Cptr += 6;
1451         //
1452         // Better be whitespace
1453         //
1454         Len = SkipWhiteSpace (Cptr);
1455         if (Len) {
1456           Cptr += Len;
1457           //
1458           // See if it's a valid symbol name
1459           //
1460           Len = ValidSymbolName (Cptr);
1461           if (Len) {
1462             //
1463             // It is a valid symbol name. See if there's line continuation,
1464             // and if so, read more lines.
1465             // Then truncate after the symbol name, look for the string "GUID",
1466             // and continue.
1467             //
1468             SymName = Cptr;
1469             ConcatenateLines (Fptr, Line, sizeof(Line));
1470 
1471             //
1472             // Now look for { 0x....... }
1473             //
1474             CSavePtr  = Cptr + Len;
1475             Cptr += Len;
1476             Cptr += SkipWhiteSpace (Cptr);
1477             if (*Cptr == '{') {
1478               Cptr++;
1479               //
1480               // Blank out 'L', 'l', '{', '}', ',' on the line.
1481               //
1482               for (TempCptr = Cptr; *TempCptr; TempCptr++) {
1483                 if ((*TempCptr == 'L') || (*TempCptr == 'l') || (*TempCptr == '{') ||
1484                     (*TempCptr == '}') || (*TempCptr == ',')) {
1485                   *TempCptr       = ' ';
1486                 }
1487               }
1488 
1489               if (sscanf (
1490                     Cptr,
1491                     "%X %X %X %X %X %X %X %X %X %X %X",
1492                     &GuidScan[0],
1493                     &GuidScan[1],
1494                     &GuidScan[2],
1495                     &GuidScan[3],
1496                     &GuidScan[4],
1497                     &GuidScan[5],
1498                     &GuidScan[6],
1499                     &GuidScan[7],
1500                     &GuidScan[8],
1501                     &GuidScan[9],
1502                     &GuidScan[10]
1503                     ) == 11) {
1504                 *CSavePtr = '\0';
1505                 AddGuid11 (FileName, GuidScan, SymName);
1506               }
1507             }
1508           }
1509         }
1510       }
1511     //
1512     // Else look for "static EFI_GUID xxxGUIDxxx = { 0x.... };
1513     //
1514     } else if ((CSavePtr = strstr (Line, "EFI_GUID")) != NULL) {
1515       //
1516       // Read more lines until met ';'
1517       //
1518       ConcatenateLines (Fptr, Line, sizeof(Line));
1519       while (strstr (Line, ";") == NULL) {
1520         LineLen = strlen (Line);
1521         Len = sizeof(Line) - LineLen;
1522         if (Len <= 1) {
1523           break;
1524         }
1525         if (Line[LineLen - 1] == '\n') {
1526           Cptr = Line + LineLen - 1;
1527           *Cptr = '\0';
1528           if (fgets (Cptr, Len, Fptr) == NULL){
1529             break;
1530           }
1531           ConcatenateLines (Fptr, Line, sizeof(Line));
1532         } else {
1533           Cptr = Line + LineLen;
1534           *Cptr = '\0';
1535           if (fgets (Cptr, Len, Fptr) == NULL) {
1536             break;
1537           }
1538           ConcatenateLines (Fptr, Line, sizeof(Line));
1539         }
1540 
1541         //
1542         // EFI_GUID may appear in comments wihout end of ';' which may cause
1543         // ignoring of new #define, so handle it here.
1544         //
1545         Cptr += SkipWhiteSpace (Cptr);
1546         if (*Cptr == '#') {
1547           Cptr++;
1548           Cptr += SkipWhiteSpace (Cptr);
1549           if (!strncmp (Cptr, "define", 6)) {
1550             goto DefineLine;
1551           }
1552         }
1553       }
1554 
1555       Cptr = CSavePtr + 8;
1556       Cptr += SkipWhiteSpace (Cptr);
1557       //
1558       // Should be variable name next
1559       //
1560       Len     = ValidSymbolName (Cptr);
1561       SymName = Cptr;
1562       Cptr += Len;
1563       CSavePtr = Cptr;
1564       Cptr += SkipWhiteSpace (Cptr);
1565       if (*Cptr == '=') {
1566         *CSavePtr = '\0';
1567         Cptr++;
1568         Cptr += SkipWhiteSpace (Cptr);
1569         //
1570         // Should be open-brace next to define guid
1571         //
1572         if (*Cptr == '{') {
1573           Cptr++;
1574           //
1575           // Blank out 'L', 'l', '{', '}', ',' on the line.
1576           //
1577           for (TempCptr = Cptr; *TempCptr; TempCptr++) {
1578             if ((*TempCptr == 'L') || (*TempCptr == 'l') || (*TempCptr == '{') ||
1579                 (*TempCptr == '}') || (*TempCptr == ',')) {
1580               *TempCptr       = ' ';
1581             }
1582           }
1583 
1584           if (sscanf (
1585                 Cptr,
1586                 "%X %X %X %X %X %X %X %X %X %X %X",
1587                 &GuidScan[0],
1588                 &GuidScan[1],
1589                 &GuidScan[2],
1590                 &GuidScan[3],
1591                 &GuidScan[4],
1592                 &GuidScan[5],
1593                 &GuidScan[6],
1594                 &GuidScan[7],
1595                 &GuidScan[8],
1596                 &GuidScan[9],
1597                 &GuidScan[10]
1598                 ) == 11) {
1599             AddGuid11 (FileName, GuidScan, SymName);
1600           }
1601         }
1602       }
1603     }
1604   }
1605 
1606   fclose (Fptr);
1607   return STATUS_SUCCESS;
1608 }
1609 //
1610 // Process Intel Itanium(TM) GUID definitions. Look for:
1611 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1612 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1613 // in either order.
1614 // This function assumes no blank lines between definitions.
1615 //
1616 static
1617 STATUS
ProcessIA64FileGuids(INT8 * FileName)1618 ProcessIA64FileGuids (
1619   INT8    *FileName
1620   )
1621 {
1622   FILE    *Fptr;
1623   INT8    Line[MAX_LINE_LEN];
1624   UINT32  Guid1H;
1625   UINT32  Guid1L;
1626   UINT32  Guid2H;
1627   UINT32  Guid2L;
1628   INT8    SymName1[MAX_LINE_LEN];
1629   INT8    SymName2[MAX_LINE_LEN];
1630   BOOLEAN Done;
1631   BOOLEAN LowFirst;
1632   BOOLEAN FoundLow;
1633 
1634   if ((Fptr = fopen (FileName, "r")) == NULL) {
1635     Error (NULL, 0, 0, FileName, "could not open input file for reading");
1636     return STATUS_ERROR;
1637   }
1638 
1639   Done = FALSE;
1640   if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1641     Done = 1;
1642   }
1643   //
1644   // Read lines from the file until done. Since the guid definition takes
1645   // two lines, we read lines in different places to recover gracefully
1646   // from mismatches. For example, if you thought you found the first half,
1647   // but the next line had a symbol mismatch, then you have to process the
1648   // line again in case it's the start of a new definition.
1649   //
1650   while (!Done) {
1651     //
1652     // Check current line for GUID definition. Assume low define first.
1653     //
1654     if (IsIA64GuidLine (Line, &Guid1H, &Guid1L, &FoundLow, SymName1)) {
1655       //
1656       // Might have to swap guids later. Save off if we found the LOW first
1657       //
1658       if (FoundLow) {
1659         LowFirst = TRUE;
1660       } else {
1661         LowFirst = FALSE;
1662       }
1663       //
1664       // Read the next line and try for the rest of the guid definition
1665       //
1666       if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1667         Done = 1;
1668       } else {
1669         if (IsIA64GuidLine (Line, &Guid2H, &Guid2L, &FoundLow, SymName2)) {
1670           //
1671           // Found another. If the symbol names match, then save it off.
1672           //
1673           if (strcmp (SymName1, SymName2) == 0) {
1674             //
1675             // Yea, found one. Save it off.
1676             //
1677             if (LowFirst) {
1678               AddGuid64x2 (FileName, Guid2H, Guid2L, Guid1H, Guid1L, SymName1);
1679             } else {
1680               AddGuid64x2 (FileName, Guid1H, Guid1L, Guid2H, Guid2L, SymName1);
1681             }
1682             //
1683             // Read the next line for processing
1684             //
1685             if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1686               Done = 1;
1687             }
1688           } else {
1689             //
1690             // Don't get another line so that we reprocess this line in case it
1691             // contains the start of a new definition.
1692             // fprintf (stdout, "Symbol name mismatch: %s: %s != %s\n",
1693             //    FileName, SymName1, SymName2);
1694             //
1695           }
1696         } else {
1697           //
1698           // Second line was not a guid definition. Get the next line from the
1699           // file.
1700           //
1701           if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1702             Done = 1;
1703           }
1704         }
1705       }
1706     } else {
1707       //
1708       // Not a guid define line. Next.
1709       //
1710       if (fgets (Line, sizeof (Line), Fptr) == NULL) {
1711         Done = 1;
1712       }
1713     }
1714   }
1715 
1716   fclose (Fptr);
1717   return STATUS_SUCCESS;
1718 }
1719 //
1720 // Given a line from an Itanium-based assembly file, check the line for a guid
1721 // defininition. One of either:
1722 // #define Cs870MemoryTestPEIMGuidL 0x9C2403386E1C8FAA
1723 // #define Cs870MemoryTestPEIMGuidH 0xE89E95C6180342f0
1724 // Return the defined value as two 32-bit values, and whether it's a high
1725 // or low guid.
1726 //
1727 static
1728 BOOLEAN
IsIA64GuidLine(INT8 * Line,UINT32 * GuidHigh,UINT32 * GuidLow,BOOLEAN * FoundLow,INT8 * SymName)1729 IsIA64GuidLine (
1730   INT8      *Line,
1731   UINT32    *GuidHigh,
1732   UINT32    *GuidLow,
1733   BOOLEAN   *FoundLow,
1734   INT8      *SymName
1735   )
1736 {
1737   INT8    *Cptr;
1738   INT8    CSave;
1739   INT8    *CSavePtr;
1740   INT8    *SymStart;
1741   UINT32  Len;
1742 
1743   Cptr = Line;
1744   Cptr += SkipWhiteSpace (Cptr);
1745   //
1746   // look for #define xxxGUID[L|H] 0xHexValue
1747   //
1748   if (*Cptr == '#') {
1749     Cptr++;
1750     Cptr += SkipWhiteSpace (Cptr);
1751     //
1752     // Look for "define"
1753     //
1754     if (!strncmp (Cptr, "define", 6)) {
1755       Cptr += 6;
1756       //
1757       // Better be whitespace
1758       //
1759       Len = SkipWhiteSpace (Cptr);
1760       if (Len) {
1761         Cptr += Len;
1762         //
1763         // See if it's a valid symbol name
1764         //
1765         Len = ValidSymbolName (Cptr);
1766         if (Len) {
1767           //
1768           // Save the start so we can copy it to their string if later checks are ok
1769           //
1770           SymStart = Cptr;
1771           //
1772           // It is a valid symbol name, look for the string GuidL or GuidH
1773           //
1774           CSavePtr  = Cptr + Len;
1775           CSave     = *CSavePtr;
1776           *CSavePtr = 0;
1777           while (*Cptr) {
1778             if (strncmp (Cptr, "GuidL", 5) == 0) {
1779               *FoundLow = 1;
1780               break;
1781             } else if (strncmp (Cptr, "GuidH", 5) == 0) {
1782               *FoundLow = 0;
1783               break;
1784             }
1785 
1786             Cptr++;
1787           }
1788           //
1789           // If we didn't run out of string, then we found the GUID string.
1790           // Restore the null character we inserted above and continue.
1791           // Now look for  0x.......
1792           //
1793           if (*Cptr) {
1794             //
1795             // Return symbol name less the "L" or "H"
1796             //
1797             strcpy (SymName, SymStart);
1798             SymName[strlen (SymName) - 1] = 0;
1799             Cptr                          = CSavePtr;
1800             *CSavePtr                     = CSave;
1801             Cptr += SkipWhiteSpace (Cptr);
1802             if ((*Cptr == '0') && (*(Cptr + 1) == 'x')) {
1803               //
1804               // skip over "0x"
1805               //
1806               Cptr += 2;
1807               //
1808               // 0x0123456789ABCDEF -- null terminate after 8 characters,
1809               // scan, replace the character and scan at that point.
1810               //
1811               CSave       = *(Cptr + 8);
1812               *(Cptr + 8) = 0;
1813               if (sscanf (Cptr, "%X", GuidHigh) == 1) {
1814                 *(Cptr + 8) = CSave;
1815                 if (sscanf (Cptr + 8, "%X", GuidLow) == 1) {
1816                   return TRUE;
1817                 }
1818               }
1819             }
1820           }
1821         }
1822       }
1823     }
1824   }
1825 
1826   return FALSE;
1827 }
1828 //
1829 // Look at the characters in the string and determine if it's a valid
1830 // symbol name. Basically [a-zA-Z_][a-zA-Z_0-9]*
1831 //
1832 static
1833 UINT32
ValidSymbolName(INT8 * Name)1834 ValidSymbolName (
1835   INT8    *Name
1836   )
1837 {
1838   int Len;
1839 
1840   Len = 0;
1841 
1842   //
1843   // Test first character
1844   //
1845   if (((*Name >= 'a') && (*Name <= 'z')) || ((*Name >= 'A') && (*Name <= 'Z')) || (*Name == '_')) {
1846     Name++;
1847     Len = 1;
1848     while (*Name) {
1849       if (((*Name >= 'a') && (*Name <= 'z')) ||
1850           ((*Name >= 'A') && (*Name <= 'Z')) ||
1851           ((*Name >= '0') && (*Name <= '9')) ||
1852           (*Name == '_')
1853           ) {
1854         Name++;
1855         Len++;
1856       } else {
1857         break;
1858       }
1859     }
1860   }
1861 
1862   return Len;
1863 }
1864 
1865 static
1866 UINT32
SkipWhiteSpace(INT8 * Str)1867 SkipWhiteSpace (
1868   INT8    *Str
1869   )
1870 {
1871   UINT32  Len;
1872   Len = 0;
1873   while (isspace (*Str) && *Str) {
1874     Len++;
1875     Str++;
1876   }
1877 
1878   return Len;
1879 }
1880 //
1881 // found FFS_FILEGUID=35b898ca-b6a9-49ce-8c72-904735cc49b7
1882 //
1883 static
1884 STATUS
AddPkgGuid(INT8 * FileName,UINT32 * Data,UINT64 * Data64)1885 AddPkgGuid (
1886   INT8      *FileName,
1887   UINT32    *Data,
1888   UINT64    *Data64
1889   )
1890 {
1891   GUID_RECORD *NewRec;
1892   int         Index;
1893 
1894   //
1895   // Sanity check the data
1896   //
1897   if ((Data[1] | Data[2] | Data[3]) & 0xFFFF0000) {
1898     Error (NULL, 0, 0, "out of range value for GUID data word(s) [1] - [3]", NULL);
1899     return STATUS_ERROR;
1900   }
1901   //
1902   // More checks for Data64?
1903   // Allocate memory for a new one guid structure
1904   //
1905   NewRec = malloc (sizeof (GUID_RECORD));
1906   if (NewRec == NULL) {
1907     Error (NULL, 0, 0, "memory allocation failure", NULL);
1908     return STATUS_ERROR;
1909   }
1910 
1911   memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1912   NewRec->FileName = malloc (strlen (FileName) + 1);
1913   if (NewRec->FileName == NULL) {
1914     free (NewRec);
1915     Error (NULL, 0, 0, "memory allocation failure", NULL);
1916     return STATUS_ERROR;
1917   }
1918 
1919   strcpy (NewRec->FileName, FileName);
1920   NewRec->Guid.Data1    = Data[0];
1921   NewRec->Guid.Data2    = (UINT16) Data[1];
1922   NewRec->Guid.Data3    = (UINT16) Data[2];
1923   NewRec->Guid.Data4[0] = (UINT8) (Data[3] >> 8);
1924   NewRec->Guid.Data4[1] = (UINT8) Data[3];
1925   for (Index = 2; Index < 8; Index++) {
1926     NewRec->Guid.Data4[Index] = ((UINT8*)Data64)[7-Index];
1927   }
1928   //
1929   // Add it to the list
1930   //
1931   NewRec->Next  = gGuidList;
1932   gGuidList     = NewRec;
1933 
1934   //
1935   // Report it
1936   // ReportGuid (FileName, NewRec);
1937   //
1938   return STATUS_SUCCESS;
1939 }
1940 //
1941 // Add a guid consisting of 11 fields to our list of guids
1942 //
1943 static
1944 STATUS
AddGuid11(INT8 * FileName,UINT32 * Data,INT8 * SymName)1945 AddGuid11 (
1946   INT8      *FileName,
1947   UINT32    *Data,
1948   INT8      *SymName
1949   )
1950 {
1951   GUID_RECORD *NewRec;
1952   int         Index;
1953 
1954   //
1955   // Sanity check the data
1956   //
1957   if (!CheckGuidData (Data, 11)) {
1958     return STATUS_ERROR;
1959   }
1960   //
1961   // Allocate memory for a new one guid structure
1962   //
1963   NewRec = malloc (sizeof (GUID_RECORD));
1964   if (NewRec == NULL) {
1965     Error (NULL, 0, 0, "memory allocation failure", NULL);
1966     return STATUS_ERROR;
1967   }
1968 
1969   memset ((char *) NewRec, 0, sizeof (GUID_RECORD));
1970   NewRec->FileName = malloc (strlen (FileName) + 1);
1971   if (NewRec->FileName == NULL) {
1972     free (NewRec);
1973     Error (NULL, 0, 0, "memory allocation failure", NULL);
1974     return STATUS_ERROR;
1975   }
1976 
1977   strcpy (NewRec->FileName, FileName);
1978   if (SymName != NULL) {
1979     NewRec->SymName = malloc (strlen (SymName) + 1);
1980     if (NewRec->SymName == NULL) {
1981       free (NewRec);
1982       Error (NULL, 0, 0, "memory allocation failure", NULL);
1983       return STATUS_ERROR;
1984     }
1985     strcpy (NewRec->SymName, SymName);
1986   }
1987 
1988   NewRec->Guid.Data1  = Data[0];
1989   NewRec->Guid.Data2  = (UINT16) Data[1];
1990   NewRec->Guid.Data3  = (UINT16) Data[2];
1991   for (Index = 0; Index < 8; Index++) {
1992     NewRec->Guid.Data4[Index] = (UINT8) Data[3 + Index];
1993   }
1994   //
1995   // Add it to the list
1996   //
1997   NewRec->Next  = gGuidList;
1998   gGuidList     = NewRec;
1999 
2000   //
2001   // Report it
2002   // ReportGuid (FileName, NewRec);
2003   //
2004   return STATUS_SUCCESS;
2005 }
2006 //
2007 // For debug purposes, print each guid found
2008 //
2009 // static
2010 // VOID
2011 // ReportGuid (
2012 //  INT8        *FileName,
2013 // GUID_RECORD *NewGuid
2014 //  )
2015 // {
2016 //  //fprintf (stdout, "%s: 0x%08X\n", FileName, NewGuid->Guid.Data1);
2017 // }
2018 //
2019 // Free up memory we allocated to keep track of guids defined.
2020 //
2021 static
2022 VOID
FreeGuids(VOID)2023 FreeGuids (
2024   VOID
2025   )
2026 {
2027   GUID_RECORD *NextRec;
2028   while (gGuidList != NULL) {
2029     NextRec = gGuidList->Next;
2030     if (gGuidList->FileName != NULL) {
2031       free (gGuidList->FileName);
2032     }
2033 
2034     if (gGuidList->SymName != NULL) {
2035       free (gGuidList->SymName);
2036     }
2037 
2038     free (gGuidList);
2039     gGuidList = NextRec;
2040   }
2041 }
2042 
2043 static
2044 VOID
FreeSigs(VOID)2045 FreeSigs (
2046   VOID
2047   )
2048 {
2049   SIGNATURE_RECORD  *NextRec;
2050   while (gSignatureList != NULL) {
2051     NextRec = gSignatureList->Next;
2052     if (gSignatureList->FileName != NULL) {
2053       free (gSignatureList->FileName);
2054     }
2055 
2056     free (gSignatureList);
2057     gSignatureList = NextRec;
2058   }
2059 }
2060 //
2061 // Scan through all guids defined and compare each for duplicates.
2062 //
2063 static
2064 STATUS
CheckDuplicates(VOID)2065 CheckDuplicates (
2066   VOID
2067   )
2068 {
2069   GUID_RECORD       *CurrentFile;
2070 
2071   GUID_RECORD       *TempFile;
2072   SIGNATURE_RECORD  *CurrentSig;
2073   SIGNATURE_RECORD  *TempSig;
2074   STATUS            Status;
2075   int               Index;
2076   int               DupCount;
2077   int               Len;
2078   BOOLEAN           Same;
2079   UINT32            GuidSum;
2080   INT8              *SymName;
2081 
2082   Status = STATUS_SUCCESS;
2083 
2084   //
2085   // If we're checking guids.....
2086   //
2087   if (gOptions.CheckGuids) {
2088     //
2089     // If -p option, print all guids found
2090     //
2091     if (gOptions.PrintFound) {
2092       CurrentFile = gGuidList;
2093       while (CurrentFile != NULL) {
2094         fprintf (
2095           stdout,
2096           "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",
2097           (UINT32) CurrentFile->Guid.Data1,
2098           (UINT32) CurrentFile->Guid.Data2,
2099           (UINT32) CurrentFile->Guid.Data3,
2100           (UINT32) CurrentFile->Guid.Data4[0],
2101           (UINT32) CurrentFile->Guid.Data4[1],
2102           (UINT32) CurrentFile->Guid.Data4[2],
2103           (UINT32) CurrentFile->Guid.Data4[3],
2104           (UINT32) CurrentFile->Guid.Data4[4],
2105           (UINT32) CurrentFile->Guid.Data4[5],
2106           (UINT32) CurrentFile->Guid.Data4[6],
2107           (UINT32) CurrentFile->Guid.Data4[7],
2108           CurrentFile->FileName
2109           );
2110         CurrentFile = CurrentFile->Next;
2111       }
2112     }
2113 
2114     if (gOptions.GuidXReference) {
2115       CurrentFile = gGuidList;
2116       while (CurrentFile != NULL) {
2117         //
2118         // If no symbol name, print FileName
2119         //
2120         SymName = CurrentFile->SymName;
2121         if (SymName == NULL) {
2122           //
2123           // Assume file name will not be NULL and strlen > 0
2124           //
2125           SymName = CurrentFile->FileName + strlen (CurrentFile->FileName) - 1;
2126           while ((*SymName != '\\') && (SymName > CurrentFile->FileName)) SymName --;
2127           if (*SymName == '\\') SymName ++;
2128         }
2129 
2130         fprintf (
2131           stdout,
2132           "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X %s\n",
2133           (UINT32) CurrentFile->Guid.Data1,
2134           (UINT32) CurrentFile->Guid.Data2,
2135           (UINT32) CurrentFile->Guid.Data3,
2136           (UINT32) CurrentFile->Guid.Data4[0],
2137           (UINT32) CurrentFile->Guid.Data4[1],
2138           (UINT32) CurrentFile->Guid.Data4[2],
2139           (UINT32) CurrentFile->Guid.Data4[3],
2140           (UINT32) CurrentFile->Guid.Data4[4],
2141           (UINT32) CurrentFile->Guid.Data4[5],
2142           (UINT32) CurrentFile->Guid.Data4[6],
2143           (UINT32) CurrentFile->Guid.Data4[7],
2144           SymName
2145           );
2146         CurrentFile = CurrentFile->Next;
2147       }
2148     }
2149     //
2150     // Now go through all guids and report duplicates.
2151     //
2152     CurrentFile = gGuidList;
2153     while (CurrentFile != NULL) {
2154       DupCount  = 0;
2155       TempFile  = CurrentFile->Next;
2156       while (TempFile) {
2157         //
2158         // Compare the guids
2159         //
2160         if ((CurrentFile->Guid.Data1 == TempFile->Guid.Data1) &&
2161             (CurrentFile->Guid.Data2 == TempFile->Guid.Data2) &&
2162             (CurrentFile->Guid.Data3 == TempFile->Guid.Data3)
2163             ) {
2164           //
2165           // OR in all the guid bytes so we can ignore NULL-guid definitions.
2166           //
2167           GuidSum = CurrentFile->Guid.Data1 | CurrentFile->Guid.Data2 | CurrentFile->Guid.Data3;
2168           Same    = TRUE;
2169           for (Index = 0; Index < 8; Index++) {
2170             GuidSum |= CurrentFile->Guid.Data4[Index];
2171             if (CurrentFile->Guid.Data4[Index] != TempFile->Guid.Data4[Index]) {
2172               Same = FALSE;
2173               break;
2174             }
2175           }
2176           //
2177           // If they're the same, and the guid was non-zero, print a message.
2178           //
2179           if (Same && GuidSum) {
2180             if (DupCount == 0) {
2181               Error (NULL, 0, 0, "duplicate GUIDS found", NULL);
2182               fprintf (stdout, "   FILE1: %s\n", CurrentFile->FileName);
2183             }
2184 
2185             DupCount++;
2186             fprintf (stdout, "   FILE%d: %s\n", DupCount + 1, TempFile->FileName);
2187             //
2188             // Flag it as reported so we don't report it again if there's three or more
2189             //
2190             TempFile->Reported = TRUE;
2191           }
2192         }
2193         //
2194         // Next one
2195         //
2196         TempFile = TempFile->Next;
2197       }
2198       //
2199       // Print the guid if we found duplicates
2200       //
2201       if (DupCount) {
2202         fprintf (
2203           stdout,
2204           "   GUID:  0x%08X 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
2205           (UINT32) CurrentFile->Guid.Data1,
2206           (UINT32) CurrentFile->Guid.Data2,
2207           (UINT32) CurrentFile->Guid.Data3,
2208           (UINT32) CurrentFile->Guid.Data4[0],
2209           (UINT32) CurrentFile->Guid.Data4[1],
2210           (UINT32) CurrentFile->Guid.Data4[2],
2211           (UINT32) CurrentFile->Guid.Data4[3],
2212           (UINT32) CurrentFile->Guid.Data4[4],
2213           (UINT32) CurrentFile->Guid.Data4[5],
2214           (UINT32) CurrentFile->Guid.Data4[6],
2215           (UINT32) CurrentFile->Guid.Data4[7]
2216           );
2217         //
2218         // return STATUS_ERROR;
2219         //
2220       }
2221       //
2222       // Find the next one that hasn't been reported
2223       //
2224       do {
2225         CurrentFile = CurrentFile->Next;
2226       } while ((CurrentFile != NULL) && (CurrentFile->Reported));
2227     }
2228   }
2229 
2230   if (gOptions.CheckSignatures) {
2231     //
2232     // Print ones found if specified
2233     //
2234     if (gOptions.PrintFound) {
2235       CurrentSig = gSignatureList;
2236       while (CurrentSig != NULL) {
2237         Len = CurrentSig->Signature.DataLen;
2238         for (Index = 0; Index < Len; Index++) {
2239           fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
2240         }
2241 
2242         fprintf (stdout, "  %s\n", CurrentSig->FileName);
2243         CurrentSig = CurrentSig->Next;
2244       }
2245     }
2246 
2247     CurrentSig = gSignatureList;
2248     while (CurrentSig != NULL) {
2249       DupCount  = 0;
2250       TempSig   = CurrentSig->Next;
2251       Len       = CurrentSig->Signature.DataLen;
2252       while (TempSig) {
2253         //
2254         // Check for same length, then do string compare
2255         //
2256         if (Len == TempSig->Signature.DataLen) {
2257           if (strncmp (CurrentSig->Signature.Data, TempSig->Signature.Data, Len) == 0) {
2258             //
2259             // Print header message if first failure for this sig
2260             //
2261             if (DupCount == 0) {
2262               Error (NULL, 0, 0, "duplicate signatures found", NULL);
2263               fprintf (stdout, "   FILE1: %s\n", CurrentSig->FileName);
2264             }
2265 
2266             DupCount++;
2267             fprintf (stdout, "   FILE%d: %s\n", DupCount + 1, TempSig->FileName);
2268             TempSig->Reported = TRUE;
2269           }
2270         }
2271 
2272         TempSig = TempSig->Next;
2273       }
2274 
2275       if (DupCount) {
2276         fprintf (stdout, "   SIG:   ");
2277         for (Index = 0; Index < Len; Index++) {
2278           fprintf (stdout, "%c", CurrentSig->Signature.Data[Index]);
2279         }
2280 
2281         fprintf (stdout, "\n");
2282       }
2283       //
2284       // On to the next one that hasn't been reported
2285       //
2286       do {
2287         CurrentSig = CurrentSig->Next;
2288       } while ((CurrentSig != NULL) && (CurrentSig->Reported));
2289     }
2290   }
2291 
2292   return Status;
2293 }
2294 
2295 static
2296 VOID
FreeOptions(VOID)2297 FreeOptions (
2298   VOID
2299   )
2300 /*++
2301 
2302 Routine Description:
2303   Free up any memory we allocated when processing command-line options.
2304 
2305 Arguments:
2306   None.
2307 
2308 Returns:
2309   NA
2310 
2311 Notes:
2312   We don't free up the ->Str fields because we did not allocate them.
2313   Instead, we just set the pointer to point to the actual parameter
2314   from the command line.
2315 
2316 --*/
2317 {
2318   STRING_LIST *Ptr;
2319   while (gOptions.ExcludeDirs != NULL) {
2320     Ptr = gOptions.ExcludeDirs->Next;
2321     //
2322     // free (gOptions.ExcludeDirs->Str);
2323     //
2324     free (gOptions.ExcludeDirs);
2325     gOptions.ExcludeDirs = Ptr;
2326   }
2327 
2328   while (gOptions.ExcludeSubDirs != NULL) {
2329     Ptr = gOptions.ExcludeSubDirs->Next;
2330     //
2331     // free (gOptions.ExcludeSubDirs->Str);
2332     //
2333     free (gOptions.ExcludeSubDirs);
2334     gOptions.ExcludeSubDirs = Ptr;
2335   }
2336 
2337   while (gOptions.ExcludeExtensions != NULL) {
2338     Ptr = gOptions.ExcludeExtensions->Next;
2339     //
2340     // free (gOptions.ExcludeExtensions->Str);
2341     //
2342     free (gOptions.ExcludeExtensions);
2343     gOptions.ExcludeExtensions = Ptr;
2344   }
2345 
2346   while (gOptions.ExcludeFiles != NULL) {
2347     Ptr = gOptions.ExcludeFiles->Next;
2348     //
2349     // free (gOptions.ExcludeFiles->Str);
2350     //
2351     free (gOptions.ExcludeFiles);
2352     gOptions.ExcludeFiles = Ptr;
2353   }
2354 }
2355 //
2356 // Given an array of 32-bit data, validate the data for the given number of
2357 // guid data. For example, it might have been scanned as 16 bytes of data, or
2358 // 11 fields of data.
2359 //
2360 static
2361 BOOLEAN
CheckGuidData(UINT32 * Data,UINT32 DataCount)2362 CheckGuidData (
2363   UINT32    *Data,
2364   UINT32    DataCount
2365   )
2366 {
2367   UINT32  Index;
2368 
2369   if (DataCount == 16) {
2370     for (Index = 0; Index < 16; Index++) {
2371       if (Data[Index] &~0xFF) {
2372         return FALSE;
2373       }
2374     }
2375 
2376     return TRUE;
2377   } else if (DataCount == 11) {
2378     //
2379     // Data[0] never out of range (32-bit)
2380     //
2381     if ((Data[1] | Data[2]) &~0xFFFF) {
2382       //
2383       // Error ("Out of range value for GUID data word(s) [1] and/or [2]");
2384       //
2385       return FALSE;
2386     }
2387 
2388     for (Index = 0; Index < 8; Index++) {
2389       if (Data[Index + 3] &~0xFF) {
2390         //
2391         // Error ("Out of range value for GUID data byte(s) [4] - [11]");
2392         //
2393         return FALSE;
2394       }
2395     }
2396 
2397     return TRUE;
2398   }
2399 
2400   return FALSE;
2401 }
2402 
2403 static
2404 VOID
ConcatenateLines(FILE * Fptr,INT8 * Line,UINT32 Len)2405 ConcatenateLines (
2406   FILE        *Fptr,
2407   INT8        *Line,
2408   UINT32      Len
2409   )
2410 {
2411   UINT32      LineLen;
2412   BOOLEAN     NeedCheck;
2413 
2414   NeedCheck = TRUE;
2415   while (NeedCheck) {
2416     LineLen = strlen (Line);
2417     if ((Line[LineLen - 1] == '\n') && (Line[LineLen - 2] == '\\')) {
2418       Line[LineLen - 2] = '\0';
2419       fgets (Line + LineLen - 2, Len - LineLen, Fptr);
2420     } else if (Line[LineLen - 1] == '\\') {
2421       Line[LineLen - 1] = '\0';
2422       fgets (Line + LineLen - 1, Len - LineLen, Fptr);
2423     } else {
2424       NeedCheck = FALSE;
2425     }
2426   }
2427 }
2428