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