From: andrewfish Date: Thu, 11 Feb 2010 19:57:56 +0000 (+0000) Subject: Add support for Seeking on FV, and update the device syntax to support specifying... X-Git-Tag: edk2-stable201903~16345 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=875c883ef36919045a56f2f7afff84fc8a115c59 Add support for Seeking on FV, and update the device syntax to support specifying which section of the FV file you want to operate on, previously the only option was to operate on the Raw file. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9991 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c index a68fbf0998..d3d9596413 100644 --- a/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c +++ b/EmbeddedPkg/Library/EfiFileLib/EfiFileLib.c @@ -560,14 +560,13 @@ EblFvFileDevicePath ( &File->Size ); if (!EFI_ERROR (GetNextFileStatus)) { - Section = NULL; - // Compare GUID first Status = CompareGuidToString (&File->FvNameGuid, FileName); if (!EFI_ERROR(Status)) { break; } + Section = NULL; Status = File->Fv->ReadSection ( File->Fv, &File->FvNameGuid, @@ -592,6 +591,24 @@ EblFvFileDevicePath ( return GetNextFileStatus; } + if (OpenMode != EFI_SECTION_ALL) { + // Calculate the size of the section we are targeting + Section = NULL; + File->Size = 0; + Status = File->Fv->ReadSection ( + File->Fv, + &File->FvNameGuid, + OpenMode, + 0, + &Section, + &File->Size, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + File->MaxPosition = File->Size; EfiInitializeFwVolDevicepathNode (&DevicePathNode, &File->FvNameGuid); File->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&DevicePathNode); @@ -643,12 +660,13 @@ EfiOpen ( UINTN Size; EFI_IP_ADDRESS Ip; CHAR8 *CwdPlusPathName; + UINTN Index; + EFI_SECTION_TYPE ModifiedSectionType; EblUpdateDeviceLists (); File = &FileData; ZeroMem (File, sizeof (EFI_OPEN_FILE)); - File->FvSectionType = SectionType; StrLen = AsciiStrSize (PathName); if (StrLen <= 1) { @@ -749,7 +767,19 @@ EfiOpen ( // Skip leading / as its not really needed for the FV since no directories are supported FileStart++; } - Status = EblFvFileDevicePath (File, &PathName[FileStart], OpenMode); + + // Check for 2nd : + ModifiedSectionType = SectionType; + for (Index = FileStart; PathName[Index] != '\0'; Index++) { + if (PathName[Index] == ':') { + // Support fv0:\DxeCore:0x10 + // This means open the PE32 Section of the file + ModifiedSectionType = AsciiStrHexToUintn (&PathName[Index + 1]); + PathName[Index] = '\0'; + } + } + File->FvSectionType = ModifiedSectionType; + Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType); } } else if ((*PathName == 'A') || (*PathName == 'a')) { // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE @@ -884,14 +914,14 @@ EfiCopyFile ( UINTN Offset; UINTN Chunk = FILE_COPY_CHUNK; - Source = EfiOpen(SourceFile, EFI_FILE_MODE_READ, 0); + Source = EfiOpen (SourceFile, EFI_FILE_MODE_READ, 0); if (Source == NULL) { AsciiPrint("Source file open error.\n"); Status = EFI_NOT_FOUND; goto Exit; } - Destination = EfiOpen(DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); + Destination = EfiOpen (DestinationFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); if (Destination == NULL) { AsciiPrint("Destination file open error.\n"); Status = EFI_NOT_FOUND; @@ -1050,7 +1080,8 @@ EfiClose ( } if ((File->Type == EfiOpenLoadFile) || - ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE))) { + ((File->Type == EfiOpenTftp) && (File->IsBufferValid == TRUE)) || + ((File->Type == EfiOpenFirmwareVolume) && (File->IsBufferValid == TRUE))) { EblFreePool(File->Buffer); } @@ -1167,14 +1198,9 @@ EfiSeek ( return EFI_INVALID_PARAMETER; } - if (File->Type == EfiOpenLoadFile || File->Type == EfiOpenFirmwareVolume) { - if (!CompareGuid (&File->FvNameGuid, &gZeroGuid)) { - if ((SeekType != EfiSeekStart) && (Offset != 0)) { - // LoadFile and FV do not support Seek - // You can seek on a raw FV device - return EFI_UNSUPPORTED; - } - } + if (File->Type == EfiOpenLoadFile) { + // LoadFile does not support Seek + return EFI_UNSUPPORTED; } CurrentPosition = File->CurrentPosition; @@ -1299,12 +1325,6 @@ EfiRead ( } switch (File->Type) { - case EfiOpenMemoryBuffer: - CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize); - File->CurrentPosition += *BufferSize; - Status = EFI_SUCCESS; - break; - case EfiOpenLoadFile: // Figure out the File->Size EfiTell (File, NULL); @@ -1319,29 +1339,45 @@ EfiRead ( File->CurrentPosition += *BufferSize; Status = EFI_SUCCESS; } else { - if (File->FvSectionType == EFI_SECTION_ALL) { - Status = File->Fv->ReadFile ( - File->Fv, - &File->FvNameGuid, - &Buffer, - BufferSize, - &File->FvType, - &File->FvAttributes, - &AuthenticationStatus - ); - } else { - Status = File->Fv->ReadSection ( - File->Fv, - &File->FvNameGuid, - File->FvSectionType, - 0, - &Buffer, - BufferSize, - &AuthenticationStatus - ); + if (File->Buffer == NULL) { + if (File->FvSectionType == EFI_SECTION_ALL) { + Status = File->Fv->ReadFile ( + File->Fv, + &File->FvNameGuid, + (VOID **)&File->Buffer, + &File->Size, + &File->FvType, + &File->FvAttributes, + &AuthenticationStatus + ); + } else { + Status = File->Fv->ReadSection ( + File->Fv, + &File->FvNameGuid, + File->FvSectionType, + 0, + (VOID **)&File->Buffer, + &File->Size, + &AuthenticationStatus + ); + } + if (EFI_ERROR (Status)) { + return Status; + } + File->IsBufferValid = TRUE; } + // Operate on the cached buffer so Seek will work + CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize); + File->CurrentPosition += *BufferSize; + Status = EFI_SUCCESS; } break; + + case EfiOpenMemoryBuffer: + CopyMem (Buffer, File->Buffer + File->CurrentPosition, *BufferSize); + File->CurrentPosition += *BufferSize; + Status = EFI_SUCCESS; + break; case EfiOpenFileSystem: Status = File->FsFileHandle->Read (File->FsFileHandle, BufferSize, Buffer);