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