X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FLibrary%2FUefiShellLib%2FUefiShellLib.c;h=42ae6e9bb0cd7d92204907d184f8e4267f5b8ed5;hb=0c1950ba5e6c0a982a763ccd5d325ddbf236ad28;hp=6d885f4681f51df49d83dcb1986ac1997c698cc1;hpb=8bd282bee9909a0ac414f11c9274c473dbb9a538;p=mirror_edk2.git diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c index 6d885f4681..42ae6e9bb0 100644 --- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c +++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c @@ -30,8 +30,8 @@ SHELL_PARAM_ITEM SfoParamList[] = { }; EFI_SHELL_ENVIRONMENT2 *mEfiShellEnvironment2; EFI_SHELL_INTERFACE *mEfiShellInterface; -EFI_SHELL_PROTOCOL *mEfiShellProtocol; -EFI_SHELL_PARAMETERS_PROTOCOL *mEfiShellParametersProtocol; +EFI_SHELL_PROTOCOL *gEfiShellProtocol; +EFI_SHELL_PARAMETERS_PROTOCOL *gEfiShellParametersProtocol; EFI_HANDLE mEfiShellEnvironment2Handle; FILE_HANDLE_FUNCTION_MAP FileFunctionMap; @@ -84,6 +84,8 @@ ShellIsDecimalDigitCharacter ( Helper function to find ShellEnvironment2 for constructor. @param[in] ImageHandle A copy of the calling image's handle. + + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. **/ EFI_STATUS EFIAPI @@ -123,7 +125,9 @@ ShellFindSE2 ( // if (Status == EFI_BUFFER_TOO_SMALL) { Buffer = (EFI_HANDLE*)AllocateZeroPool(BufferSize); - ASSERT(Buffer != NULL); + if (Buffer == NULL) { + return (EFI_OUT_OF_RESOURCES); + } Status = gBS->LocateHandle (ByProtocol, &gEfiShellEnvironment2Guid, NULL, // ignored for ByProtocol @@ -182,7 +186,7 @@ ShellLibConstructorWorker ( Status = gBS->OpenProtocol( ImageHandle, &gEfiShellProtocolGuid, - (VOID **)&mEfiShellProtocol, + (VOID **)&gEfiShellProtocol, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL @@ -194,25 +198,25 @@ ShellLibConstructorWorker ( Status = gBS->LocateProtocol( &gEfiShellProtocolGuid, NULL, - (VOID **)&mEfiShellProtocol + (VOID **)&gEfiShellProtocol ); if (EFI_ERROR(Status)) { - mEfiShellProtocol = NULL; + gEfiShellProtocol = NULL; } } Status = gBS->OpenProtocol( ImageHandle, &gEfiShellParametersProtocolGuid, - (VOID **)&mEfiShellParametersProtocol, + (VOID **)&gEfiShellParametersProtocol, ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR(Status)) { - mEfiShellParametersProtocol = NULL; + gEfiShellParametersProtocol = NULL; } - if (mEfiShellParametersProtocol == NULL || mEfiShellProtocol == NULL) { + if (gEfiShellParametersProtocol == NULL || gEfiShellProtocol == NULL) { // // Moved to seperate function due to complexity // @@ -238,18 +242,18 @@ ShellLibConstructorWorker ( // only success getting 2 of either the old or new, but no 1/2 and 1/2 // if ((mEfiShellEnvironment2 != NULL && mEfiShellInterface != NULL) || - (mEfiShellProtocol != NULL && mEfiShellParametersProtocol != NULL) ) { - if (mEfiShellProtocol != NULL) { - FileFunctionMap.GetFileInfo = mEfiShellProtocol->GetFileInfo; - FileFunctionMap.SetFileInfo = mEfiShellProtocol->SetFileInfo; - FileFunctionMap.ReadFile = mEfiShellProtocol->ReadFile; - FileFunctionMap.WriteFile = mEfiShellProtocol->WriteFile; - FileFunctionMap.CloseFile = mEfiShellProtocol->CloseFile; - FileFunctionMap.DeleteFile = mEfiShellProtocol->DeleteFile; - FileFunctionMap.GetFilePosition = mEfiShellProtocol->GetFilePosition; - FileFunctionMap.SetFilePosition = mEfiShellProtocol->SetFilePosition; - FileFunctionMap.FlushFile = mEfiShellProtocol->FlushFile; - FileFunctionMap.GetFileSize = mEfiShellProtocol->GetFileSize; + (gEfiShellProtocol != NULL && gEfiShellParametersProtocol != NULL) ) { + if (gEfiShellProtocol != NULL) { + FileFunctionMap.GetFileInfo = gEfiShellProtocol->GetFileInfo; + FileFunctionMap.SetFileInfo = gEfiShellProtocol->SetFileInfo; + FileFunctionMap.ReadFile = gEfiShellProtocol->ReadFile; + FileFunctionMap.WriteFile = gEfiShellProtocol->WriteFile; + FileFunctionMap.CloseFile = gEfiShellProtocol->CloseFile; + FileFunctionMap.DeleteFile = gEfiShellProtocol->DeleteFile; + FileFunctionMap.GetFilePosition = gEfiShellProtocol->GetFilePosition; + FileFunctionMap.SetFilePosition = gEfiShellProtocol->SetFilePosition; + FileFunctionMap.FlushFile = gEfiShellProtocol->FlushFile; + FileFunctionMap.GetFileSize = gEfiShellProtocol->GetFileSize; } else { FileFunctionMap.GetFileInfo = (EFI_SHELL_GET_FILE_INFO)FileHandleGetInfo; FileFunctionMap.SetFileInfo = (EFI_SHELL_SET_FILE_INFO)FileHandleSetInfo; @@ -285,8 +289,8 @@ ShellLibConstructor ( ) { mEfiShellEnvironment2 = NULL; - mEfiShellProtocol = NULL; - mEfiShellParametersProtocol = NULL; + gEfiShellProtocol = NULL; + gEfiShellParametersProtocol = NULL; mEfiShellInterface = NULL; mEfiShellEnvironment2Handle = NULL; @@ -330,19 +334,19 @@ ShellLibDestructor ( NULL); mEfiShellInterface = NULL; } - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { gBS->CloseProtocol(ImageHandle, &gEfiShellProtocolGuid, ImageHandle, NULL); - mEfiShellProtocol = NULL; + gEfiShellProtocol = NULL; } - if (mEfiShellParametersProtocol != NULL) { + if (gEfiShellParametersProtocol != NULL) { gBS->CloseProtocol(ImageHandle, &gEfiShellParametersProtocolGuid, ImageHandle, NULL); - mEfiShellParametersProtocol = NULL; + gEfiShellParametersProtocol = NULL; } mEfiShellEnvironment2Handle = NULL; @@ -483,20 +487,18 @@ ShellOpenFileByDevicePath( EFI_FILE_PROTOCOL *Handle1; EFI_FILE_PROTOCOL *Handle2; - // - // ASERT for FileHandle, FilePath, and DeviceHandle being NULL - // - ASSERT(FilePath != NULL); - ASSERT(FileHandle != NULL); - ASSERT(DeviceHandle != NULL); + if (FilePath == NULL || FileHandle == NULL || DeviceHandle == NULL) { + return (EFI_INVALID_PARAMETER); + } + // // which shell interface should we use // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // use UEFI Shell 2.0 method. // - FileName = mEfiShellProtocol->GetFilePathFromDevicePath(*FilePath); + FileName = gEfiShellProtocol->GetFilePathFromDevicePath(*FilePath); if (FileName == NULL) { return (EFI_INVALID_PARAMETER); } @@ -601,7 +603,7 @@ ShellOpenFileByDevicePath( otherwise, the Filehandle is NULL. The Attributes is valid only for EFI_FILE_MODE_CREATE. - if FileNAme is NULL then ASSERT() + if FileName is NULL then ASSERT() @param FileName pointer to file name @param FileHandle pointer to the file handle. @@ -648,14 +650,14 @@ ShellOpenFileByName( return (EFI_INVALID_PARAMETER); } - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { if ((OpenMode & EFI_FILE_MODE_CREATE) == EFI_FILE_MODE_CREATE && (Attributes & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY) { return ShellCreateDirectory(FileName, FileHandle); } // // Use UEFI Shell 2.0 method // - Status = mEfiShellProtocol->OpenFileByName(FileName, + Status = gEfiShellProtocol->OpenFileByName(FileName, FileHandle, OpenMode); if (StrCmp(FileName, L"NUL") != 0 && !EFI_ERROR(Status) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)){ @@ -718,11 +720,11 @@ ShellCreateDirectory( OUT SHELL_FILE_HANDLE *FileHandle ) { - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // Use UEFI Shell 2.0 method // - return (mEfiShellProtocol->CreateFile(DirectoryName, + return (gEfiShellProtocol->CreateFile(DirectoryName, EFI_FILE_DIRECTORY, FileHandle )); @@ -1033,12 +1035,12 @@ ShellGetExecutionBreakFlag( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // We are using UEFI Shell 2.0; see if the event has been triggered // - if (gBS->CheckEvent(mEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) { + if (gBS->CheckEvent(gEfiShellProtocol->ExecutionBreak) != EFI_SUCCESS) { return (FALSE); } return (TRUE); @@ -1047,8 +1049,11 @@ ShellGetExecutionBreakFlag( // // using EFI Shell; call the function to check // - ASSERT(mEfiShellEnvironment2 != NULL); - return (mEfiShellEnvironment2->GetExecutionBreak()); + if (mEfiShellEnvironment2 != NULL) { + return (mEfiShellEnvironment2->GetExecutionBreak()); + } + + return (FALSE); } /** return the value of an environment variable @@ -1070,19 +1075,18 @@ ShellGetEnvironmentVariable ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { - return (mEfiShellProtocol->GetEnv(EnvKey)); + if (gEfiShellProtocol != NULL) { + return (gEfiShellProtocol->GetEnv(EnvKey)); } // - // ASSERT that we must have EFI shell + // Check for EFI shell // - ASSERT(mEfiShellEnvironment2 != NULL); + if (mEfiShellEnvironment2 != NULL) { + return (mEfiShellEnvironment2->GetEnv((CHAR16*)EnvKey)); + } - // - // using EFI Shell - // - return (mEfiShellEnvironment2->GetEnv((CHAR16*)EnvKey)); + return NULL; } /** set the value of an environment variable @@ -1115,8 +1119,8 @@ ShellSetEnvironmentVariable ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { - return (mEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile)); + if (gEfiShellProtocol != NULL) { + return (gEfiShellProtocol->SetEnv(EnvKey, EnvVal, Volatile)); } // @@ -1168,26 +1172,30 @@ ShellExecute ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // Call UEFI Shell 2.0 version (not using Output parameter) // - return (mEfiShellProtocol->Execute(ParentHandle, + return (gEfiShellProtocol->Execute(ParentHandle, CommandLine, EnvironmentVariables, Status)); } + // - // ASSERT that we must have EFI shell - // - ASSERT(mEfiShellEnvironment2 != NULL); - // - // Call EFI Shell version (not using EnvironmentVariables or Status parameters) - // Due to oddity in the EFI shell we want to dereference the ParentHandle here + // Check for EFI shell // - return (mEfiShellEnvironment2->Execute(*ParentHandle, - CommandLine, - Output)); + if (mEfiShellEnvironment2 != NULL) { + // + // Call EFI Shell version (not using EnvironmentVariables or Status parameters) + // Due to oddity in the EFI shell we want to dereference the ParentHandle here + // + return (mEfiShellEnvironment2->Execute(*ParentHandle, + CommandLine, + Output)); + } + + return (EFI_UNSUPPORTED); } /** Retreives the current directory path @@ -1210,9 +1218,10 @@ ShellGetCurrentDir ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { - return (mEfiShellProtocol->GetCurDir(DeviceName)); + if (gEfiShellProtocol != NULL) { + return (gEfiShellProtocol->GetCurDir(DeviceName)); } + // // Check for EFI shell // @@ -1243,43 +1252,45 @@ ShellSetPageBreakMode ( // // check for UEFI Shell 2.0 // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // Enable with UEFI 2.0 Shell // - mEfiShellProtocol->EnablePageBreak(); + gEfiShellProtocol->EnablePageBreak(); return; } else { // - // ASSERT that must have EFI Shell - // - ASSERT(mEfiShellEnvironment2 != NULL); + // Check for EFI shell // - // Enable with EFI Shell - // - mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF); - return; + if (mEfiShellEnvironment2 != NULL) { + // + // Enable with EFI Shell + // + mEfiShellEnvironment2->EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF); + return; + } } } else { // // check for UEFI Shell 2.0 // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { // // Disable with UEFI 2.0 Shell // - mEfiShellProtocol->DisablePageBreak(); + gEfiShellProtocol->DisablePageBreak(); return; } else { // - // ASSERT that must have EFI Shell - // - ASSERT(mEfiShellEnvironment2 != NULL); + // Check for EFI shell // - // Disable with EFI Shell - // - mEfiShellEnvironment2->DisablePageBreak (); - return; + if (mEfiShellEnvironment2 != NULL) { + // + // Disable with EFI Shell + // + mEfiShellEnvironment2->DisablePageBreak (); + return; + } } } } @@ -1306,8 +1317,8 @@ typedef struct { EFI_SHELL_FILE_INFO based list. it is up to the caller to free the memory via the ShellCloseFileMetaArg function. - @param[in] FileList the EFI shell list type - @param[in,out] ListHead the list to add to + @param[in] FileList the EFI shell list type + @param[in, out] ListHead the list to add to @retval the resultant head of the double linked new format list; **/ @@ -1353,8 +1364,9 @@ InternalShellConvertFileListType ( // allocate a new EFI_SHELL_FILE_INFO object // NewInfo = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); - ASSERT(NewInfo != NULL); if (NewInfo == NULL) { + ShellCloseFileMetaArg(&(EFI_SHELL_FILE_INFO*)ListHead); + ListHead = NULL; break; } @@ -1377,9 +1389,11 @@ InternalShellConvertFileListType ( // // make sure all the memory allocations were sucessful // - ASSERT(NewInfo->FullName != NULL); - ASSERT(NewInfo->FileName != NULL); - ASSERT(NewInfo->Info != NULL); + if (NULL == NewInfo->FullName || NewInfo->FileName == NULL || NewInfo->Info == NULL) { + ShellCloseFileMetaArg(&(EFI_SHELL_FILE_INFO*)ListHead); + ListHead = NULL; + break; + } // // Copt the strings and structure @@ -1438,7 +1452,7 @@ ShellOpenFileMetaArg ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { if (*ListHead == NULL) { *ListHead = (EFI_SHELL_FILE_INFO*)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); if (*ListHead == NULL) { @@ -1446,13 +1460,13 @@ ShellOpenFileMetaArg ( } InitializeListHead(&((*ListHead)->Link)); } - Status = mEfiShellProtocol->OpenFileList(Arg, + Status = gEfiShellProtocol->OpenFileList(Arg, OpenMode, ListHead); if (EFI_ERROR(Status)) { - mEfiShellProtocol->RemoveDupInFileList(ListHead); + gEfiShellProtocol->RemoveDupInFileList(ListHead); } else { - Status = mEfiShellProtocol->RemoveDupInFileList(ListHead); + Status = gEfiShellProtocol->RemoveDupInFileList(ListHead); } if (*ListHead != NULL && IsListEmpty(&(*ListHead)->Link)) { FreePool(*ListHead); @@ -1463,49 +1477,50 @@ ShellOpenFileMetaArg ( } // - // ASSERT that we must have EFI shell - // - ASSERT(mEfiShellEnvironment2 != NULL); - - // - // make sure the list head is initialized + // Check for EFI shell // - InitializeListHead(&mOldStyleFileList); + if (mEfiShellEnvironment2 != NULL) { + // + // make sure the list head is initialized + // + InitializeListHead(&mOldStyleFileList); - // - // Get the EFI Shell list of files - // - Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList); - if (EFI_ERROR(Status)) { - *ListHead = NULL; - return (Status); - } + // + // Get the EFI Shell list of files + // + Status = mEfiShellEnvironment2->FileMetaArg(Arg, &mOldStyleFileList); + if (EFI_ERROR(Status)) { + *ListHead = NULL; + return (Status); + } - if (*ListHead == NULL) { - *ListHead = (EFI_SHELL_FILE_INFO *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); if (*ListHead == NULL) { - return (EFI_OUT_OF_RESOURCES); + *ListHead = (EFI_SHELL_FILE_INFO *)AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); + if (*ListHead == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + InitializeListHead(&((*ListHead)->Link)); } - InitializeListHead(&((*ListHead)->Link)); - } - // - // Convert that to equivalent of UEFI Shell 2.0 structure - // - InternalShellConvertFileListType(&mOldStyleFileList, &(*ListHead)->Link); + // + // Convert that to equivalent of UEFI Shell 2.0 structure + // + InternalShellConvertFileListType(&mOldStyleFileList, &(*ListHead)->Link); - // - // Free the EFI Shell version that was converted. - // - mEfiShellEnvironment2->FreeFileList(&mOldStyleFileList); + // + // Free the EFI Shell version that was converted. + // + mEfiShellEnvironment2->FreeFileList(&mOldStyleFileList); - if ((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink && (*ListHead)->Link.BackLink == &((*ListHead)->Link)) { - FreePool(*ListHead); - *ListHead = NULL; - Status = EFI_NOT_FOUND; + if ((*ListHead)->Link.ForwardLink == (*ListHead)->Link.BackLink && (*ListHead)->Link.BackLink == &((*ListHead)->Link)) { + FreePool(*ListHead); + *ListHead = NULL; + Status = EFI_NOT_FOUND; + } + return (Status); } - return (Status); + return (EFI_UNSUPPORTED); } /** Free the linked list returned from ShellOpenFileMetaArg. @@ -1532,9 +1547,9 @@ ShellCloseFileMetaArg ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellProtocol != NULL) { - return (mEfiShellProtocol->FreeFileList(ListHead)); - } else { + if (gEfiShellProtocol != NULL) { + return (gEfiShellProtocol->FreeFileList(ListHead)); + } else if (mEfiShellEnvironment2 != NULL) { // // Since this is EFI Shell version we need to free our internally made copy // of the list @@ -1551,6 +1566,8 @@ ShellCloseFileMetaArg ( } return EFI_SUCCESS; } + + return (EFI_UNSUPPORTED); } /** @@ -1602,7 +1619,6 @@ ShellFindFilePath ( Size = StrSize(Path); Size += StrSize(FileName); TestPath = AllocateZeroPool(Size); - ASSERT(TestPath != NULL); if (TestPath == NULL) { return (NULL); } @@ -1709,7 +1725,6 @@ ShellFindFilePathEx ( Size = StrSize(FileName); Size += StrSize(FileExtension); TestPath = AllocateZeroPool(Size); - ASSERT(TestPath != NULL); if (TestPath == NULL) { return (NULL); } @@ -1923,6 +1938,10 @@ InternalCommandLineParse ( // initialize the linked list // *CheckPackage = (LIST_ENTRY*)AllocateZeroPool(sizeof(LIST_ENTRY)); + if (*CheckPackage == NULL) { + return (EFI_OUT_OF_RESOURCES); + } + InitializeListHead(*CheckPackage); // @@ -1945,9 +1964,17 @@ InternalCommandLineParse ( // this is a flag // CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE)); - ASSERT(CurrentItemPackage != NULL); + if (CurrentItemPackage == NULL) { + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_OUT_OF_RESOURCES); + } CurrentItemPackage->Name = AllocateZeroPool(StrSize(Argv[LoopCounter])); - ASSERT(CurrentItemPackage->Name != NULL); + if (CurrentItemPackage->Name == NULL) { + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_OUT_OF_RESOURCES); + } StrCpy(CurrentItemPackage->Name, Argv[LoopCounter]); CurrentItemPackage->Type = CurrentItemType; CurrentItemPackage->OriginalPosition = (UINTN)(-1); @@ -2011,11 +2038,19 @@ InternalCommandLineParse ( TempPointer++; } CurrentItemPackage = AllocateZeroPool(sizeof(SHELL_PARAM_PACKAGE)); - ASSERT(CurrentItemPackage != NULL); + if (CurrentItemPackage == NULL) { + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_OUT_OF_RESOURCES); + } CurrentItemPackage->Name = NULL; CurrentItemPackage->Type = TypePosition; CurrentItemPackage->Value = AllocateZeroPool(StrSize(TempPointer)); - ASSERT(CurrentItemPackage->Value != NULL); + if (CurrentItemPackage->Value == NULL) { + ShellCommandLineFreeVarList(*CheckPackage); + *CheckPackage = NULL; + return (EFI_OUT_OF_RESOURCES); + } StrCpy(CurrentItemPackage->Value, TempPointer); CurrentItemPackage->OriginalPosition = Count++; InsertHeadList(*CheckPackage, &CurrentItemPackage->Link); @@ -2025,8 +2060,9 @@ InternalCommandLineParse ( // if (ProblemParam != NULL) { *ProblemParam = AllocateZeroPool(StrSize(Argv[LoopCounter])); - ASSERT(*ProblemParam != NULL); - StrCpy(*ProblemParam, Argv[LoopCounter]); + if (*ProblemParam != NULL) { + StrCpy(*ProblemParam, Argv[LoopCounter]); + } } ShellCommandLineFreeVarList(*CheckPackage); *CheckPackage = NULL; @@ -2089,13 +2125,13 @@ ShellCommandLineParseEx ( // // Check for UEFI Shell 2.0 protocols // - if (mEfiShellParametersProtocol != NULL) { + if (gEfiShellParametersProtocol != NULL) { return (InternalCommandLineParse(CheckList, CheckPackage, ProblemParam, AutoPageBreak, - (CONST CHAR16**) mEfiShellParametersProtocol->Argv, - mEfiShellParametersProtocol->Argc, + (CONST CHAR16**) gEfiShellParametersProtocol->Argv, + gEfiShellParametersProtocol->Argc, AlwaysAllowNumbers)); } @@ -2200,14 +2236,9 @@ ShellCommandLineGetFlag ( CHAR16 *TempString; // - // ASSERT that both CheckPackage and KeyString aren't NULL - // - ASSERT(KeyString != NULL); - - // - // return FALSE for no package + // return FALSE for no package or KeyString is NULL // - if (CheckPackage == NULL) { + if (CheckPackage == NULL || KeyString == NULL) { return (FALSE); } @@ -2269,9 +2300,9 @@ ShellCommandLineGetValue ( CHAR16 *TempString; // - // check for CheckPackage == NULL + // return NULL for no package or KeyString is NULL // - if (CheckPackage == NULL) { + if (CheckPackage == NULL || KeyString == NULL) { return (NULL); } @@ -2443,14 +2474,14 @@ ShellCommandLineCheckDuplicate ( If the string would grow bigger than NewSize it will halt and return error. - @param[in] SourceString The string with source buffer. - @param[in,out] NewString The string with resultant buffer. - @param[in] NewSize The size in bytes of NewString. - @param[in] FindTarget The string to look for. - @param[in] ReplaceWith The string to replace FindTarget with. - @param[in] SkipPreCarrot If TRUE will skip a FindTarget that has a '^' - immediately before it. - @param[in] ParameterReplacing If TRUE will add "" around items with spaces. + @param[in] SourceString The string with source buffer. + @param[in, out] NewString The string with resultant buffer. + @param[in] NewSize The size in bytes of NewString. + @param[in] FindTarget The string to look for. + @param[in] ReplaceWith The string to replace FindTarget with. + @param[in] SkipPreCarrot If TRUE will skip a FindTarget that has a '^' + immediately before it. + @param[in] ParameterReplacing If TRUE will add "" around items with spaces. @retval EFI_INVALID_PARAMETER SourceString was NULL. @retval EFI_INVALID_PARAMETER NewString was NULL. @@ -2491,7 +2522,9 @@ ShellCopySearchAndReplace( Replace = StrnCatGrow(&Replace, NULL, ReplaceWith, 0); } else { Replace = AllocateZeroPool(StrSize(ReplaceWith) + 2*sizeof(CHAR16)); - UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith); + if (Replace != NULL) { + UnicodeSPrint(Replace, StrSize(ReplaceWith) + 2*sizeof(CHAR16), L"\"%s\"", ReplaceWith); + } } if (Replace == NULL) { return (EFI_OUT_OF_RESOURCES); @@ -2547,8 +2580,8 @@ InternalPrintTo ( if (Size == 0) { return (EFI_SUCCESS); } - if (mEfiShellParametersProtocol != NULL) { - return (mEfiShellProtocol->WriteFile(mEfiShellParametersProtocol->StdOut, &Size, (VOID*)String)); + if (gEfiShellParametersProtocol != NULL) { + return (gEfiShellProtocol->WriteFile(gEfiShellParametersProtocol->StdOut, &Size, (VOID*)String)); } if (mEfiShellInterface != NULL) { // @@ -2664,32 +2697,40 @@ InternalShellPrintWorker( // update the attribute // if (ResumeLocation != NULL) { - switch (*(ResumeLocation+1)) { - case (L'N'): - gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute); - break; - case (L'E'): - gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); - break; - case (L'H'): - gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); - break; - case (L'B'): - gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); - break; - case (L'V'): - gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); - break; - default: - // - // Print a simple '%' symbol - // - Status = InternalPrintTo(L"%"); - if (EFI_ERROR(Status)) { + if (*(ResumeLocation-1) == L'^') { + // + // Print a simple '%' symbol + // + Status = InternalPrintTo(L"%"); + ResumeLocation = ResumeLocation - 1; + } else { + switch (*(ResumeLocation+1)) { + case (L'N'): + gST->ConOut->SetAttribute(gST->ConOut, OriginalAttribute); break; - } - ResumeLocation = ResumeLocation - 1; - break; + case (L'E'): + gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_YELLOW, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); + break; + case (L'H'): + gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_WHITE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); + break; + case (L'B'): + gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_BLUE, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); + break; + case (L'V'): + gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR(EFI_GREEN, ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))); + break; + default: + // + // Print a simple '%' symbol + // + Status = InternalPrintTo(L"%"); + if (EFI_ERROR(Status)) { + break; + } + ResumeLocation = ResumeLocation - 1; + break; + } } } else { // @@ -2849,13 +2890,13 @@ ShellIsDirectory( // // try good logic first. // - if (mEfiShellProtocol != NULL) { + if (gEfiShellProtocol != NULL) { TempLocation = StrnCatGrow(&TempLocation, NULL, DirName, 0); TempLocation2 = StrStr(TempLocation, L":"); if (TempLocation2 != NULL && StrLen(StrStr(TempLocation, L":")) == 2) { *(TempLocation2+1) = CHAR_NULL; } - if (mEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) { + if (gEfiShellProtocol->GetDevicePathFromMap(TempLocation) != NULL) { FreePool(TempLocation); return (EFI_SUCCESS); } @@ -3002,8 +3043,8 @@ ShellStrToUintn( if Destination's current length (including NULL terminator) is already more then CurrentSize, then ASSERT() - @param[in,out] Destination The String to append onto - @param[in,out] CurrentSize on call the number of bytes in Destination. On + @param[in, out] Destination The String to append onto + @param[in, out] CurrentSize on call the number of bytes in Destination. On return possibly the new size (still in bytes). if NULL then allocate whatever is needed. @param[in] Source The String to append from @@ -3071,11 +3112,9 @@ StrnCatGrow ( NewSize += 2 * Count * sizeof(CHAR16); } *Destination = ReallocatePool(*CurrentSize, NewSize, *Destination); - ASSERT(*Destination != NULL); *CurrentSize = NewSize; } else { *Destination = AllocateZeroPool((Count+1)*sizeof(CHAR16)); - ASSERT(*Destination != NULL); } // @@ -3798,3 +3837,158 @@ ShellIsHexOrDecimalNumber ( } return (FALSE); } + +/** + Function to read a single line from a SHELL_FILE_HANDLE. The \n is not included in the returned + buffer. The returned buffer must be callee freed. + + If the position upon start is 0, then the Ascii Boolean will be set. This should be + maintained and not changed for all operations with the same file. + + @param[in] Handle SHELL_FILE_HANDLE to read from. + @param[in, out] Ascii Boolean value for indicating whether the file is + Ascii (TRUE) or UCS2 (FALSE). + + @return The line of text from the file. + @retval NULL There was not enough memory available. + + @sa ShellFileHandleReadLine +**/ +CHAR16* +EFIAPI +ShellFileHandleReturnLine( + IN SHELL_FILE_HANDLE Handle, + IN OUT BOOLEAN *Ascii + ) +{ + CHAR16 *RetVal; + UINTN Size; + EFI_STATUS Status; + + Size = 0; + RetVal = NULL; + + Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii); + if (Status == EFI_BUFFER_TOO_SMALL) { + RetVal = AllocateZeroPool(Size); + if (RetVal == NULL) { + return (NULL); + } + Status = ShellFileHandleReadLine(Handle, RetVal, &Size, FALSE, Ascii); + + } + if (EFI_ERROR(Status) && (RetVal != NULL)) { + FreePool(RetVal); + RetVal = NULL; + } + return (RetVal); +} + +/** + Function to read a single line (up to but not including the \n) from a SHELL_FILE_HANDLE. + + If the position upon start is 0, then the Ascii Boolean will be set. This should be + maintained and not changed for all operations with the same file. + + @param[in] Handle SHELL_FILE_HANDLE to read from. + @param[in, out] Buffer The pointer to buffer to read into. + @param[in, out] Size The pointer to number of bytes in Buffer. + @param[in] Truncate If the buffer is large enough, this has no effect. + If the buffer is is too small and Truncate is TRUE, + the line will be truncated. + If the buffer is is too small and Truncate is FALSE, + then no read will occur. + + @param[in, out] Ascii Boolean value for indicating whether the file is + Ascii (TRUE) or UCS2 (FALSE). + + @retval EFI_SUCCESS The operation was successful. The line is stored in + Buffer. + @retval EFI_INVALID_PARAMETER Handle was NULL. + @retval EFI_INVALID_PARAMETER Size was NULL. + @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line. + Size was updated to the minimum space required. +**/ +EFI_STATUS +EFIAPI +ShellFileHandleReadLine( + IN SHELL_FILE_HANDLE Handle, + IN OUT CHAR16 *Buffer, + IN OUT UINTN *Size, + IN BOOLEAN Truncate, + IN OUT BOOLEAN *Ascii + ) +{ + EFI_STATUS Status; + CHAR16 CharBuffer; + UINTN CharSize; + UINTN CountSoFar; + UINT64 OriginalFilePosition; + + + if (Handle == NULL + ||Size == NULL + ){ + return (EFI_INVALID_PARAMETER); + } + if (Buffer == NULL) { + ASSERT(*Size == 0); + } else { + *Buffer = CHAR_NULL; + } + gEfiShellProtocol->GetFilePosition(Handle, &OriginalFilePosition); + if (OriginalFilePosition == 0) { + CharSize = sizeof(CHAR16); + Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer); + ASSERT_EFI_ERROR(Status); + if (CharBuffer == gUnicodeFileTag) { + *Ascii = FALSE; + } else { + *Ascii = TRUE; + gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition); + } + } + + for (CountSoFar = 0;;CountSoFar++){ + CharBuffer = 0; + if (*Ascii) { + CharSize = sizeof(CHAR8); + } else { + CharSize = sizeof(CHAR16); + } + Status = gEfiShellProtocol->ReadFile(Handle, &CharSize, &CharBuffer); + if ( EFI_ERROR(Status) + || CharSize == 0 + || (CharBuffer == L'\n' && !(*Ascii)) + || (CharBuffer == '\n' && *Ascii) + ){ + break; + } + // + // if we have space save it... + // + if ((CountSoFar+1)*sizeof(CHAR16) < *Size){ + ASSERT(Buffer != NULL); + ((CHAR16*)Buffer)[CountSoFar] = CharBuffer; + ((CHAR16*)Buffer)[CountSoFar+1] = CHAR_NULL; + } + } + + // + // if we ran out of space tell when... + // + if ((CountSoFar+1)*sizeof(CHAR16) > *Size){ + *Size = (CountSoFar+1)*sizeof(CHAR16); + if (!Truncate) { + gEfiShellProtocol->SetFilePosition(Handle, OriginalFilePosition); + } else { + DEBUG((DEBUG_WARN, "The line was truncated in ShellFileHandleReadLine")); + } + return (EFI_BUFFER_TOO_SMALL); + } + while(Buffer[StrLen(Buffer)-1] == L'\r') { + Buffer[StrLen(Buffer)-1] = CHAR_NULL; + } + + return (Status); +}