X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ShellPkg%2FApplication%2FShell%2FShellProtocol.c;h=89132969b6aad9ab5523016f004b61b762d42c17;hb=a71003f2491a26b96b808064d35c8fd01d6422ed;hp=392298989ee6dd7a943deb50453d8a1d09580eef;hpb=8be0ba36fc347bac7199e7dbb8d373ea5e4bf0af;p=mirror_edk2.git diff --git a/ShellPkg/Application/Shell/ShellProtocol.c b/ShellPkg/Application/Shell/ShellProtocol.c index 392298989e..89132969b6 100644 --- a/ShellPkg/Application/Shell/ShellProtocol.c +++ b/ShellPkg/Application/Shell/ShellProtocol.c @@ -2,7 +2,7 @@ Member functions of EFI_SHELL_PROTOCOL and functions for creation, manipulation, and initialization of EFI_SHELL_PROTOCOL. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -14,7 +14,6 @@ **/ #include "Shell.h" -#include /** Close an open file handle. @@ -37,6 +36,36 @@ EfiShellClose ( return (FileHandleClose(ConvertShellHandleToEfiFileProtocol(FileHandle))); } +/** + Internal worker to determine whether there is a BlockIo somewhere + upon the device path specified. + + @param[in] DevicePath The device path to test. + + @retval TRUE gEfiBlockIoProtocolGuid was installed on a handle with this device path + @retval FALSE gEfiBlockIoProtocolGuid was not found. +**/ +BOOLEAN +EFIAPI +InternalShellProtocolIsBlockIoPresent( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePathCopy; + EFI_STATUS Status; + EFI_HANDLE Handle; + + Handle = NULL; + + DevicePathCopy = (EFI_DEVICE_PATH_PROTOCOL*)DevicePath; + Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &DevicePathCopy, &Handle); + + if ((Handle != NULL) && (!EFI_ERROR(Status))) { + return (TRUE); + } + return (FALSE); +} + /** Internal worker to determine whether there is a file system somewhere upon the device path specified. @@ -86,27 +115,19 @@ InternalShellProtocolDebugPrintMessage ( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText; EFI_STATUS Status; CHAR16 *Temp; Status = EFI_SUCCESS; DEBUG_CODE_BEGIN(); - DevicePathToText = NULL; - Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, - NULL, - (VOID**)&DevicePathToText); if (Mapping != NULL) { DEBUG((EFI_D_INFO, "Added new map item:\"%S\"\r\n", Mapping)); } - if (!EFI_ERROR(Status)) { - if (DevicePath != NULL) { - Temp = DevicePathToText->ConvertDevicePathToText(DevicePath, TRUE, TRUE); - DEBUG((EFI_D_INFO, "DevicePath: %S\r\n", Temp)); - FreePool(Temp); - } - } + Temp = ConvertDevicePathToText(DevicePath, TRUE, TRUE); + DEBUG((EFI_D_INFO, "DevicePath: %S\r\n", Temp)); + FreePool(Temp); + DEBUG_CODE_END(); return (Status); } @@ -176,7 +197,8 @@ EfiShellSetMap( // make sure this is a valid to add device path // ///@todo add BlockIo to this test... - if (!InternalShellProtocolIsSimpleFileSystemPresent(DevicePath)) { + if (!InternalShellProtocolIsSimpleFileSystemPresent(DevicePath) + && !InternalShellProtocolIsBlockIoPresent(DevicePath)) { return (EFI_INVALID_PARAMETER); } @@ -386,6 +408,7 @@ EfiShellGetFilePathFromDevicePath( EFI_HANDLE MapHandle; EFI_STATUS Status; FILEPATH_DEVICE_PATH *FilePath; + FILEPATH_DEVICE_PATH *AlignedNode; PathForReturn = NULL; PathSize = 0; @@ -436,7 +459,10 @@ EfiShellGetFilePathFromDevicePath( // ASSERT((PathForReturn == NULL && PathSize == 0) || (PathForReturn != NULL)); PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, L"\\", 1); - PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, FilePath->PathName, 0); + + AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePath), FilePath); + PathForReturn = StrnCatGrow(&PathForReturn, &PathSize, AlignedNode->PathName, 0); + FreePool(AlignedNode); } } // for loop of remaining nodes } @@ -453,10 +479,12 @@ EfiShellGetFilePathFromDevicePath( This function converts a file system style name to a device path, by replacing any mapping references to the associated device path. - @param Path the pointer to the path + @param[in] Path The pointer to the path. - @return all The pointer of the file path. The file path is callee + @return The pointer of the file path. The file path is callee allocated and should be freed by the caller. + @retval NULL The path could not be found. + @retval NULL There was not enough available memory. **/ EFI_DEVICE_PATH_PROTOCOL * EFIAPI @@ -490,12 +518,13 @@ EfiShellGetDevicePathFromFilePath( Size = StrSize(Cwd); Size += StrSize(Path); NewPath = AllocateZeroPool(Size); - ASSERT(NewPath != NULL); + if (NewPath == NULL) { + return (NULL); + } StrCpy(NewPath, Cwd); - if ((Path[0] == (CHAR16)L'\\') && - (NewPath[StrLen(NewPath)-1] == (CHAR16)L'\\') - ) { - ((CHAR16*)NewPath)[StrLen(NewPath)-1] = CHAR_NULL; + if (*Path == L'\\') { + Path++; + while (PathRemoveLastItem(NewPath)) ; } StrCat(NewPath, Path); DevicePathForReturn = EfiShellGetDevicePathFromFilePath(NewPath); @@ -509,8 +538,7 @@ EfiShellGetDevicePathFromFilePath( // ASSERT((MapName == NULL && Size == 0) || (MapName != NULL)); MapName = StrnCatGrow(&MapName, &Size, Path, (StrStr(Path, L":")-Path+1)); - if (MapName[StrLen(MapName)-1] != L':') { - ASSERT(FALSE); + if (MapName == NULL || MapName[StrLen(MapName)-1] != L':') { return (NULL); } @@ -530,7 +558,6 @@ EfiShellGetDevicePathFromFilePath( // DevicePathCopyForFree = DevicePathCopy = DuplicateDevicePath(DevicePath); if (DevicePathCopy == NULL) { - ASSERT(FALSE); FreePool(MapName); return (NULL); } @@ -551,7 +578,11 @@ EfiShellGetDevicePathFromFilePath( // // build the full device path // - DevicePathForReturn = FileDevicePath(Handle, Path+StrLen(MapName)+1); + if (*(Path+StrLen(MapName)+1) == CHAR_NULL) { + DevicePathForReturn = FileDevicePath(Handle, L"\\"); + } else { + DevicePathForReturn = FileDevicePath(Handle, Path+StrLen(MapName)); + } FreePool(MapName); if (DevicePathCopyForFree != NULL) { @@ -608,14 +639,16 @@ EfiShellGetDeviceName( { EFI_STATUS Status; EFI_COMPONENT_NAME2_PROTOCOL *CompName2; - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_HANDLE *HandleList; UINTN HandleCount; UINTN LoopVar; CHAR16 *DeviceNameToReturn; CHAR8 *Lang; - CHAR8 *TempChar; + UINTN ParentControllerCount; + EFI_HANDLE *ParentControllerBuffer; + UINTN ParentDriverCount; + EFI_HANDLE *ParentDriverBuffer; if (BestDeviceName == NULL || DeviceHandle == NULL @@ -668,23 +701,7 @@ EfiShellGetDeviceName( if (EFI_ERROR(Status)) { continue; } - if (Language == NULL) { - Lang = AllocatePool(AsciiStrSize(CompName2->SupportedLanguages)); - if (Lang == NULL) { - return (EFI_OUT_OF_RESOURCES); - } - AsciiStrCpy(Lang, CompName2->SupportedLanguages); - TempChar = AsciiStrStr(Lang, ";"); - if (TempChar != NULL){ - *TempChar = CHAR_NULL; - } - } else { - Lang = AllocatePool(AsciiStrSize(Language)); - if (Lang == NULL) { - return (EFI_OUT_OF_RESOURCES); - } - AsciiStrCpy(Lang, Language); - } + Lang = GetBestLanguageForDriver(CompName2->SupportedLanguages, Language, FALSE); Status = CompName2->GetControllerName(CompName2, DeviceHandle, NULL, Lang, &DeviceNameToReturn); FreePool(Lang); Lang = NULL; @@ -695,38 +712,79 @@ EfiShellGetDeviceName( if (HandleList != NULL) { FreePool(HandleList); } + + // + // Now check the parent controller using this as the child. + // + if (DeviceNameToReturn == NULL){ + PARSE_HANDLE_DATABASE_PARENTS(DeviceHandle, &ParentControllerCount, &ParentControllerBuffer); + for (LoopVar = 0 ; LoopVar < ParentControllerCount ; LoopVar++) { + PARSE_HANDLE_DATABASE_UEFI_DRIVERS(ParentControllerBuffer[LoopVar], &ParentDriverCount, &ParentDriverBuffer); + for (HandleCount = 0 ; HandleCount < ParentDriverCount ; HandleCount++) { + // + // try using that driver's component name with controller and our driver as the child. + // + Status = gBS->OpenProtocol( + ParentDriverBuffer[HandleCount], + &gEfiComponentName2ProtocolGuid, + (VOID**)&CompName2, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) { + Status = gBS->OpenProtocol( + ParentDriverBuffer[HandleCount], + &gEfiComponentNameProtocolGuid, + (VOID**)&CompName2, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + } + + if (EFI_ERROR(Status)) { + continue; + } + Lang = GetBestLanguageForDriver(CompName2->SupportedLanguages, Language, FALSE); + Status = CompName2->GetControllerName(CompName2, ParentControllerBuffer[LoopVar], DeviceHandle, Lang, &DeviceNameToReturn); + FreePool(Lang); + Lang = NULL; + if (!EFI_ERROR(Status) && DeviceNameToReturn != NULL) { + break; + } + + + + } + SHELL_FREE_NON_NULL(ParentDriverBuffer); + if (!EFI_ERROR(Status) && DeviceNameToReturn != NULL) { + break; + } + } + SHELL_FREE_NON_NULL(ParentControllerBuffer); + } + // + // dont return on fail since we will try device path if that bit is on + // if (DeviceNameToReturn != NULL){ ASSERT(BestDeviceName != NULL); StrnCatGrow(BestDeviceName, NULL, DeviceNameToReturn, 0); return (EFI_SUCCESS); } - // - // dont return on fail since we will try device path if that bit is on - // } if ((Flags & EFI_DEVICE_NAME_USE_DEVICE_PATH) != 0) { - Status = gBS->LocateProtocol( - &gEfiDevicePathToTextProtocolGuid, + Status = gBS->OpenProtocol( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID**)&DevicePath, + gImageHandle, NULL, - (VOID**)&DevicePathToText); - // - // we now have the device path to text protocol - // + EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!EFI_ERROR(Status)) { - Status = gBS->OpenProtocol( - DeviceHandle, - &gEfiDevicePathProtocolGuid, - (VOID**)&DevicePath, - gImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (!EFI_ERROR(Status)) { - // - // use device path to text on the device path - // - *BestDeviceName = DevicePathToText->ConvertDevicePathToText(DevicePath, TRUE, TRUE); - return (EFI_SUCCESS); - } + // + // use device path to text on the device path + // + *BestDeviceName = ConvertDevicePathToText(DevicePath, TRUE, TRUE); + return (EFI_SUCCESS); } } // @@ -884,7 +942,6 @@ InternalOpenFileDevicePath( SHELL_FILE_HANDLE ShellHandle; EFI_FILE_PROTOCOL *Handle1; EFI_FILE_PROTOCOL *Handle2; - EFI_DEVICE_PATH_PROTOCOL *DpCopy; FILEPATH_DEVICE_PATH *AlignedNode; if (FileHandle == NULL) { @@ -894,7 +951,6 @@ InternalOpenFileDevicePath( Handle1 = NULL; Handle2 = NULL; Handle = NULL; - DpCopy = DevicePath; ShellHandle = NULL; FilePathNode = NULL; AlignedNode = NULL; @@ -903,75 +959,46 @@ InternalOpenFileDevicePath( if (!EFI_ERROR(Status)) { Handle1 = ConvertShellHandleToEfiFileProtocol(ShellHandle); - // - // chop off the begining part before the file system part... - // - ///@todo BlockIo? - Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, - &DevicePath, - &Handle); - if (!EFI_ERROR(Status)) { + if (Handle1 != NULL) { // - // To access as a file system, the file path should only - // contain file path components. Follow the file path nodes - // and find the target file + // chop off the begining part before the file system part... // - for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath - ; !IsDevicePathEnd (&FilePathNode->Header) - ; FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header) - ){ - SHELL_FREE_NON_NULL(AlignedNode); - AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePathNode), FilePathNode); - // - // For file system access each node should be a file path component - // - if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH || - DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP - ) { - Status = EFI_UNSUPPORTED; - break; - } - - // - // Open this file path node - // - Handle2 = Handle1; - Handle1 = NULL; - + ///@todo BlockIo? + Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, + &DevicePath, + &Handle); + if (!EFI_ERROR(Status)) { // - // if this is the last node in the DevicePath always create (if that was requested). + // To access as a file system, the file path should only + // contain file path components. Follow the file path nodes + // and find the target file // - if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) { - Status = Handle2->Open ( - Handle2, - &Handle1, - AlignedNode->PathName, - OpenMode, - Attributes - ); - } else { - + for ( FilePathNode = (FILEPATH_DEVICE_PATH *)DevicePath + ; !IsDevicePathEnd (&FilePathNode->Header) + ; FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header) + ){ + SHELL_FREE_NON_NULL(AlignedNode); + AlignedNode = AllocateCopyPool (DevicePathNodeLength(FilePathNode), FilePathNode); // - // This is not the last node and we dont want to 'create' existing - // directory entries... + // For file system access each node should be a file path component // + if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH || + DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP + ) { + Status = EFI_UNSUPPORTED; + break; + } // - // open without letting it create - // prevents error on existing files/directories + // Open this file path node // - Status = Handle2->Open ( - Handle2, - &Handle1, - AlignedNode->PathName, - OpenMode &~EFI_FILE_MODE_CREATE, - Attributes - ); + Handle2 = Handle1; + Handle1 = NULL; + // - // if above failed now open and create the 'item' - // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above) + // if this is the last node in the DevicePath always create (if that was requested). // - if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) { + if (IsDevicePathEnd ((NextDevicePathNode (&FilePathNode->Header)))) { Status = Handle2->Open ( Handle2, &Handle1, @@ -979,20 +1006,51 @@ InternalOpenFileDevicePath( OpenMode, Attributes ); + } else { + + // + // This is not the last node and we dont want to 'create' existing + // directory entries... + // + + // + // open without letting it create + // prevents error on existing files/directories + // + Status = Handle2->Open ( + Handle2, + &Handle1, + AlignedNode->PathName, + OpenMode &~EFI_FILE_MODE_CREATE, + Attributes + ); + // + // if above failed now open and create the 'item' + // if OpenMode EFI_FILE_MODE_CREATE bit was on (but disabled above) + // + if ((EFI_ERROR (Status)) && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) { + Status = Handle2->Open ( + Handle2, + &Handle1, + AlignedNode->PathName, + OpenMode, + Attributes + ); + } } - } - // - // Close the last node - // - ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2); + // + // Close the last node + // + ShellInfoObject.NewEfiShellProtocol->CloseFile (Handle2); - // - // If there's been an error, stop - // - if (EFI_ERROR (Status)) { - break; - } - } // for loop + // + // If there's been an error, stop + // + if (EFI_ERROR (Status)) { + break; + } + } // for loop + } } } SHELL_FREE_NON_NULL(AlignedNode); @@ -1473,18 +1531,18 @@ EfiShellExecute( DevPath = AppendDevicePath (ShellInfoObject.ImageDevPath, ShellInfoObject.FileDevPath); DEBUG_CODE_BEGIN(); - Temp = gDevPathToText->ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE); + Temp = ConvertDevicePathToText(ShellInfoObject.FileDevPath, TRUE, TRUE); FreePool(Temp); - Temp = gDevPathToText->ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE); + Temp = ConvertDevicePathToText(ShellInfoObject.ImageDevPath, TRUE, TRUE); FreePool(Temp); - Temp = gDevPathToText->ConvertDevicePathToText(DevPath, TRUE, TRUE); + Temp = ConvertDevicePathToText(DevPath, TRUE, TRUE); FreePool(Temp); DEBUG_CODE_END(); Temp = NULL; Size = 0; ASSERT((Temp == NULL && Size == 0) || (Temp != NULL)); - StrnCatGrow(&Temp, &Size, L"Shell.efi ", 0); + StrnCatGrow(&Temp, &Size, L"Shell.efi -_exit ", 0); StrnCatGrow(&Temp, &Size, CommandLine, 0); Status = InternalShellExecuteDevicePath( @@ -1624,14 +1682,14 @@ InternalDuplicateShellFileInfo( { EFI_SHELL_FILE_INFO *NewNode; - NewNode = AllocatePool(sizeof(EFI_SHELL_FILE_INFO)); + NewNode = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); if (NewNode == NULL) { return (NULL); } NewNode->FullName = AllocateZeroPool(StrSize(Node->FullName)); NewNode->FileName = AllocateZeroPool(StrSize(Node->FileName)); - NewNode->Info = AllocatePool((UINTN)Node->Info->Size); + NewNode->Info = AllocateZeroPool((UINTN)Node->Info->Size); if ( NewNode->FullName == NULL || NewNode->FileName == NULL || NewNode->Info == NULL @@ -1686,7 +1744,7 @@ CreateAndPopulateShellFileInfo( if (ShellFileListItem == NULL) { return (NULL); } - if (Info != NULL) { + if (Info != NULL && Info->Size != 0) { ShellFileListItem->Info = AllocateZeroPool((UINTN)Info->Size); if (ShellFileListItem->Info == NULL) { FreePool(ShellFileListItem); @@ -1777,6 +1835,9 @@ EfiShellFindFilesInDir( TempString = NULL; Size = 0; TempString = StrnCatGrow(&TempString, &Size, ShellFileHandleGetPath(FileDirHandle), 0); + if (TempString == NULL) { + return (EFI_OUT_OF_RESOURCES); + } TempSpot = StrStr(TempString, L";"); if (TempSpot != NULL) { @@ -1784,6 +1845,9 @@ EfiShellFindFilesInDir( } TempString = StrnCatGrow(&TempString, &Size, BasePath, 0); + if (TempString == NULL) { + return (EFI_OUT_OF_RESOURCES); + } BasePath = TempString; } @@ -1834,8 +1898,8 @@ EfiShellFindFilesInDir( /** Updates a file name to be preceeded by the mapped drive name - @param[in] BasePath the Mapped drive name to prepend - @param[in,out] Path pointer to pointer to the file name to update. + @param[in] BasePath the Mapped drive name to prepend + @param[in, out] Path pointer to pointer to the file name to update. @retval EFI_SUCCESS @retval EFI_OUT_OF_RESOURCES @@ -1890,12 +1954,12 @@ UpdateFileName( Upon a EFI_SUCCESS return fromt he function any the caller is responsible to call FreeFileList with FileList. - @param[in] FilePattern The FilePattern to check against. - @param[in] UnicodeCollation The pointer to EFI_UNICODE_COLLATION_PROTOCOL structure - @param[in] FileHandle The FileHandle to start with - @param[in,out] FileList pointer to pointer to list of found files. - @param[in] ParentNode The node for the parent. Same file as identified by HANDLE. - @param[in] MapName The file system name this file is on. + @param[in] FilePattern The FilePattern to check against. + @param[in] UnicodeCollation The pointer to EFI_UNICODE_COLLATION_PROTOCOL structure + @param[in] FileHandle The FileHandle to start with + @param[in, out] FileList pointer to pointer to list of found files. + @param[in] ParentNode The node for the parent. Same file as identified by HANDLE. + @param[in] MapName The file system name this file is on. @retval EFI_SUCCESS all files were found and the FileList contains a list. @retval EFI_NOT_FOUND no files were found @@ -1958,7 +2022,7 @@ ShellSearchHandle( } else { NewShellNode->Handle = NULL; if (*FileList == NULL) { - *FileList = AllocatePool(sizeof(EFI_SHELL_FILE_INFO)); + *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); InitializeListHead(&((*FileList)->Link)); } @@ -1997,7 +2061,7 @@ ShellSearchHandle( ShellInfoNode->FullName = NewFullName; } } - if (Directory && !EFI_ERROR(Status)){ + if (Directory && !EFI_ERROR(Status) && ShellInfoNode->FullName != NULL && ShellInfoNode->FileName != NULL){ // // should be a directory // @@ -2011,7 +2075,6 @@ ShellSearchHandle( // // // - ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { break; } @@ -2039,7 +2102,7 @@ ShellSearchHandle( Status = EFI_OUT_OF_RESOURCES; } if (*FileList == NULL) { - *FileList = AllocatePool(sizeof(EFI_SHELL_FILE_INFO)); + *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO)); InitializeListHead(&((*FileList)->Link)); } @@ -2116,21 +2179,22 @@ EfiShellFindFiles( RootDevicePath = NULL; RootFileHandle = NULL; MapName = NULL; - PatternCopy = AllocatePool(StrSize(FilePattern)); + PatternCopy = AllocateZeroPool(StrSize(FilePattern)); if (PatternCopy == NULL) { return (EFI_OUT_OF_RESOURCES); } StrCpy(PatternCopy, FilePattern); - PatternCopy = CleanPath(PatternCopy); + PatternCopy = PathCleanUpDirectories(PatternCopy); Count = StrStr(PatternCopy, L":") - PatternCopy; Count += 2; ASSERT(MapName == NULL); MapName = StrnCatGrow(&MapName, NULL, PatternCopy, Count); - - if (!EFI_ERROR(Status)) { + if (MapName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { RootDevicePath = EfiShellGetDevicePathFromFilePath(PatternCopy); if (RootDevicePath == NULL) { Status = EFI_INVALID_PARAMETER; @@ -2181,17 +2245,19 @@ EfiShellOpenFileList( CHAR16 *Path2; UINTN Path2Size; CONST CHAR16 *CurDir; + BOOLEAN Found; - ShellCommandCleanPath(Path); + PathCleanUpDirectories(Path); Path2Size = 0; Path2 = NULL; - ASSERT(FileList != NULL); - ASSERT(*FileList != NULL); + if (FileList == NULL || *FileList == NULL) { + return (EFI_INVALID_PARAMETER); + } if (*Path == L'.' && *(Path+1) == L'\\') { - Path++; + Path+=2; } // @@ -2203,6 +2269,7 @@ EfiShellOpenFileList( StrnCatGrow(&Path2, &Path2Size, CurDir, 0); if (*Path == L'\\') { Path++; + while (PathRemoveLastItem(Path2)) ; } ASSERT((Path2 == NULL && Path2Size == 0) || (Path2 != NULL)); StrnCatGrow(&Path2, &Path2Size, Path, 0); @@ -2211,7 +2278,7 @@ EfiShellOpenFileList( StrnCatGrow(&Path2, NULL, Path, 0); } - CleanPath (Path2); + PathCleanUpDirectories (Path2); // // do the search @@ -2224,6 +2291,7 @@ EfiShellOpenFileList( return (Status); } + Found = FALSE; // // We had no errors so open all the files (that are not already opened...) // @@ -2233,9 +2301,13 @@ EfiShellOpenFileList( ){ if (ShellFileListItem->Status == 0 && ShellFileListItem->Handle == NULL) { ShellFileListItem->Status = EfiShellOpenFileByName (ShellFileListItem->FullName, &ShellFileListItem->Handle, OpenMode); + Found = TRUE; } } + if (!Found) { + return (EFI_NOT_FOUND); + } return(EFI_SUCCESS); } @@ -2559,7 +2631,7 @@ EfiShellSetCurDir( DirectoryName = StrnCatGrow(&DirectoryName, NULL, Dir, 0); ASSERT(DirectoryName != NULL); - CleanPath(DirectoryName); + PathCleanUpDirectories(DirectoryName); if (FileSystem == NULL) { // @@ -2641,7 +2713,7 @@ EfiShellSetCurDir( MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0); ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL)); MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, DirectoryName, 0); - if (MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] != L'\\') { + if (MapListItem->CurrentDirectoryPath != NULL && MapListItem->CurrentDirectoryPath[StrLen(MapListItem->CurrentDirectoryPath)-1] != L'\\') { ASSERT((MapListItem->CurrentDirectoryPath == NULL && Size == 0) || (MapListItem->CurrentDirectoryPath != NULL)); MapListItem->CurrentDirectoryPath = StrnCatGrow(&MapListItem->CurrentDirectoryPath, &Size, L"\\", 0); } @@ -2766,7 +2838,6 @@ InternalEfiShellGetListAlias( UINTN NameSize; CHAR16 *RetVal; UINTN RetSize; - CHAR16 *Alias; Status = gRT->QueryVariableInfo(EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS, &MaxStorSize, &RemStorSize, &MaxVarSize); ASSERT_EFI_ERROR(Status); @@ -2792,7 +2863,6 @@ InternalEfiShellGetListAlias( break; } if (CompareGuid(&Guid, &gShellAliasGuid)){ - Alias = GetVariable(VariableName, &gShellAliasGuid); ASSERT((RetVal == NULL && RetSize == 0) || (RetVal != NULL)); RetVal = StrnCatGrow(&RetVal, &RetSize, VariableName, 0); RetVal = StrnCatGrow(&RetVal, &RetSize, L";", 0); @@ -3006,7 +3076,7 @@ EFI_SHELL_PROTOCOL mShellProtocol = { This must be removed via calling CleanUpShellProtocol(). - @param[in,out] NewShell The pointer to the pointer to the structure + @param[in, out] NewShell The pointer to the pointer to the structure to install. @retval EFI_SUCCESS The operation was successful. @@ -3135,7 +3205,7 @@ CreatePopulateInstallShellProtocol ( Free all memory and restore the system to the state it was in before calling CreatePopulateInstallShellProtocol. - @param[in,out] NewShell The pointer to the new shell protocol structure. + @param[in, out] NewShell The pointer to the new shell protocol structure. @retval EFI_SUCCESS The operation was successful. **/ @@ -3183,9 +3253,16 @@ CleanUpShellProtocol ( NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle1); - Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle2); - + if (!EFI_ERROR (Status)) { + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle1); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle2); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle3); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlCNotifyHandle4); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlSNotifyHandle1); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlSNotifyHandle2); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlSNotifyHandle3); + Status = SimpleEx->UnregisterKeyNotify(SimpleEx, ShellInfoObject.CtrlSNotifyHandle4); + } return (Status); } @@ -3202,10 +3279,27 @@ NotificationFunction( IN EFI_KEY_DATA *KeyData ) { - if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) { - return (EFI_UNSUPPORTED); + EFI_INPUT_KEY Key; + if ( ((KeyData->Key.UnicodeChar == L'c') && + (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED))) || + (KeyData->Key.UnicodeChar == 3) + ){ + if (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak == NULL) { + return (EFI_UNSUPPORTED); + } + return (gBS->SignalEvent(ShellInfoObject.NewEfiShellProtocol->ExecutionBreak)); + } else if ((KeyData->Key.UnicodeChar == L's') && + (KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED) || KeyData->KeyState.KeyShiftState == (EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED)) + ){ + ShellInfoObject.HaltOutput = TRUE; + + // + // Make sure that there are no pending keystrokes to pervent the pause. + // + gST->ConIn->Reset(gST->ConIn, FALSE); + while (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key)==EFI_SUCCESS); } - return (gBS->SignalEvent(ShellInfoObject.NewEfiShellProtocol->ExecutionBreak)); + return (EFI_SUCCESS); } /**