\r
#include "UefiShellDebug1CommandsLib.h"\r
\r
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
+ {L"-n", TypeValue},\r
+ {L"-s", TypeValue},\r
+ {NULL, TypeMax}\r
+ };\r
+\r
+typedef enum {\r
+ OutOfDiffPoint,\r
+ InDiffPoint,\r
+ InPrevDiffPoint\r
+} READ_STATUS;\r
+\r
+/**\r
+ Function to print differnt point data.\r
+\r
+ @param[in] FileName File name\r
+ @param[in] Buffer Data buffer to be printed.\r
+ @param[in] BufferSize Size of the data to be printed.\r
+ @param[in] Address Address of the differnt point.\r
+ @param[in] DifferentBytes Total size of the buffer.\r
+\r
+**/\r
+VOID\r
+PrintDifferentPoint(\r
+ CONST CHAR16 *FileName,\r
+ UINT8 *Buffer,\r
+ UINT64 DataSize,\r
+ UINTN Address,\r
+ UINT64 BufferSize\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ ShellPrintEx (-1, -1, L"%s: %s\r\n %08x:", L"File1", FileName, Address);\r
+\r
+ //\r
+ // Print data in hex-format.\r
+ //\r
+ for (Index = 0; Index < DataSize; Index++) {\r
+ ShellPrintEx (-1, -1, L" %02x", Buffer[Index]);\r
+ }\r
+\r
+ if (DataSize < BufferSize) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_END_OF_FILE), gShellDebug1HiiHandle);\r
+ }\r
+\r
+ ShellPrintEx (-1, -1, L" *");\r
+\r
+ //\r
+ // Print data in char-format.\r
+ //\r
+ for (Index = 0; Index < DataSize; Index++) {\r
+ if (Buffer[Index] >= 0x20 && Buffer[Index] <= 0x7E) {\r
+ ShellPrintEx (-1, -1, L"%c", Buffer[Index]);\r
+ } else {\r
+ //\r
+ // Print dots for control characters\r
+ //\r
+ ShellPrintEx (-1, -1, L".");\r
+ }\r
+ }\r
+\r
+ ShellPrintEx (-1, -1, L"*\r\n");\r
+}\r
+\r
/**\r
Function for 'comp' command.\r
\r
CHAR16 *FileName2;\r
CONST CHAR16 *TempParam;\r
SHELL_STATUS ShellStatus;\r
- UINTN LoopVar;\r
SHELL_FILE_HANDLE FileHandle1;\r
SHELL_FILE_HANDLE FileHandle2;\r
- UINT8 DifferentCount;\r
UINT64 Size1;\r
UINT64 Size2;\r
- UINT8 DataFromFile1;\r
- UINT8 DataFromFile2;\r
- UINT8 ADF_File11;\r
- UINT8 ADF_File12;\r
- UINT8 ADF_File13;\r
- UINT8 ADF_File21;\r
- UINT8 ADF_File22;\r
- UINT8 ADF_File23;\r
+ UINT64 DifferentBytes;\r
+ UINT64 DifferentCount;\r
+ UINT8 DiffPointNumber;\r
+ UINT8 OneByteFromFile1;\r
+ UINT8 OneByteFromFile2;\r
+ UINT8 *DataFromFile1;\r
+ UINT8 *DataFromFile2;\r
+ UINTN InsertPosition1;\r
+ UINTN InsertPosition2;\r
UINTN DataSizeFromFile1;\r
UINTN DataSizeFromFile2;\r
+ UINTN TempAddress;\r
+ UINTN Index;\r
UINTN DiffPointAddress;\r
+ READ_STATUS ReadStatus;\r
\r
- DifferentCount = 0;\r
ShellStatus = SHELL_SUCCESS;\r
Status = EFI_SUCCESS;\r
FileName1 = NULL;\r
FileName2 = NULL;\r
FileHandle1 = NULL;\r
FileHandle2 = NULL;\r
- Size1 = 0;\r
+ DataFromFile1 = NULL;\r
+ DataFromFile2 = NULL;\r
+ ReadStatus = OutOfDiffPoint;\r
+ DifferentCount = 10;\r
+ DifferentBytes = 4;\r
+ DiffPointNumber = 0;\r
+ InsertPosition1 = 0;\r
+ InsertPosition2 = 0;\r
+ TempAddress = 0;\r
\r
//\r
// initialize the shell lib (we must be in non-auto-init...)\r
//\r
// parse the command line\r
//\r
- Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE);\r
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
if (EFI_ERROR(Status)) {\r
if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"comp", ProblemParam); \r
}\r
}\r
if (ShellStatus == SHELL_SUCCESS) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_HEADER), gShellDebug1HiiHandle, FileName1, FileName2);\r
Status = gEfiShellProtocol->GetFileSize(FileHandle1, &Size1);\r
ASSERT_EFI_ERROR(Status);\r
Status = gEfiShellProtocol->GetFileSize(FileHandle2, &Size2);\r
ASSERT_EFI_ERROR(Status);\r
- if (Size1 != Size2) {\r
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_SIZE_FAIL), gShellDebug1HiiHandle);\r
- DifferentCount++;\r
- ShellStatus = SHELL_NOT_EQUAL;\r
+\r
+ if (ShellCommandLineGetFlag (Package, L"-n")) {\r
+ TempParam = ShellCommandLineGetValue (Package, L"-n");\r
+ if (TempParam == NULL) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-n");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempParam, L"all") == 0) {\r
+ DifferentCount = MAX_UINTN;\r
+ } else {\r
+ Status = ShellConvertStringToUint64 (TempParam, &DifferentCount, FALSE, TRUE);\r
+ if (EFI_ERROR(Status) || DifferentCount == 0) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-n");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (ShellCommandLineGetFlag (Package, L"-s")) {\r
+ TempParam = ShellCommandLineGetValue (Package, L"-s");\r
+ if (TempParam == NULL) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-s");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ Status = ShellConvertStringToUint64 (TempParam, &DifferentBytes, FALSE, TRUE);\r
+ if (EFI_ERROR(Status) || DifferentBytes == 0) {\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-s");\r
+ ShellStatus = SHELL_INVALID_PARAMETER;\r
+ } else {\r
+ if (DifferentBytes > MAX (Size1, Size2)) {\r
+ DifferentBytes = MAX (Size1, Size2);\r
+ }\r
+ }\r
+ }\r
}\r
}\r
+\r
if (ShellStatus == SHELL_SUCCESS) {\r
- for (LoopVar = 0 ; LoopVar < Size1 && DifferentCount <= 10 ; LoopVar++) {\r
+ DataFromFile1 = AllocateZeroPool ((UINTN)DifferentBytes);\r
+ DataFromFile2 = AllocateZeroPool ((UINTN)DifferentBytes);\r
+ if (DataFromFile1 == NULL || DataFromFile2 == NULL) {\r
+ ShellStatus = SHELL_OUT_OF_RESOURCES;\r
+ SHELL_FREE_NON_NULL (DataFromFile1);\r
+ SHELL_FREE_NON_NULL (DataFromFile2);\r
+ }\r
+ }\r
+\r
+ if (ShellStatus == SHELL_SUCCESS) {\r
+ while (DiffPointNumber < DifferentCount) {\r
DataSizeFromFile1 = 1;\r
DataSizeFromFile2 = 1;\r
- Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &DataFromFile1);\r
- ASSERT_EFI_ERROR(Status);\r
- Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &DataFromFile2);\r
- ASSERT_EFI_ERROR(Status);\r
- if (DataFromFile1 != DataFromFile2) {\r
- DiffPointAddress = LoopVar;\r
- ADF_File11 = 0;\r
- ADF_File12 = 0;\r
- ADF_File13 = 0;\r
- ADF_File21 = 0;\r
- ADF_File22 = 0;\r
- ADF_File23 = 0;\r
+ OneByteFromFile1 = 0;\r
+ OneByteFromFile2 = 0;\r
+ Status = gEfiShellProtocol->ReadFile (FileHandle1, &DataSizeFromFile1, &OneByteFromFile1);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = gEfiShellProtocol->ReadFile (FileHandle2, &DataSizeFromFile2, &OneByteFromFile2);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- //\r
- // Now check the next 3 bytes if possible. This will make output\r
- // cleaner when there are a sequence of differences.\r
- //\r
- if (LoopVar + 1 < Size1) {\r
- LoopVar++;\r
- DataSizeFromFile1 = 1;\r
- DataSizeFromFile2 = 1;\r
- Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File11);\r
- ASSERT_EFI_ERROR(Status);\r
- Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File21);\r
- ASSERT_EFI_ERROR(Status);\r
- if (LoopVar + 1 < Size1) {\r
- LoopVar++;\r
- DataSizeFromFile1 = 1;\r
- DataSizeFromFile2 = 1;\r
- Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File12);\r
- ASSERT_EFI_ERROR(Status);\r
- Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File22);\r
- ASSERT_EFI_ERROR(Status);\r
- if (LoopVar + 1 < Size1) {\r
- LoopVar++;\r
- DataSizeFromFile1 = 1;\r
- DataSizeFromFile2 = 1;\r
- Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File13);\r
- ASSERT_EFI_ERROR(Status);\r
- Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File23);\r
- ASSERT_EFI_ERROR(Status);\r
- }\r
+ TempAddress++;\r
+\r
+ //\r
+ // 1.When end of file and no chars in DataFromFile buffer, then break while.\r
+ // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever.\r
+ // So the previous different point is the last one, then break the while block.\r
+ //\r
+ if ( (DataSizeFromFile1 == 0 && InsertPosition1 == 0 && DataSizeFromFile2 == 0 && InsertPosition2 == 0) ||\r
+ (ReadStatus == InPrevDiffPoint && (DataSizeFromFile1 == 0 || DataSizeFromFile2 == 0))\r
+ ) {\r
+ break;\r
+ }\r
+\r
+ if (ReadStatus == OutOfDiffPoint) {\r
+ if (OneByteFromFile1 != OneByteFromFile2) {\r
+ ReadStatus = InDiffPoint;\r
+ DiffPointAddress = TempAddress;\r
+ if (DataSizeFromFile1 == 1) {\r
+ DataFromFile1[InsertPosition1++] = OneByteFromFile1;\r
+ }\r
+ if (DataSizeFromFile2 == 1) {\r
+ DataFromFile2[InsertPosition2++] = OneByteFromFile2;\r
}\r
}\r
+ } else if (ReadStatus == InDiffPoint) {\r
+ if (DataSizeFromFile1 == 1) {\r
+ DataFromFile1[InsertPosition1++] = OneByteFromFile1;\r
+ }\r
+ if (DataSizeFromFile2 == 1) {\r
+ DataFromFile2[InsertPosition2++] = OneByteFromFile2;\r
+ }\r
+ } else if (ReadStatus == InPrevDiffPoint) {\r
+ if (OneByteFromFile1 == OneByteFromFile2) {\r
+ ReadStatus = OutOfDiffPoint;\r
+ }\r
+ }\r
+\r
+ //\r
+ // ReadStatus should be always equal InDiffPoint.\r
+ //\r
+ if ( InsertPosition1 == DifferentBytes ||\r
+ InsertPosition2 == DifferentBytes ||\r
+ (DataSizeFromFile1 == 0 && DataSizeFromFile2 == 0)\r
+ ) {\r
+\r
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT), gShellDebug1HiiHandle, ++DiffPointNumber);\r
+ PrintDifferentPoint (FileName1, DataFromFile1, InsertPosition1, DiffPointAddress, DifferentBytes);\r
+ PrintDifferentPoint (FileName2, DataFromFile2, InsertPosition2, DiffPointAddress, DifferentBytes);\r
\r
//\r
- // Print out based on highest of the 4 bytes that are different.\r
+ // One of two buffuers is empty, it means this is the last different point.\r
//\r
- if (ADF_File13 != ADF_File23) {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN (STR_COMP_SPOT_FAIL4),\r
- gShellDebug1HiiHandle,\r
- ++DifferentCount,\r
- FileName1,\r
- DiffPointAddress,\r
- DataFromFile1, ADF_File11, ADF_File12, ADF_File13,\r
- DataFromFile1, ADF_File11, ADF_File12, ADF_File13,\r
- FileName2,\r
- DiffPointAddress,\r
- DataFromFile2, ADF_File21, ADF_File22, ADF_File23,\r
- DataFromFile2, ADF_File21, ADF_File22, ADF_File23\r
- );\r
- } else if (ADF_File12 != ADF_File22) {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN (STR_COMP_SPOT_FAIL3),\r
- gShellDebug1HiiHandle,\r
- ++DifferentCount,\r
- FileName1,\r
- DiffPointAddress,\r
- DataFromFile1, ADF_File11, ADF_File12,\r
- DataFromFile1, ADF_File11, ADF_File12,\r
- FileName2,\r
- DiffPointAddress,\r
- DataFromFile2, ADF_File21, ADF_File22,\r
- DataFromFile2, ADF_File21, ADF_File22\r
- );\r
- } else if (ADF_File11 != ADF_File21) {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN (STR_COMP_SPOT_FAIL2),\r
- gShellDebug1HiiHandle,\r
- ++DifferentCount,\r
- FileName1,\r
- DiffPointAddress,\r
- DataFromFile1, ADF_File11,\r
- DataFromFile1, ADF_File11,\r
- FileName2,\r
- DiffPointAddress,\r
- DataFromFile2, ADF_File21,\r
- DataFromFile2, ADF_File21\r
- );\r
+ if (InsertPosition1 == 0 || InsertPosition2 == 0) {\r
+ break;\r
+ }\r
+\r
+ for (Index = 1; Index < InsertPosition1 && Index < InsertPosition2; Index++) {\r
+ if (DataFromFile1[Index] == DataFromFile2[Index]) {\r
+ ReadStatus = OutOfDiffPoint;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (ReadStatus == OutOfDiffPoint) {\r
+ //\r
+ // Try to find a new different point in the rest of DataFromFile.\r
+ //\r
+ for (; Index < MAX (InsertPosition1,InsertPosition2); Index++) {\r
+ if (DataFromFile1[Index] != DataFromFile2[Index]) {\r
+ ReadStatus = InDiffPoint;\r
+ DiffPointAddress += Index;\r
+ break;\r
+ }\r
+ }\r
} else {\r
- ShellPrintHiiEx(\r
- -1,\r
- -1,\r
- NULL,\r
- STRING_TOKEN (STR_COMP_SPOT_FAIL1),\r
- gShellDebug1HiiHandle,\r
- ++DifferentCount,\r
- FileName1,\r
- DiffPointAddress,\r
- DataFromFile1,\r
- DataFromFile1,\r
- FileName2,\r
- DiffPointAddress,\r
- DataFromFile2,\r
- DataFromFile2\r
- );\r
+ //\r
+ // Doesn't find a new different point, still in the same different point.\r
+ //\r
+ ReadStatus = InPrevDiffPoint;\r
}\r
- ShellStatus = SHELL_NOT_EQUAL;\r
+\r
+ CopyMem (DataFromFile1, DataFromFile1 + Index, InsertPosition1 - Index);\r
+ CopyMem (DataFromFile2, DataFromFile2 + Index, InsertPosition2 - Index);\r
+\r
+ SetMem (DataFromFile1 + InsertPosition1 - Index, (UINTN)DifferentBytes - InsertPosition1 + Index, 0);\r
+ SetMem (DataFromFile2 + InsertPosition2 - Index, (UINTN)DifferentBytes - InsertPosition2 + Index, 0);\r
+\r
+ InsertPosition1 -= Index;\r
+ InsertPosition2 -= Index;\r
}\r
}\r
- if (DifferentCount == 0) {\r
+\r
+ SHELL_FREE_NON_NULL (DataFromFile1);\r
+ SHELL_FREE_NON_NULL (DataFromFile2);\r
+\r
+ if (DiffPointNumber == 0) {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_PASS), gShellDebug1HiiHandle);\r
} else {\r
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_FAIL), gShellDebug1HiiHandle);\r