diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c new file mode 100644 index 00000000..8c4b26e2 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c @@ -0,0 +1,221 @@ +/** @file + LZMA Decompress interfaces + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "LzmaDecompressLibInternal.h" +#include "Sdk/C/7zTypes.h" +#include "Sdk/C/7zVersion.h" +#include "Sdk/C/LzmaDec.h" + +#define SCRATCH_BUFFER_REQUEST_SIZE SIZE_64KB + +typedef struct +{ + ISzAlloc Functions; + VOID *Buffer; + UINTN BufferSize; +} ISzAllocWithData; + +/** + Allocation routine used by LZMA decompression. + + @param P Pointer to the ISzAlloc instance + @param Size The size in bytes to be allocated + + @return The allocated pointer address, or NULL on failure +**/ +VOID * +SzAlloc ( + CONST ISzAlloc *P, + size_t Size + ) +{ + VOID *Addr; + ISzAllocWithData *Private; + + Private = (ISzAllocWithData*) P; + + if (Private->BufferSize >= Size) { + Addr = Private->Buffer; + Private->Buffer = (VOID*) ((UINT8*)Addr + Size); + Private->BufferSize -= Size; + return Addr; + } else { + ASSERT (FALSE); + return NULL; + } +} + +/** + Free routine used by LZMA decompression. + + @param P Pointer to the ISzAlloc instance + @param Address The address to be freed +**/ +VOID +SzFree ( + CONST ISzAlloc *P, + VOID *Address + ) +{ + // + // We use the 'scratch buffer' for allocations, so there is no free + // operation required. The scratch buffer will be freed by the caller + // of the decompression code. + // +} + +#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) + +/** + Get the size of the uncompressed buffer by parsing EncodeData header. + + @param EncodedData Pointer to the compressed data. + + @return The size of the uncompressed buffer. +**/ +UINT64 +GetDecodedSizeOfBuf( + UINT8 *EncodedData + ) +{ + UINT64 DecodedSize; + INTN Index; + + /* Parse header */ + DecodedSize = 0; + for (Index = LZMA_PROPS_SIZE + 7; Index >= LZMA_PROPS_SIZE; Index--) + DecodedSize = LShiftU64(DecodedSize, 8) + EncodedData[Index]; + + return DecodedSize; +} + +// +// LZMA functions and data as defined in local LzmaDecompressLibInternal.h +// + +/** + Given a Lzma compressed source buffer, this function retrieves the size of + the uncompressed buffer and the size of the scratch buffer required + to decompress the compressed source buffer. + + Retrieves the size of the uncompressed buffer and the temporary scratch buffer + required to decompress the buffer specified by Source and SourceSize. + The size of the uncompressed buffer is returned in DestinationSize, + the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned. + This function does not have scratch buffer available to perform a thorough + checking of the validity of the source data. It just retrieves the "Original Size" + field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize. + And ScratchSize is specific to the decompression implementation. + + If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT(). + + @param Source The source buffer containing the compressed data. + @param SourceSize The size, in bytes, of the source buffer. + @param DestinationSize A pointer to the size, in bytes, of the uncompressed buffer + that will be generated when the compressed buffer specified + by Source and SourceSize is decompressed. + @param ScratchSize A pointer to the size, in bytes, of the scratch buffer that + is required to decompress the compressed buffer specified + by Source and SourceSize. + + @retval RETURN_SUCCESS The size of the uncompressed data was returned + in DestinationSize and the size of the scratch + buffer was returned in ScratchSize. + + @retval RETURN_UNSUPPORTED DestinationSize cannot be output because the + uncompressed buffer size (in bytes) does not fit + in a UINT32. Output parameters have not been + modified. +**/ +RETURN_STATUS +EFIAPI +LzmaUefiDecompressGetInfo ( + IN CONST VOID *Source, + IN UINT32 SourceSize, + OUT UINT32 *DestinationSize, + OUT UINT32 *ScratchSize + ) +{ + UInt64 DecodedSize; + + ASSERT(SourceSize >= LZMA_HEADER_SIZE); + + DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); + if (DecodedSize > MAX_UINT32) { + return RETURN_UNSUPPORTED; + } + + *DestinationSize = (UINT32)DecodedSize; + *ScratchSize = SCRATCH_BUFFER_REQUEST_SIZE; + return RETURN_SUCCESS; +} + +/** + Decompresses a Lzma compressed source buffer. + + Extracts decompressed data to its original form. + If the compressed source data specified by Source is successfully decompressed + into Destination, then RETURN_SUCCESS is returned. If the compressed source data + specified by Source is not in a valid compressed data format, + then RETURN_INVALID_PARAMETER is returned. + + @param Source The source buffer containing the compressed data. + @param SourceSize The size of source buffer. + @param Destination The destination buffer to store the decompressed data + @param Scratch A temporary scratch buffer that is used to perform the decompression. + This is an optional parameter that may be NULL if the + required scratch buffer size is 0. + + @retval RETURN_SUCCESS Decompression completed successfully, and + the uncompressed buffer is returned in Destination. + @retval RETURN_INVALID_PARAMETER + The source buffer specified by Source is corrupted + (not in a valid compressed format). +**/ +RETURN_STATUS +EFIAPI +LzmaUefiDecompress ( + IN CONST VOID *Source, + IN UINTN SourceSize, + IN OUT VOID *Destination, + IN OUT VOID *Scratch + ) +{ + SRes LzmaResult; + ELzmaStatus Status; + SizeT DecodedBufSize; + SizeT EncodedDataSize; + ISzAllocWithData AllocFuncs; + + AllocFuncs.Functions.Alloc = SzAlloc; + AllocFuncs.Functions.Free = SzFree; + AllocFuncs.Buffer = Scratch; + AllocFuncs.BufferSize = SCRATCH_BUFFER_REQUEST_SIZE; + + DecodedBufSize = (SizeT)GetDecodedSizeOfBuf((UINT8*)Source); + EncodedDataSize = (SizeT) (SourceSize - LZMA_HEADER_SIZE); + + LzmaResult = LzmaDecode( + Destination, + &DecodedBufSize, + (Byte*)((UINT8*)Source + LZMA_HEADER_SIZE), + &EncodedDataSize, + Source, + LZMA_PROPS_SIZE, + LZMA_FINISH_END, + &Status, + &(AllocFuncs.Functions) + ); + + if (LzmaResult == SZ_OK) { + return RETURN_SUCCESS; + } else { + return RETURN_INVALID_PARAMETER; + } +} + |