VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/Comp.c@ 80924

Last change on this file since 80924 was 80721, checked in by vboxsync, 6 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • Property svn:eol-style set to native
File size: 13.0 KB
Line 
1/** @file
2 Main file for Comp shell Debug1 function.
3
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include "UefiShellDebug1CommandsLib.h"
11
12STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
13 {L"-n", TypeValue},
14 {L"-s", TypeValue},
15 {NULL, TypeMax}
16 };
17
18typedef enum {
19 OutOfDiffPoint,
20 InDiffPoint,
21 InPrevDiffPoint
22} READ_STATUS;
23
24/**
25 Function to print differnt point data.
26
27 @param[in] FileName File name.
28 @param[in] FileTag File tag name.
29 @param[in] Buffer Data buffer to be printed.
30 @param[in] BufferSize Size of the data to be printed.
31 @param[in] Address Address of the differnt point.
32 @param[in] DifferentBytes Total size of the buffer.
33
34**/
35VOID
36PrintDifferentPoint(
37 CONST CHAR16 *FileName,
38 CHAR16 *FileTag,
39 UINT8 *Buffer,
40 UINT64 BufferSize,
41 UINTN Address,
42 UINT64 DifferentBytes
43 )
44{
45 UINTN Index;
46
47 ShellPrintEx (-1, -1, L"%s: %s\r\n %08x:", FileTag, FileName, Address);
48
49 //
50 // Print data in hex-format.
51 //
52 for (Index = 0; Index < BufferSize; Index++) {
53 ShellPrintEx (-1, -1, L" %02x", Buffer[Index]);
54 }
55
56 if (BufferSize < DifferentBytes) {
57 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_END_OF_FILE), gShellDebug1HiiHandle);
58 }
59
60 ShellPrintEx (-1, -1, L" *");
61
62 //
63 // Print data in char-format.
64 //
65 for (Index = 0; Index < BufferSize; Index++) {
66 if (Buffer[Index] >= 0x20 && Buffer[Index] <= 0x7E) {
67 ShellPrintEx (-1, -1, L"%c", Buffer[Index]);
68 } else {
69 //
70 // Print dots for control characters
71 //
72 ShellPrintEx (-1, -1, L".");
73 }
74 }
75
76 ShellPrintEx (-1, -1, L"*\r\n");
77}
78
79/**
80 Function for 'comp' command.
81
82 @param[in] ImageHandle Handle to the Image (NULL if Internal).
83 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
84**/
85SHELL_STATUS
86EFIAPI
87ShellCommandRunComp (
88 IN EFI_HANDLE ImageHandle,
89 IN EFI_SYSTEM_TABLE *SystemTable
90 )
91{
92 EFI_STATUS Status;
93 LIST_ENTRY *Package;
94 CHAR16 *ProblemParam;
95 CHAR16 *FileName1;
96 CHAR16 *FileName2;
97 CONST CHAR16 *TempParam;
98 SHELL_STATUS ShellStatus;
99 SHELL_FILE_HANDLE FileHandle1;
100 SHELL_FILE_HANDLE FileHandle2;
101 UINT64 Size1;
102 UINT64 Size2;
103 UINT64 DifferentBytes;
104 UINT64 DifferentCount;
105 UINT8 DiffPointNumber;
106 UINT8 OneByteFromFile1;
107 UINT8 OneByteFromFile2;
108 UINT8 *DataFromFile1;
109 UINT8 *DataFromFile2;
110 UINTN InsertPosition1;
111 UINTN InsertPosition2;
112 UINTN DataSizeFromFile1;
113 UINTN DataSizeFromFile2;
114 UINTN TempAddress;
115 UINTN Index;
116 UINTN DiffPointAddress;
117 READ_STATUS ReadStatus;
118
119 ShellStatus = SHELL_SUCCESS;
120 Status = EFI_SUCCESS;
121 FileName1 = NULL;
122 FileName2 = NULL;
123 FileHandle1 = NULL;
124 FileHandle2 = NULL;
125 DataFromFile1 = NULL;
126 DataFromFile2 = NULL;
127 ReadStatus = OutOfDiffPoint;
128 DifferentCount = 10;
129 DifferentBytes = 4;
130 DiffPointNumber = 0;
131 InsertPosition1 = 0;
132 InsertPosition2 = 0;
133 TempAddress = 0;
134 DiffPointAddress = 0;
135
136 //
137 // initialize the shell lib (we must be in non-auto-init...)
138 //
139 Status = ShellInitialize();
140 ASSERT_EFI_ERROR(Status);
141
142 Status = CommandInit();
143 ASSERT_EFI_ERROR(Status);
144
145 //
146 // parse the command line
147 //
148 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
149 if (EFI_ERROR(Status)) {
150 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
151 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"comp", ProblemParam);
152 FreePool(ProblemParam);
153 ShellStatus = SHELL_INVALID_PARAMETER;
154 } else {
155 ASSERT(FALSE);
156 }
157 } else {
158 if (ShellCommandLineGetCount(Package) > 3) {
159 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"comp");
160 ShellStatus = SHELL_INVALID_PARAMETER;
161 } else if (ShellCommandLineGetCount(Package) < 3) {
162 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"comp");
163 ShellStatus = SHELL_INVALID_PARAMETER;
164 } else {
165 TempParam = ShellCommandLineGetRawValue(Package, 1);
166 ASSERT(TempParam != NULL);
167 FileName1 = ShellFindFilePath(TempParam);
168 if (FileName1 == NULL) {
169 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam);
170 ShellStatus = SHELL_NOT_FOUND;
171 } else {
172 Status = ShellOpenFileByName(FileName1, &FileHandle1, EFI_FILE_MODE_READ, 0);
173 if (EFI_ERROR(Status)) {
174 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam);
175 ShellStatus = SHELL_NOT_FOUND;
176 }
177 }
178 TempParam = ShellCommandLineGetRawValue(Package, 2);
179 ASSERT(TempParam != NULL);
180 FileName2 = ShellFindFilePath(TempParam);
181 if (FileName2 == NULL) {
182 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam);
183 ShellStatus = SHELL_NOT_FOUND;
184 } else {
185 Status = ShellOpenFileByName(FileName2, &FileHandle2, EFI_FILE_MODE_READ, 0);
186 if (EFI_ERROR(Status)) {
187 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam);
188 ShellStatus = SHELL_NOT_FOUND;
189 }
190 }
191 if (ShellStatus == SHELL_SUCCESS) {
192 Status = gEfiShellProtocol->GetFileSize(FileHandle1, &Size1);
193 ASSERT_EFI_ERROR(Status);
194 Status = gEfiShellProtocol->GetFileSize(FileHandle2, &Size2);
195 ASSERT_EFI_ERROR(Status);
196
197 if (ShellCommandLineGetFlag (Package, L"-n")) {
198 TempParam = ShellCommandLineGetValue (Package, L"-n");
199 if (TempParam == NULL) {
200 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-n");
201 ShellStatus = SHELL_INVALID_PARAMETER;
202 } else {
203 if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempParam, L"all") == 0) {
204 DifferentCount = MAX_UINTN;
205 } else {
206 Status = ShellConvertStringToUint64 (TempParam, &DifferentCount, FALSE, TRUE);
207 if (EFI_ERROR(Status) || DifferentCount == 0) {
208 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-n");
209 ShellStatus = SHELL_INVALID_PARAMETER;
210 }
211 }
212 }
213 }
214
215 if (ShellCommandLineGetFlag (Package, L"-s")) {
216 TempParam = ShellCommandLineGetValue (Package, L"-s");
217 if (TempParam == NULL) {
218 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-s");
219 ShellStatus = SHELL_INVALID_PARAMETER;
220 } else {
221 Status = ShellConvertStringToUint64 (TempParam, &DifferentBytes, FALSE, TRUE);
222 if (EFI_ERROR(Status) || DifferentBytes == 0) {
223 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-s");
224 ShellStatus = SHELL_INVALID_PARAMETER;
225 } else {
226 if (DifferentBytes > MAX (Size1, Size2)) {
227 DifferentBytes = MAX (Size1, Size2);
228 }
229 }
230 }
231 }
232 }
233
234 if (ShellStatus == SHELL_SUCCESS) {
235 DataFromFile1 = AllocateZeroPool ((UINTN)DifferentBytes);
236 DataFromFile2 = AllocateZeroPool ((UINTN)DifferentBytes);
237 if (DataFromFile1 == NULL || DataFromFile2 == NULL) {
238 ShellStatus = SHELL_OUT_OF_RESOURCES;
239 SHELL_FREE_NON_NULL (DataFromFile1);
240 SHELL_FREE_NON_NULL (DataFromFile2);
241 }
242 }
243
244 if (ShellStatus == SHELL_SUCCESS) {
245 while (DiffPointNumber < DifferentCount) {
246 DataSizeFromFile1 = 1;
247 DataSizeFromFile2 = 1;
248 OneByteFromFile1 = 0;
249 OneByteFromFile2 = 0;
250 Status = gEfiShellProtocol->ReadFile (FileHandle1, &DataSizeFromFile1, &OneByteFromFile1);
251 ASSERT_EFI_ERROR (Status);
252 Status = gEfiShellProtocol->ReadFile (FileHandle2, &DataSizeFromFile2, &OneByteFromFile2);
253 ASSERT_EFI_ERROR (Status);
254
255 TempAddress++;
256
257 //
258 // 1.When end of file and no chars in DataFromFile buffer, then break while.
259 // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever.
260 // So the previous different point is the last one, then break the while block.
261 //
262 if ( (DataSizeFromFile1 == 0 && InsertPosition1 == 0 && DataSizeFromFile2 == 0 && InsertPosition2 == 0) ||
263 (ReadStatus == InPrevDiffPoint && (DataSizeFromFile1 == 0 || DataSizeFromFile2 == 0))
264 ) {
265 break;
266 }
267
268 if (ReadStatus == OutOfDiffPoint) {
269 if (OneByteFromFile1 != OneByteFromFile2) {
270 ReadStatus = InDiffPoint;
271 DiffPointAddress = TempAddress;
272 if (DataSizeFromFile1 == 1) {
273 DataFromFile1[InsertPosition1++] = OneByteFromFile1;
274 }
275 if (DataSizeFromFile2 == 1) {
276 DataFromFile2[InsertPosition2++] = OneByteFromFile2;
277 }
278 }
279 } else if (ReadStatus == InDiffPoint) {
280 if (DataSizeFromFile1 == 1) {
281 DataFromFile1[InsertPosition1++] = OneByteFromFile1;
282 }
283 if (DataSizeFromFile2 == 1) {
284 DataFromFile2[InsertPosition2++] = OneByteFromFile2;
285 }
286 } else if (ReadStatus == InPrevDiffPoint) {
287 if (OneByteFromFile1 == OneByteFromFile2) {
288 ReadStatus = OutOfDiffPoint;
289 }
290 }
291
292 //
293 // ReadStatus should be always equal InDiffPoint.
294 //
295 if ( InsertPosition1 == DifferentBytes ||
296 InsertPosition2 == DifferentBytes ||
297 (DataSizeFromFile1 == 0 && DataSizeFromFile2 == 0)
298 ) {
299
300 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT), gShellDebug1HiiHandle, ++DiffPointNumber);
301 PrintDifferentPoint (FileName1, L"File1", DataFromFile1, InsertPosition1, DiffPointAddress, DifferentBytes);
302 PrintDifferentPoint (FileName2, L"File2", DataFromFile2, InsertPosition2, DiffPointAddress, DifferentBytes);
303
304 //
305 // One of two buffuers is empty, it means this is the last different point.
306 //
307 if (InsertPosition1 == 0 || InsertPosition2 == 0) {
308 break;
309 }
310
311 for (Index = 1; Index < InsertPosition1 && Index < InsertPosition2; Index++) {
312 if (DataFromFile1[Index] == DataFromFile2[Index]) {
313 ReadStatus = OutOfDiffPoint;
314 break;
315 }
316 }
317
318 if (ReadStatus == OutOfDiffPoint) {
319 //
320 // Try to find a new different point in the rest of DataFromFile.
321 //
322 for (; Index < MAX (InsertPosition1,InsertPosition2); Index++) {
323 if (DataFromFile1[Index] != DataFromFile2[Index]) {
324 ReadStatus = InDiffPoint;
325 DiffPointAddress += Index;
326 break;
327 }
328 }
329 } else {
330 //
331 // Doesn't find a new different point, still in the same different point.
332 //
333 ReadStatus = InPrevDiffPoint;
334 }
335
336 CopyMem (DataFromFile1, DataFromFile1 + Index, InsertPosition1 - Index);
337 CopyMem (DataFromFile2, DataFromFile2 + Index, InsertPosition2 - Index);
338
339 SetMem (DataFromFile1 + InsertPosition1 - Index, (UINTN)DifferentBytes - InsertPosition1 + Index, 0);
340 SetMem (DataFromFile2 + InsertPosition2 - Index, (UINTN)DifferentBytes - InsertPosition2 + Index, 0);
341
342 InsertPosition1 -= Index;
343 InsertPosition2 -= Index;
344 }
345 }
346
347 SHELL_FREE_NON_NULL (DataFromFile1);
348 SHELL_FREE_NON_NULL (DataFromFile2);
349
350 if (DiffPointNumber == 0) {
351 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_PASS), gShellDebug1HiiHandle);
352 } else {
353 ShellStatus = SHELL_NOT_EQUAL;
354 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_FAIL), gShellDebug1HiiHandle);
355 }
356 }
357 }
358
359 ShellCommandLineFreeVarList (Package);
360 }
361 SHELL_FREE_NON_NULL(FileName1);
362 SHELL_FREE_NON_NULL(FileName2);
363
364 if (FileHandle1 != NULL) {
365 gEfiShellProtocol->CloseFile(FileHandle1);
366 }
367 if (FileHandle2 != NULL) {
368 gEfiShellProtocol->CloseFile(FileHandle2);
369 }
370
371 return (ShellStatus);
372}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette