2 Main file for Comp shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "UefiShellDebug1CommandsLib.h"
18 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
31 Function to print differnt point data.
33 @param[in] FileName File name.
34 @param[in] FileTag File tag name.
35 @param[in] Buffer Data buffer to be printed.
36 @param[in] BufferSize Size of the data to be printed.
37 @param[in] Address Address of the differnt point.
38 @param[in] DifferentBytes Total size of the buffer.
43 CONST CHAR16
*FileName
,
53 ShellPrintEx (-1, -1, L
"%s: %s\r\n %08x:", FileTag
, FileName
, Address
);
56 // Print data in hex-format.
58 for (Index
= 0; Index
< BufferSize
; Index
++) {
59 ShellPrintEx (-1, -1, L
" %02x", Buffer
[Index
]);
62 if (BufferSize
< DifferentBytes
) {
63 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_COMP_END_OF_FILE
), gShellDebug1HiiHandle
);
66 ShellPrintEx (-1, -1, L
" *");
69 // Print data in char-format.
71 for (Index
= 0; Index
< BufferSize
; Index
++) {
72 if (Buffer
[Index
] >= 0x20 && Buffer
[Index
] <= 0x7E) {
73 ShellPrintEx (-1, -1, L
"%c", Buffer
[Index
]);
76 // Print dots for control characters
78 ShellPrintEx (-1, -1, L
".");
82 ShellPrintEx (-1, -1, L
"*\r\n");
86 Function for 'comp' command.
88 @param[in] ImageHandle Handle to the Image (NULL if Internal).
89 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
94 IN EFI_HANDLE ImageHandle
,
95 IN EFI_SYSTEM_TABLE
*SystemTable
100 CHAR16
*ProblemParam
;
103 CONST CHAR16
*TempParam
;
104 SHELL_STATUS ShellStatus
;
105 SHELL_FILE_HANDLE FileHandle1
;
106 SHELL_FILE_HANDLE FileHandle2
;
109 UINT64 DifferentBytes
;
110 UINT64 DifferentCount
;
111 UINT8 DiffPointNumber
;
112 UINT8 OneByteFromFile1
;
113 UINT8 OneByteFromFile2
;
114 UINT8
*DataFromFile1
;
115 UINT8
*DataFromFile2
;
116 UINTN InsertPosition1
;
117 UINTN InsertPosition2
;
118 UINTN DataSizeFromFile1
;
119 UINTN DataSizeFromFile2
;
122 UINTN DiffPointAddress
;
123 READ_STATUS ReadStatus
;
125 ShellStatus
= SHELL_SUCCESS
;
126 Status
= EFI_SUCCESS
;
131 DataFromFile1
= NULL
;
132 DataFromFile2
= NULL
;
133 ReadStatus
= OutOfDiffPoint
;
140 DiffPointAddress
= 0;
143 // initialize the shell lib (we must be in non-auto-init...)
145 Status
= ShellInitialize();
146 ASSERT_EFI_ERROR(Status
);
148 Status
= CommandInit();
149 ASSERT_EFI_ERROR(Status
);
152 // parse the command line
154 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
155 if (EFI_ERROR(Status
)) {
156 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
157 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"comp", ProblemParam
);
158 FreePool(ProblemParam
);
159 ShellStatus
= SHELL_INVALID_PARAMETER
;
164 if (ShellCommandLineGetCount(Package
) > 3) {
165 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"comp");
166 ShellStatus
= SHELL_INVALID_PARAMETER
;
167 } else if (ShellCommandLineGetCount(Package
) < 3) {
168 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"comp");
169 ShellStatus
= SHELL_INVALID_PARAMETER
;
171 TempParam
= ShellCommandLineGetRawValue(Package
, 1);
172 ASSERT(TempParam
!= NULL
);
173 FileName1
= ShellFindFilePath(TempParam
);
174 if (FileName1
== NULL
) {
175 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_FIND_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
176 ShellStatus
= SHELL_NOT_FOUND
;
178 Status
= ShellOpenFileByName(FileName1
, &FileHandle1
, EFI_FILE_MODE_READ
, 0);
179 if (EFI_ERROR(Status
)) {
180 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
181 ShellStatus
= SHELL_NOT_FOUND
;
184 TempParam
= ShellCommandLineGetRawValue(Package
, 2);
185 ASSERT(TempParam
!= NULL
);
186 FileName2
= ShellFindFilePath(TempParam
);
187 if (FileName2
== NULL
) {
188 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_FIND_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
189 ShellStatus
= SHELL_NOT_FOUND
;
191 Status
= ShellOpenFileByName(FileName2
, &FileHandle2
, EFI_FILE_MODE_READ
, 0);
192 if (EFI_ERROR(Status
)) {
193 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
194 ShellStatus
= SHELL_NOT_FOUND
;
197 if (ShellStatus
== SHELL_SUCCESS
) {
198 Status
= gEfiShellProtocol
->GetFileSize(FileHandle1
, &Size1
);
199 ASSERT_EFI_ERROR(Status
);
200 Status
= gEfiShellProtocol
->GetFileSize(FileHandle2
, &Size2
);
201 ASSERT_EFI_ERROR(Status
);
203 if (ShellCommandLineGetFlag (Package
, L
"-n")) {
204 TempParam
= ShellCommandLineGetValue (Package
, L
"-n");
205 if (TempParam
== NULL
) {
206 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"comp", L
"-n");
207 ShellStatus
= SHELL_INVALID_PARAMETER
;
209 if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)TempParam
, L
"all") == 0) {
210 DifferentCount
= MAX_UINTN
;
212 Status
= ShellConvertStringToUint64 (TempParam
, &DifferentCount
, FALSE
, TRUE
);
213 if (EFI_ERROR(Status
) || DifferentCount
== 0) {
214 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"comp", TempParam
, L
"-n");
215 ShellStatus
= SHELL_INVALID_PARAMETER
;
221 if (ShellCommandLineGetFlag (Package
, L
"-s")) {
222 TempParam
= ShellCommandLineGetValue (Package
, L
"-s");
223 if (TempParam
== NULL
) {
224 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"comp", L
"-s");
225 ShellStatus
= SHELL_INVALID_PARAMETER
;
227 Status
= ShellConvertStringToUint64 (TempParam
, &DifferentBytes
, FALSE
, TRUE
);
228 if (EFI_ERROR(Status
) || DifferentBytes
== 0) {
229 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"comp", TempParam
, L
"-s");
230 ShellStatus
= SHELL_INVALID_PARAMETER
;
232 if (DifferentBytes
> MAX (Size1
, Size2
)) {
233 DifferentBytes
= MAX (Size1
, Size2
);
240 if (ShellStatus
== SHELL_SUCCESS
) {
241 DataFromFile1
= AllocateZeroPool ((UINTN
)DifferentBytes
);
242 DataFromFile2
= AllocateZeroPool ((UINTN
)DifferentBytes
);
243 if (DataFromFile1
== NULL
|| DataFromFile2
== NULL
) {
244 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
245 SHELL_FREE_NON_NULL (DataFromFile1
);
246 SHELL_FREE_NON_NULL (DataFromFile2
);
250 if (ShellStatus
== SHELL_SUCCESS
) {
251 while (DiffPointNumber
< DifferentCount
) {
252 DataSizeFromFile1
= 1;
253 DataSizeFromFile2
= 1;
254 OneByteFromFile1
= 0;
255 OneByteFromFile2
= 0;
256 Status
= gEfiShellProtocol
->ReadFile (FileHandle1
, &DataSizeFromFile1
, &OneByteFromFile1
);
257 ASSERT_EFI_ERROR (Status
);
258 Status
= gEfiShellProtocol
->ReadFile (FileHandle2
, &DataSizeFromFile2
, &OneByteFromFile2
);
259 ASSERT_EFI_ERROR (Status
);
264 // 1.When end of file and no chars in DataFromFile buffer, then break while.
265 // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever.
266 // So the previous different point is the last one, then break the while block.
268 if ( (DataSizeFromFile1
== 0 && InsertPosition1
== 0 && DataSizeFromFile2
== 0 && InsertPosition2
== 0) ||
269 (ReadStatus
== InPrevDiffPoint
&& (DataSizeFromFile1
== 0 || DataSizeFromFile2
== 0))
274 if (ReadStatus
== OutOfDiffPoint
) {
275 if (OneByteFromFile1
!= OneByteFromFile2
) {
276 ReadStatus
= InDiffPoint
;
277 DiffPointAddress
= TempAddress
;
278 if (DataSizeFromFile1
== 1) {
279 DataFromFile1
[InsertPosition1
++] = OneByteFromFile1
;
281 if (DataSizeFromFile2
== 1) {
282 DataFromFile2
[InsertPosition2
++] = OneByteFromFile2
;
285 } else if (ReadStatus
== InDiffPoint
) {
286 if (DataSizeFromFile1
== 1) {
287 DataFromFile1
[InsertPosition1
++] = OneByteFromFile1
;
289 if (DataSizeFromFile2
== 1) {
290 DataFromFile2
[InsertPosition2
++] = OneByteFromFile2
;
292 } else if (ReadStatus
== InPrevDiffPoint
) {
293 if (OneByteFromFile1
== OneByteFromFile2
) {
294 ReadStatus
= OutOfDiffPoint
;
299 // ReadStatus should be always equal InDiffPoint.
301 if ( InsertPosition1
== DifferentBytes
||
302 InsertPosition2
== DifferentBytes
||
303 (DataSizeFromFile1
== 0 && DataSizeFromFile2
== 0)
306 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT
), gShellDebug1HiiHandle
, ++DiffPointNumber
);
307 PrintDifferentPoint (FileName1
, L
"File1", DataFromFile1
, InsertPosition1
, DiffPointAddress
, DifferentBytes
);
308 PrintDifferentPoint (FileName2
, L
"File2", DataFromFile2
, InsertPosition2
, DiffPointAddress
, DifferentBytes
);
311 // One of two buffuers is empty, it means this is the last different point.
313 if (InsertPosition1
== 0 || InsertPosition2
== 0) {
317 for (Index
= 1; Index
< InsertPosition1
&& Index
< InsertPosition2
; Index
++) {
318 if (DataFromFile1
[Index
] == DataFromFile2
[Index
]) {
319 ReadStatus
= OutOfDiffPoint
;
324 if (ReadStatus
== OutOfDiffPoint
) {
326 // Try to find a new different point in the rest of DataFromFile.
328 for (; Index
< MAX (InsertPosition1
,InsertPosition2
); Index
++) {
329 if (DataFromFile1
[Index
] != DataFromFile2
[Index
]) {
330 ReadStatus
= InDiffPoint
;
331 DiffPointAddress
+= Index
;
337 // Doesn't find a new different point, still in the same different point.
339 ReadStatus
= InPrevDiffPoint
;
342 CopyMem (DataFromFile1
, DataFromFile1
+ Index
, InsertPosition1
- Index
);
343 CopyMem (DataFromFile2
, DataFromFile2
+ Index
, InsertPosition2
- Index
);
345 SetMem (DataFromFile1
+ InsertPosition1
- Index
, (UINTN
)DifferentBytes
- InsertPosition1
+ Index
, 0);
346 SetMem (DataFromFile2
+ InsertPosition2
- Index
, (UINTN
)DifferentBytes
- InsertPosition2
+ Index
, 0);
348 InsertPosition1
-= Index
;
349 InsertPosition2
-= Index
;
353 SHELL_FREE_NON_NULL (DataFromFile1
);
354 SHELL_FREE_NON_NULL (DataFromFile2
);
356 if (DiffPointNumber
== 0) {
357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_COMP_FOOTER_PASS
), gShellDebug1HiiHandle
);
359 ShellStatus
= SHELL_NOT_EQUAL
;
360 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_COMP_FOOTER_FAIL
), gShellDebug1HiiHandle
);
365 ShellCommandLineFreeVarList (Package
);
367 SHELL_FREE_NON_NULL(FileName1
);
368 SHELL_FREE_NON_NULL(FileName2
);
370 if (FileHandle1
!= NULL
) {
371 gEfiShellProtocol
->CloseFile(FileHandle1
);
373 if (FileHandle2
!= NULL
) {
374 gEfiShellProtocol
->CloseFile(FileHandle2
);
377 return (ShellStatus
);