/** Search the path environment variable for possible locations and test for which one contains a man file with the name specified. If a valid file is found stop searching and return the (opened) SHELL_FILE_HANDLE for that file. @param[in] FileName Name of the file to find and open. @param[out] Handle Pointer to the handle of the found file. The value of this is undefined for return values except EFI_SUCCESS. @retval EFI_SUCCESS The file was found. Handle is a valid SHELL_FILE_HANDLE @retval EFI_INVALID_PARAMETER A parameter had an invalid value. @retval EFI_NOT_FOUND The file was not found. **/ EFI_STATUS EFIAPI SearchPathForFile( IN CONST CHAR16 *FileName, OUT SHELL_FILE_HANDLE *Handle ) { CHAR16 *FullFileName; EFI_STATUS Status; if ( FileName == NULL || Handle == NULL || StrLen(FileName) == 0 ){ return (EFI_INVALID_PARAMETER); } FullFileName = ShellFindFilePath(FileName); if (FullFileName == NULL) { return (EFI_NOT_FOUND); } // // now open that file // Status = EfiShellOpenFileByName(FullFileName, Handle, EFI_FILE_MODE_READ); FreePool(FullFileName); return (Status); }
/** Function for 'compress' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunEfiCompress ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; SHELL_FILE_HANDLE InShellFileHandle; SHELL_FILE_HANDLE OutShellFileHandle; UINT64 OutSize; UINTN OutSize2; VOID *OutBuffer; UINT64 InSize; UINTN InSize2; VOID *InBuffer; CHAR16 *InFileName; CONST CHAR16 *OutFileName; CONST CHAR16 *TempParam; InFileName = NULL; OutFileName = NULL; OutSize = 0; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; OutBuffer = NULL; InShellFileHandle = NULL; OutShellFileHandle = NULL; InBuffer = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"eficompress", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"eficompress"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) < 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"eficompress"); ShellStatus = SHELL_INVALID_PARAMETER; } else { TempParam = ShellCommandLineGetRawValue(Package, 1); ASSERT(TempParam != NULL); InFileName = ShellFindFilePath(TempParam); OutFileName = ShellCommandLineGetRawValue(Package, 2); if (InFileName == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"eficompress", TempParam); ShellStatus = SHELL_NOT_FOUND; } else { if (ShellIsDirectory(InFileName) == EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", InFileName); ShellStatus = SHELL_INVALID_PARAMETER; } if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, L"eficompress", OutFileName); ShellStatus = SHELL_INVALID_PARAMETER; } if (ShellStatus == SHELL_SUCCESS) { Status = ShellOpenFileByName(InFileName, &InShellFileHandle, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 1)); ShellStatus = SHELL_NOT_FOUND; } Status = ShellOpenFileByName(OutFileName, &OutShellFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"eficompress", ShellCommandLineGetRawValue(Package, 2)); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus == SHELL_SUCCESS) { Status = gEfiShellProtocol->GetFileSize(InShellFileHandle, &InSize); ASSERT_EFI_ERROR(Status); InBuffer = AllocateZeroPool((UINTN)InSize); if (InBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { InSize2 = (UINTN) InSize; Status = gEfiShellProtocol->ReadFile (InShellFileHandle, &InSize2, InBuffer); InSize = InSize2; ASSERT_EFI_ERROR (Status); Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); if (Status == EFI_BUFFER_TOO_SMALL) { OutBuffer = AllocateZeroPool ((UINTN) OutSize); if (OutBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; } else { Status = Compress (InBuffer, InSize, OutBuffer, &OutSize); } } } if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_COMPRESS_FAIL), gShellDebug1HiiHandle, Status); ShellStatus = ((Status == EFI_OUT_OF_RESOURCES) ? SHELL_OUT_OF_RESOURCES : SHELL_DEVICE_ERROR); } else { OutSize2 = (UINTN)OutSize; Status = gEfiShellProtocol->WriteFile(OutShellFileHandle, &OutSize2, OutBuffer); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, L"eficompress", OutFileName); ShellStatus = SHELL_DEVICE_ERROR; } } } } } ShellCommandLineFreeVarList (Package); } if (InShellFileHandle != NULL) { gEfiShellProtocol->CloseFile(InShellFileHandle); } if (OutShellFileHandle != NULL) { gEfiShellProtocol->CloseFile(OutShellFileHandle); } SHELL_FREE_NON_NULL(InFileName); SHELL_FREE_NON_NULL(InBuffer); SHELL_FREE_NON_NULL(OutBuffer); return (ShellStatus); }
/** Function for 'comp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunComp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; UINTN LoopVar; SHELL_FILE_HANDLE FileHandle1; SHELL_FILE_HANDLE FileHandle2; UINT8 ErrorCount; UINT64 Size1; UINT64 Size2; UINT8 DataFromFile1; UINT8 DataFromFile2; UINT8 ADF_File11; UINT8 ADF_File12; UINT8 ADF_File13; UINT8 ADF_File21; UINT8 ADF_File22; UINT8 ADF_File23; UINTN DataSizeFromFile1; UINTN DataSizeFromFile2; CHAR16 *FileName1; CHAR16 *FileName2; CONST CHAR16 *TempParam; UINTN ErrorAddress; ErrorCount = 0; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; FileName1 = NULL; FileName2 = NULL; FileHandle1 = NULL; FileHandle2 = NULL; Size1 = 0; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"comp", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"comp"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) < 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"comp"); ShellStatus = SHELL_INVALID_PARAMETER; } else { TempParam = ShellCommandLineGetRawValue(Package, 1); ASSERT(TempParam != NULL); FileName1 = ShellFindFilePath(TempParam); if (FileName1 == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } else { Status = ShellOpenFileByName(FileName1, &FileHandle1, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } } TempParam = ShellCommandLineGetRawValue(Package, 2); ASSERT(TempParam != NULL); FileName2 = ShellFindFilePath(TempParam); if (FileName2 == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } else { Status = ShellOpenFileByName(FileName2, &FileHandle2, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus == SHELL_SUCCESS) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_HEADER), gShellDebug1HiiHandle, FileName1, FileName2); Status = gEfiShellProtocol->GetFileSize(FileHandle1, &Size1); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->GetFileSize(FileHandle2, &Size2); ASSERT_EFI_ERROR(Status); if (Size1 != Size2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_SIZE_FAIL), gShellDebug1HiiHandle); ErrorCount++; ShellStatus = SHELL_NOT_EQUAL; } } if (ShellStatus == SHELL_SUCCESS) { for (LoopVar = 0 ; LoopVar < Size1 && ErrorCount <= 10 ; LoopVar++) { DataSizeFromFile1 = 1; DataSizeFromFile2 = 1; Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &DataFromFile1); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &DataFromFile2); ASSERT_EFI_ERROR(Status); if (DataFromFile1 != DataFromFile2) { ErrorAddress = LoopVar; ADF_File11 = 0; ADF_File12 = 0; ADF_File13 = 0; ADF_File21 = 0; ADF_File22 = 0; ADF_File23 = 0; // // Now check the next 3 bytes if possible. This will make output // cleaner when there are a sequence of differences. // if (LoopVar + 1 < Size1) { LoopVar++; DataSizeFromFile1 = 1; DataSizeFromFile2 = 1; Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File11); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File21); ASSERT_EFI_ERROR(Status); if (LoopVar + 1 < Size1) { LoopVar++; DataSizeFromFile1 = 1; DataSizeFromFile2 = 1; Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File12); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File22); ASSERT_EFI_ERROR(Status); if (LoopVar + 1 < Size1) { LoopVar++; DataSizeFromFile1 = 1; DataSizeFromFile2 = 1; Status = gEfiShellProtocol->ReadFile(FileHandle1, &DataSizeFromFile1, &ADF_File13); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->ReadFile(FileHandle2, &DataSizeFromFile2, &ADF_File23); ASSERT_EFI_ERROR(Status); } } } // // Print out based on highest of the 4 bytes that are different. // if (ADF_File13 != ADF_File23) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_COMP_SPOT_FAIL4), gShellDebug1HiiHandle, ++ErrorCount, FileName1, ErrorAddress, DataFromFile1, ADF_File11, ADF_File12, ADF_File13, DataFromFile1, ADF_File11, ADF_File12, ADF_File13, FileName2, ErrorAddress, DataFromFile2, ADF_File21, ADF_File22, ADF_File23, DataFromFile2, ADF_File21, ADF_File22, ADF_File23 ); } else if (ADF_File12 != ADF_File22) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_COMP_SPOT_FAIL3), gShellDebug1HiiHandle, ++ErrorCount, FileName1, ErrorAddress, DataFromFile1, ADF_File11, ADF_File12, DataFromFile1, ADF_File11, ADF_File12, FileName2, ErrorAddress, DataFromFile2, ADF_File21, ADF_File22, DataFromFile2, ADF_File21, ADF_File22 ); } else if (ADF_File11 != ADF_File21) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_COMP_SPOT_FAIL2), gShellDebug1HiiHandle, ++ErrorCount, FileName1, ErrorAddress, DataFromFile1, ADF_File11, DataFromFile1, ADF_File11, FileName2, ErrorAddress, DataFromFile2, ADF_File21, DataFromFile2, ADF_File21 ); } else { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_COMP_SPOT_FAIL1), gShellDebug1HiiHandle, ++ErrorCount, FileName1, ErrorAddress, DataFromFile1, DataFromFile1, FileName2, ErrorAddress, DataFromFile2, DataFromFile2 ); } ShellStatus = SHELL_NOT_EQUAL; } } if (ErrorCount == 0) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_PASS), gShellDebug1HiiHandle); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_FAIL), gShellDebug1HiiHandle); } } } ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL(FileName1); SHELL_FREE_NON_NULL(FileName2); if (FileHandle1 != NULL) { gEfiShellProtocol->CloseFile(FileHandle1); } if (FileHandle2 != NULL) { gEfiShellProtocol->CloseFile(FileHandle2); } return (ShellStatus); }
/** Function for 'decompress' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunEfiDecompress ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; SHELL_FILE_HANDLE InFileHandle; SHELL_FILE_HANDLE OutFileHandle; UINT32 OutSize; UINTN OutSizeTemp; VOID *OutBuffer; UINTN InSize; VOID *InBuffer; CHAR16 *InFileName; CONST CHAR16 *OutFileName; UINT64 Temp64Bit; UINT32 ScratchSize; VOID *ScratchBuffer; EFI_DECOMPRESS_PROTOCOL *Decompress; CONST CHAR16 *TempParam; InFileName = NULL; OutFileName = NULL; OutSize = 0; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; OutBuffer = NULL; InBuffer = NULL; ScratchBuffer = NULL; InFileHandle = NULL; OutFileHandle = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) < 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle); ShellStatus = SHELL_INVALID_PARAMETER; } else { TempParam = ShellCommandLineGetRawValue(Package, 1); ASSERT(TempParam != NULL); InFileName = ShellFindFilePath(TempParam); OutFileName = ShellCommandLineGetRawValue(Package, 2); if (InFileName == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, TempParam); ShellStatus = SHELL_NOT_FOUND; } else { if (ShellIsDirectory(InFileName) == EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, InFileName); ShellStatus = SHELL_INVALID_PARAMETER; } if (ShellIsDirectory(OutFileName) == EFI_SUCCESS){ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_NOT_DIR), gShellDebug1HiiHandle, OutFileName); ShellStatus = SHELL_INVALID_PARAMETER; } if (ShellStatus == SHELL_SUCCESS) { Status = ShellOpenFileByName(InFileName, &InFileHandle, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, 1), Status); ShellStatus = SHELL_NOT_FOUND; } Status = ShellOpenFileByName(OutFileName, &OutFileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_OPEN_FAIL), gShellDebug1HiiHandle, ShellCommandLineGetRawValue(Package, 2), Status); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus == SHELL_SUCCESS) { Status = FileHandleGetSize(InFileHandle, &Temp64Bit); ASSERT(Temp64Bit <= (UINT32)(-1)); InSize = (UINTN)Temp64Bit; ASSERT_EFI_ERROR(Status); InBuffer = AllocateZeroPool(InSize); ASSERT(InBuffer != NULL); Status = gEfiShellProtocol->ReadFile(InFileHandle, &InSize, InBuffer); ASSERT_EFI_ERROR(Status); Status = gBS->LocateProtocol(&gEfiDecompressProtocolGuid, NULL, (VOID**)&Decompress); ASSERT_EFI_ERROR(Status); Status = Decompress->GetInfo(Decompress, InBuffer, (UINT32)InSize, &OutSize, &ScratchSize); ASSERT_EFI_ERROR(Status); OutBuffer = AllocateZeroPool(OutSize); ScratchBuffer = AllocateZeroPool(ScratchSize); ASSERT(OutBuffer != NULL); ASSERT(ScratchBuffer != NULL); Status = Decompress->Decompress(Decompress, InBuffer, (UINT32)InSize, OutBuffer, OutSize, ScratchBuffer, ScratchSize); ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_EFI_DECOMPRESS_FAIL), gShellDebug1HiiHandle, Status); ShellStatus = SHELL_DEVICE_ERROR; } else { OutSizeTemp = OutSize; Status = gEfiShellProtocol->WriteFile(OutFileHandle, &OutSizeTemp, OutBuffer); OutSize = (UINT32)OutSizeTemp; if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_WRITE_FAIL), gShellDebug1HiiHandle, OutFileName, Status); ShellStatus = SHELL_DEVICE_ERROR; } } } } } ShellCommandLineFreeVarList (Package); } if (InFileHandle != NULL) { gEfiShellProtocol->CloseFile(InFileHandle); } if (OutFileHandle != NULL) { gEfiShellProtocol->CloseFile(OutFileHandle); } SHELL_FREE_NON_NULL(InFileName); SHELL_FREE_NON_NULL(InBuffer); SHELL_FREE_NON_NULL(OutBuffer); SHELL_FREE_NON_NULL(ScratchBuffer); return (ShellStatus); }
/** Function for 'comp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunComp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; CHAR16 *FileName1; CHAR16 *FileName2; CONST CHAR16 *TempParam; SHELL_STATUS ShellStatus; SHELL_FILE_HANDLE FileHandle1; SHELL_FILE_HANDLE FileHandle2; UINT64 Size1; UINT64 Size2; UINT64 DifferentBytes; UINT64 DifferentCount; UINT8 DiffPointNumber; UINT8 OneByteFromFile1; UINT8 OneByteFromFile2; UINT8 *DataFromFile1; UINT8 *DataFromFile2; UINTN InsertPosition1; UINTN InsertPosition2; UINTN DataSizeFromFile1; UINTN DataSizeFromFile2; UINTN TempAddress; UINTN Index; UINTN DiffPointAddress; READ_STATUS ReadStatus; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; FileName1 = NULL; FileName2 = NULL; FileHandle1 = NULL; FileHandle2 = NULL; DataFromFile1 = NULL; DataFromFile2 = NULL; ReadStatus = OutOfDiffPoint; DifferentCount = 10; DifferentBytes = 4; DiffPointNumber = 0; InsertPosition1 = 0; InsertPosition2 = 0; TempAddress = 0; DiffPointAddress = 0; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); // ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return SHELL_UNSUPPORTED; } Status = CommandInit(); // ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return SHELL_UNSUPPORTED; } // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"comp", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } /* else { ASSERT(FALSE); } */ } else { if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"comp"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) < 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"comp"); ShellStatus = SHELL_INVALID_PARAMETER; } else { TempParam = ShellCommandLineGetRawValue(Package, 1); ASSERT(TempParam != NULL); FileName1 = ShellFindFilePath(TempParam); if (FileName1 == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } else { Status = ShellOpenFileByName(FileName1, &FileHandle1, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } } TempParam = ShellCommandLineGetRawValue(Package, 2); ASSERT(TempParam != NULL); FileName2 = ShellFindFilePath(TempParam); if (FileName2 == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_FILE_FIND_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } else { Status = ShellOpenFileByName(FileName2, &FileHandle2, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellDebug1HiiHandle, L"comp", TempParam); ShellStatus = SHELL_NOT_FOUND; } } if (ShellStatus == SHELL_SUCCESS) { Status = gEfiShellProtocol->GetFileSize(FileHandle1, &Size1); ASSERT_EFI_ERROR(Status); Status = gEfiShellProtocol->GetFileSize(FileHandle2, &Size2); ASSERT_EFI_ERROR(Status); if (ShellCommandLineGetFlag (Package, L"-n")) { TempParam = ShellCommandLineGetValue (Package, L"-n"); if (TempParam == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-n"); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (gUnicodeCollation->StriColl (gUnicodeCollation, (CHAR16 *)TempParam, L"all") == 0) { DifferentCount = MAX_UINTN; } else { Status = ShellConvertStringToUint64 (TempParam, &DifferentCount, FALSE, TRUE); if (EFI_ERROR(Status) || DifferentCount == 0) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-n"); ShellStatus = SHELL_INVALID_PARAMETER; } } } } if (ShellCommandLineGetFlag (Package, L"-s")) { TempParam = ShellCommandLineGetValue (Package, L"-s"); if (TempParam == NULL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"comp", L"-s"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = ShellConvertStringToUint64 (TempParam, &DifferentBytes, FALSE, TRUE); if (EFI_ERROR(Status) || DifferentBytes == 0) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"comp", TempParam, L"-s"); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (DifferentBytes > MAX (Size1, Size2)) { DifferentBytes = MAX (Size1, Size2); } } } } } if (ShellStatus == SHELL_SUCCESS) { DataFromFile1 = AllocateZeroPool ((UINTN)DifferentBytes); DataFromFile2 = AllocateZeroPool ((UINTN)DifferentBytes); if (DataFromFile1 == NULL || DataFromFile2 == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; SHELL_FREE_NON_NULL (DataFromFile1); SHELL_FREE_NON_NULL (DataFromFile2); } } if (ShellStatus == SHELL_SUCCESS) { while (DiffPointNumber < DifferentCount) { DataSizeFromFile1 = 1; DataSizeFromFile2 = 1; OneByteFromFile1 = 0; OneByteFromFile2 = 0; Status = gEfiShellProtocol->ReadFile (FileHandle1, &DataSizeFromFile1, &OneByteFromFile1); ASSERT_EFI_ERROR (Status); Status = gEfiShellProtocol->ReadFile (FileHandle2, &DataSizeFromFile2, &OneByteFromFile2); ASSERT_EFI_ERROR (Status); TempAddress++; // // 1.When end of file and no chars in DataFromFile buffer, then break while. // 2.If no more char in File1 or File2, The ReadStatus is InPrevDiffPoint forever. // So the previous different point is the last one, then break the while block. // if ( (DataSizeFromFile1 == 0 && InsertPosition1 == 0 && DataSizeFromFile2 == 0 && InsertPosition2 == 0) || (ReadStatus == InPrevDiffPoint && (DataSizeFromFile1 == 0 || DataSizeFromFile2 == 0)) ) { break; } if (ReadStatus == OutOfDiffPoint) { if (OneByteFromFile1 != OneByteFromFile2) { ReadStatus = InDiffPoint; DiffPointAddress = TempAddress; if (DataSizeFromFile1 == 1) { DataFromFile1[InsertPosition1++] = OneByteFromFile1; } if (DataSizeFromFile2 == 1) { DataFromFile2[InsertPosition2++] = OneByteFromFile2; } } } else if (ReadStatus == InDiffPoint) { if (DataSizeFromFile1 == 1) { DataFromFile1[InsertPosition1++] = OneByteFromFile1; } if (DataSizeFromFile2 == 1) { DataFromFile2[InsertPosition2++] = OneByteFromFile2; } } else if (ReadStatus == InPrevDiffPoint) { if (OneByteFromFile1 == OneByteFromFile2) { ReadStatus = OutOfDiffPoint; } } // // ReadStatus should be always equal InDiffPoint. // if ( InsertPosition1 == DifferentBytes || InsertPosition2 == DifferentBytes || (DataSizeFromFile1 == 0 && DataSizeFromFile2 == 0) ) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_COMP_DIFFERENCE_POINT), gShellDebug1HiiHandle, ++DiffPointNumber); PrintDifferentPoint (FileName1, L"File1", DataFromFile1, InsertPosition1, DiffPointAddress, DifferentBytes); PrintDifferentPoint (FileName2, L"File2", DataFromFile2, InsertPosition2, DiffPointAddress, DifferentBytes); // // One of two buffuers is empty, it means this is the last different point. // if (InsertPosition1 == 0 || InsertPosition2 == 0) { break; } for (Index = 1; Index < InsertPosition1 && Index < InsertPosition2; Index++) { if (DataFromFile1[Index] == DataFromFile2[Index]) { ReadStatus = OutOfDiffPoint; break; } } if (ReadStatus == OutOfDiffPoint) { // // Try to find a new different point in the rest of DataFromFile. // for (; Index < MAX (InsertPosition1,InsertPosition2); Index++) { if (DataFromFile1[Index] != DataFromFile2[Index]) { ReadStatus = InDiffPoint; DiffPointAddress += Index; break; } } } else { // // Doesn't find a new different point, still in the same different point. // ReadStatus = InPrevDiffPoint; } CopyMem (DataFromFile1, DataFromFile1 + Index, InsertPosition1 - Index); CopyMem (DataFromFile2, DataFromFile2 + Index, InsertPosition2 - Index); SetMem (DataFromFile1 + InsertPosition1 - Index, (UINTN)DifferentBytes - InsertPosition1 + Index, 0); SetMem (DataFromFile2 + InsertPosition2 - Index, (UINTN)DifferentBytes - InsertPosition2 + Index, 0); InsertPosition1 -= Index; InsertPosition2 -= Index; } } SHELL_FREE_NON_NULL (DataFromFile1); SHELL_FREE_NON_NULL (DataFromFile2); if (DiffPointNumber == 0) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_PASS), gShellDebug1HiiHandle); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_COMP_FOOTER_FAIL), gShellDebug1HiiHandle); } } } ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL(FileName1); SHELL_FREE_NON_NULL(FileName2); if (FileHandle1 != NULL) { gEfiShellProtocol->CloseFile(FileHandle1); } if (FileHandle2 != NULL) { gEfiShellProtocol->CloseFile(FileHandle2); } return (ShellStatus); }