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