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