2 Main file for Comp shell Debug1 function.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2017, 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] Buffer Data buffer to be printed.
35 @param[in] BufferSize Size of the data to be printed.
36 @param[in] Address Address of the differnt point.
37 @param[in] DifferentBytes Total size of the buffer.
42 CONST CHAR16
*FileName
,
51 ShellPrintEx (-1, -1, L
"%s: %s\r\n %08x:", L
"File1", FileName
, Address
);
54 // Print data in hex-format.
56 for (Index
= 0; Index
< DataSize
; Index
++) {
57 ShellPrintEx (-1, -1, L
" %02x", Buffer
[Index
]);
60 if (DataSize
< BufferSize
) {
61 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_COMP_END_OF_FILE
), gShellDebug1HiiHandle
);
64 ShellPrintEx (-1, -1, L
" *");
67 // Print data in char-format.
69 for (Index
= 0; Index
< DataSize
; Index
++) {
70 if (Buffer
[Index
] >= 0x20 && Buffer
[Index
] <= 0x7E) {
71 ShellPrintEx (-1, -1, L
"%c", Buffer
[Index
]);
74 // Print dots for control characters
76 ShellPrintEx (-1, -1, L
".");
80 ShellPrintEx (-1, -1, L
"*\r\n");
84 Function for 'comp' command.
86 @param[in] ImageHandle Handle to the Image (NULL if Internal).
87 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
92 IN EFI_HANDLE ImageHandle
,
93 IN EFI_SYSTEM_TABLE
*SystemTable
101 CONST CHAR16
*TempParam
;
102 SHELL_STATUS ShellStatus
;
103 SHELL_FILE_HANDLE FileHandle1
;
104 SHELL_FILE_HANDLE FileHandle2
;
107 UINT64 DifferentBytes
;
108 UINT64 DifferentCount
;
109 UINT8 DiffPointNumber
;
110 UINT8 OneByteFromFile1
;
111 UINT8 OneByteFromFile2
;
112 UINT8
*DataFromFile1
;
113 UINT8
*DataFromFile2
;
114 UINTN InsertPosition1
;
115 UINTN InsertPosition2
;
116 UINTN DataSizeFromFile1
;
117 UINTN DataSizeFromFile2
;
120 UINTN DiffPointAddress
;
121 READ_STATUS ReadStatus
;
123 ShellStatus
= SHELL_SUCCESS
;
124 Status
= EFI_SUCCESS
;
129 DataFromFile1
= NULL
;
130 DataFromFile2
= NULL
;
131 ReadStatus
= OutOfDiffPoint
;
138 DiffPointAddress
= 0;
141 // initialize the shell lib (we must be in non-auto-init...)
143 Status
= ShellInitialize();
144 ASSERT_EFI_ERROR(Status
);
146 Status
= CommandInit();
147 ASSERT_EFI_ERROR(Status
);
150 // parse the command line
152 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
153 if (EFI_ERROR(Status
)) {
154 if (Status
== EFI_VOLUME_CORRUPTED
&& ProblemParam
!= NULL
) {
155 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDebug1HiiHandle
, L
"comp", ProblemParam
);
156 FreePool(ProblemParam
);
157 ShellStatus
= SHELL_INVALID_PARAMETER
;
162 if (ShellCommandLineGetCount(Package
) > 3) {
163 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDebug1HiiHandle
, L
"comp");
164 ShellStatus
= SHELL_INVALID_PARAMETER
;
165 } else if (ShellCommandLineGetCount(Package
) < 3) {
166 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_FEW
), gShellDebug1HiiHandle
, L
"comp");
167 ShellStatus
= SHELL_INVALID_PARAMETER
;
169 TempParam
= ShellCommandLineGetRawValue(Package
, 1);
170 ASSERT(TempParam
!= NULL
);
171 FileName1
= ShellFindFilePath(TempParam
);
172 if (FileName1
== NULL
) {
173 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_FIND_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
174 ShellStatus
= SHELL_NOT_FOUND
;
176 Status
= ShellOpenFileByName(FileName1
, &FileHandle1
, EFI_FILE_MODE_READ
, 0);
177 if (EFI_ERROR(Status
)) {
178 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
179 ShellStatus
= SHELL_NOT_FOUND
;
182 TempParam
= ShellCommandLineGetRawValue(Package
, 2);
183 ASSERT(TempParam
!= NULL
);
184 FileName2
= ShellFindFilePath(TempParam
);
185 if (FileName2
== NULL
) {
186 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_FILE_FIND_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
187 ShellStatus
= SHELL_NOT_FOUND
;
189 Status
= ShellOpenFileByName(FileName2
, &FileHandle2
, EFI_FILE_MODE_READ
, 0);
190 if (EFI_ERROR(Status
)) {
191 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL
), gShellDebug1HiiHandle
, L
"comp", TempParam
);
192 ShellStatus
= SHELL_NOT_FOUND
;
195 if (ShellStatus
== SHELL_SUCCESS
) {
196 Status
= gEfiShellProtocol
->GetFileSize(FileHandle1
, &Size1
);
197 ASSERT_EFI_ERROR(Status
);
198 Status
= gEfiShellProtocol
->GetFileSize(FileHandle2
, &Size2
);
199 ASSERT_EFI_ERROR(Status
);
201 if (ShellCommandLineGetFlag (Package
, L
"-n")) {
202 TempParam
= ShellCommandLineGetValue (Package
, L
"-n");
203 if (TempParam
== NULL
) {
204 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"comp", L
"-n");
205 ShellStatus
= SHELL_INVALID_PARAMETER
;
207 if (gUnicodeCollation
->StriColl (gUnicodeCollation
, (CHAR16
*)TempParam
, L
"all") == 0) {
208 DifferentCount
= MAX_UINTN
;
210 Status
= ShellConvertStringToUint64 (TempParam
, &DifferentCount
, FALSE
, TRUE
);
211 if (EFI_ERROR(Status
) || DifferentCount
== 0) {
212 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"comp", TempParam
, L
"-n");
213 ShellStatus
= SHELL_INVALID_PARAMETER
;
219 if (ShellCommandLineGetFlag (Package
, L
"-s")) {
220 TempParam
= ShellCommandLineGetValue (Package
, L
"-s");
221 if (TempParam
== NULL
) {
222 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDebug1HiiHandle
, L
"comp", L
"-s");
223 ShellStatus
= SHELL_INVALID_PARAMETER
;
225 Status
= ShellConvertStringToUint64 (TempParam
, &DifferentBytes
, FALSE
, TRUE
);
226 if (EFI_ERROR(Status
) || DifferentBytes
== 0) {
227 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM_VAL
), gShellDebug1HiiHandle
, L
"comp", TempParam
, L
"-s");
228 ShellStatus
= SHELL_INVALID_PARAMETER
;
230 if (DifferentBytes
> MAX (Size1
, Size2
)) {
231 DifferentBytes
= MAX (Size1
, Size2
);
238 if (ShellStatus
== SHELL_SUCCESS
) {
239 DataFromFile1
= AllocateZeroPool ((UINTN
)DifferentBytes
);
240 DataFromFile2
= AllocateZeroPool ((UINTN
)DifferentBytes
);
241 if (DataFromFile1
== NULL
|| DataFromFile2
== NULL
) {
242 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
243 SHELL_FREE_NON_NULL (DataFromFile1
);
244 SHELL_FREE_NON_NULL (DataFromFile2
);
248 if (ShellStatus
== SHELL_SUCCESS
) {
249 while (DiffPointNumber
< DifferentCount
) {
250 DataSizeFromFile1
= 1;
251 DataSizeFromFile2
= 1;
252 OneByteFromFile1
= 0;
253 OneByteFromFile2
= 0;
254 Status
= gEfiShellProtocol
->ReadFile (FileHandle1
, &DataSizeFromFile1
, &OneByteFromFile1
);
255 ASSERT_EFI_ERROR (Status
);
256 Status
= gEfiShellProtocol
->ReadFile (FileHandle2
, &DataSizeFromFile2
, &OneByteFromFile2
);
257 ASSERT_EFI_ERROR (Status
);
262 // 1.When end of file and no chars in DataFromFile buffer, then break while.
263 // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever.
264 // So the previous different point is the last one, then break the while block.
266 if ( (DataSizeFromFile1
== 0 && InsertPosition1
== 0 && DataSizeFromFile2
== 0 && InsertPosition2
== 0) ||
267 (ReadStatus
== InPrevDiffPoint
&& (DataSizeFromFile1
== 0 || DataSizeFromFile2
== 0))
272 if (ReadStatus
== OutOfDiffPoint
) {
273 if (OneByteFromFile1
!= OneByteFromFile2
) {
274 ReadStatus
= InDiffPoint
;
275 DiffPointAddress
= TempAddress
;
276 if (DataSizeFromFile1
== 1) {
277 DataFromFile1
[InsertPosition1
++] = OneByteFromFile1
;
279 if (DataSizeFromFile2
== 1) {
280 DataFromFile2
[InsertPosition2
++] = OneByteFromFile2
;
283 } else if (ReadStatus
== InDiffPoint
) {
284 if (DataSizeFromFile1
== 1) {
285 DataFromFile1
[InsertPosition1
++] = OneByteFromFile1
;
287 if (DataSizeFromFile2
== 1) {
288 DataFromFile2
[InsertPosition2
++] = OneByteFromFile2
;
290 } else if (ReadStatus
== InPrevDiffPoint
) {
291 if (OneByteFromFile1
== OneByteFromFile2
) {
292 ReadStatus
= OutOfDiffPoint
;
297 // ReadStatus should be always equal InDiffPoint.
299 if ( InsertPosition1
== DifferentBytes
||
300 InsertPosition2
== DifferentBytes
||
301 (DataSizeFromFile1
== 0 && DataSizeFromFile2
== 0)
304 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT
), gShellDebug1HiiHandle
, ++DiffPointNumber
);
305 PrintDifferentPoint (FileName1
, DataFromFile1
, InsertPosition1
, DiffPointAddress
, DifferentBytes
);
306 PrintDifferentPoint (FileName2
, DataFromFile2
, InsertPosition2
, DiffPointAddress
, DifferentBytes
);
309 // One of two buffuers is empty, it means this is the last different point.
311 if (InsertPosition1
== 0 || InsertPosition2
== 0) {
315 for (Index
= 1; Index
< InsertPosition1
&& Index
< InsertPosition2
; Index
++) {
316 if (DataFromFile1
[Index
] == DataFromFile2
[Index
]) {
317 ReadStatus
= OutOfDiffPoint
;
322 if (ReadStatus
== OutOfDiffPoint
) {
324 // Try to find a new different point in the rest of DataFromFile.
326 for (; Index
< MAX (InsertPosition1
,InsertPosition2
); Index
++) {
327 if (DataFromFile1
[Index
] != DataFromFile2
[Index
]) {
328 ReadStatus
= InDiffPoint
;
329 DiffPointAddress
+= Index
;
335 // Doesn't find a new different point, still in the same different point.
337 ReadStatus
= InPrevDiffPoint
;
340 CopyMem (DataFromFile1
, DataFromFile1
+ Index
, InsertPosition1
- Index
);
341 CopyMem (DataFromFile2
, DataFromFile2
+ Index
, InsertPosition2
- Index
);
343 SetMem (DataFromFile1
+ InsertPosition1
- Index
, (UINTN
)DifferentBytes
- InsertPosition1
+ Index
, 0);
344 SetMem (DataFromFile2
+ InsertPosition2
- Index
, (UINTN
)DifferentBytes
- InsertPosition2
+ Index
, 0);
346 InsertPosition1
-= Index
;
347 InsertPosition2
-= Index
;
351 SHELL_FREE_NON_NULL (DataFromFile1
);
352 SHELL_FREE_NON_NULL (DataFromFile2
);
354 if (DiffPointNumber
== 0) {
355 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_COMP_FOOTER_PASS
), gShellDebug1HiiHandle
);
357 ShellPrintHiiEx(-1, -1, NULL
, STRING_TOKEN (STR_COMP_FOOTER_FAIL
), gShellDebug1HiiHandle
);
362 ShellCommandLineFreeVarList (Package
);
364 SHELL_FREE_NON_NULL(FileName1
);
365 SHELL_FREE_NON_NULL(FileName2
);
367 if (FileHandle1
!= NULL
) {
368 gEfiShellProtocol
->CloseFile(FileHandle1
);
370 if (FileHandle2
!= NULL
) {
371 gEfiShellProtocol
->CloseFile(FileHandle2
);
374 return (ShellStatus
);