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