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