1306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten/** @file
2182b1d16236001427c2929284eaba558a556c495lgao  LZMA Decompress GUIDed Section Extraction Library.
3182b1d16236001427c2929284eaba558a556c495lgao  It wraps Lzma decompress interfaces to GUIDed Section Extraction interfaces
4182b1d16236001427c2929284eaba558a556c495lgao  and registers them into GUIDed handler table.
5306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
7180a5a35cb49699bd249dee19e41cee34c856a58hhtian  This program and the accompanying materials
8306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  are licensed and made available under the terms and conditions of the BSD License
9306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  which accompanies this distribution.  The full text of the license may be found at
10306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  http://opensource.org/licenses/bsd-license.php
11306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
12306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
15306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten**/
16306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
17182b1d16236001427c2929284eaba558a556c495lgao#include "LzmaDecompressLibInternal.h"
18306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
19306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten/**
20182b1d16236001427c2929284eaba558a556c495lgao  Examines a GUIDed section and returns the size of the decoded buffer and the
21182b1d16236001427c2929284eaba558a556c495lgao  size of an scratch buffer required to actually decode the data in a GUIDed section.
22182b1d16236001427c2929284eaba558a556c495lgao
23182b1d16236001427c2929284eaba558a556c495lgao  Examines a GUIDed section specified by InputSection.
24182b1d16236001427c2929284eaba558a556c495lgao  If GUID for InputSection does not match the GUID that this handler supports,
25182b1d16236001427c2929284eaba558a556c495lgao  then RETURN_UNSUPPORTED is returned.
26182b1d16236001427c2929284eaba558a556c495lgao  If the required information can not be retrieved from InputSection,
27182b1d16236001427c2929284eaba558a556c495lgao  then RETURN_INVALID_PARAMETER is returned.
28182b1d16236001427c2929284eaba558a556c495lgao  If the GUID of InputSection does match the GUID that this handler supports,
29182b1d16236001427c2929284eaba558a556c495lgao  then the size required to hold the decoded buffer is returned in OututBufferSize,
30182b1d16236001427c2929284eaba558a556c495lgao  the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field
31182b1d16236001427c2929284eaba558a556c495lgao  from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.
32182b1d16236001427c2929284eaba558a556c495lgao
33182b1d16236001427c2929284eaba558a556c495lgao  If InputSection is NULL, then ASSERT().
34182b1d16236001427c2929284eaba558a556c495lgao  If OutputBufferSize is NULL, then ASSERT().
35182b1d16236001427c2929284eaba558a556c495lgao  If ScratchBufferSize is NULL, then ASSERT().
36182b1d16236001427c2929284eaba558a556c495lgao  If SectionAttribute is NULL, then ASSERT().
37182b1d16236001427c2929284eaba558a556c495lgao
38182b1d16236001427c2929284eaba558a556c495lgao
39182b1d16236001427c2929284eaba558a556c495lgao  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
40182b1d16236001427c2929284eaba558a556c495lgao  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required
41182b1d16236001427c2929284eaba558a556c495lgao                                 if the buffer specified by InputSection were decoded.
42182b1d16236001427c2929284eaba558a556c495lgao  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space
43182b1d16236001427c2929284eaba558a556c495lgao                                 if the buffer specified by InputSection were decoded.
44182b1d16236001427c2929284eaba558a556c495lgao  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes
45182b1d16236001427c2929284eaba558a556c495lgao                                 field of EFI_GUID_DEFINED_SECTION in the PI Specification.
46182b1d16236001427c2929284eaba558a556c495lgao
47182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_SUCCESS            The information about InputSection was returned.
48182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
49182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.
50306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
51306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten**/
52306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenRETURN_STATUS
53306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenEFIAPI
54306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenLzmaGuidedSectionGetInfo (
55306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  IN  CONST VOID  *InputSection,
56306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  OUT UINT32      *OutputBufferSize,
57306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  OUT UINT32      *ScratchBufferSize,
58306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  OUT UINT16      *SectionAttribute
59306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  )
60306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten{
61182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (InputSection != NULL);
62182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (OutputBufferSize != NULL);
63182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (ScratchBufferSize != NULL);
64182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (SectionAttribute != NULL);
65182b1d16236001427c2929284eaba558a556c495lgao
6630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  if (IS_SECTION2 (InputSection)) {
6730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
6830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gLzmaCustomDecompressGuid,
6930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
7030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
7130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
7230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
7330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *SectionAttribute = ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->Attributes;
7430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
7530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return LzmaUefiDecompressGetInfo (
7630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
7730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
7830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             OutputBufferSize,
7930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBufferSize
8030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             );
8130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  } else {
8230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
8330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gLzmaCustomDecompressGuid,
84182b1d16236001427c2929284eaba558a556c495lgao        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
8530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
8630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
87306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
8830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *SectionAttribute = ((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes;
89306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
9030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return LzmaUefiDecompressGetInfo (
9130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
9230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
9330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             OutputBufferSize,
9430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBufferSize
9530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             );
9630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  }
97306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten}
98306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
99306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten/**
100182b1d16236001427c2929284eaba558a556c495lgao  Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.
101182b1d16236001427c2929284eaba558a556c495lgao
102182b1d16236001427c2929284eaba558a556c495lgao  Decodes the GUIDed section specified by InputSection.
103182b1d16236001427c2929284eaba558a556c495lgao  If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.
104182b1d16236001427c2929284eaba558a556c495lgao  If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.
105182b1d16236001427c2929284eaba558a556c495lgao  If the GUID of InputSection does match the GUID that this handler supports, then InputSection
106182b1d16236001427c2929284eaba558a556c495lgao  is decoded into the buffer specified by OutputBuffer and the authentication status of this
107182b1d16236001427c2929284eaba558a556c495lgao  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the
108182b1d16236001427c2929284eaba558a556c495lgao  data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,
109182b1d16236001427c2929284eaba558a556c495lgao  the decoded data will be placed in caller allocated buffer specified by OutputBuffer.
110182b1d16236001427c2929284eaba558a556c495lgao
111182b1d16236001427c2929284eaba558a556c495lgao  If InputSection is NULL, then ASSERT().
112182b1d16236001427c2929284eaba558a556c495lgao  If OutputBuffer is NULL, then ASSERT().
113182b1d16236001427c2929284eaba558a556c495lgao  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
114182b1d16236001427c2929284eaba558a556c495lgao  If AuthenticationStatus is NULL, then ASSERT().
115182b1d16236001427c2929284eaba558a556c495lgao
116182b1d16236001427c2929284eaba558a556c495lgao
117182b1d16236001427c2929284eaba558a556c495lgao  @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.
118182b1d16236001427c2929284eaba558a556c495lgao  @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation.
119182b1d16236001427c2929284eaba558a556c495lgao  @param[out] ScratchBuffer A caller allocated buffer that may be required by this function
120182b1d16236001427c2929284eaba558a556c495lgao                            as a scratch buffer to perform the decode operation.
121182b1d16236001427c2929284eaba558a556c495lgao  @param[out] AuthenticationStatus
122182b1d16236001427c2929284eaba558a556c495lgao                            A pointer to the authentication status of the decoded output buffer.
123182b1d16236001427c2929284eaba558a556c495lgao                            See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI
124182b1d16236001427c2929284eaba558a556c495lgao                            section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must
125182b1d16236001427c2929284eaba558a556c495lgao                            never be set by this handler.
126182b1d16236001427c2929284eaba558a556c495lgao
127182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.
128182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.
129182b1d16236001427c2929284eaba558a556c495lgao  @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.
130306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
131306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten**/
132306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenRETURN_STATUS
133306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenEFIAPI
134306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenLzmaGuidedSectionExtraction (
135306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  IN CONST  VOID    *InputSection,
136306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  OUT       VOID    **OutputBuffer,
137182b1d16236001427c2929284eaba558a556c495lgao  OUT       VOID    *ScratchBuffer,        OPTIONAL
138306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  OUT       UINT32  *AuthenticationStatus
139306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  )
140306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten{
141182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (OutputBuffer != NULL);
142182b1d16236001427c2929284eaba558a556c495lgao  ASSERT (InputSection != NULL);
143306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
14430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  if (IS_SECTION2 (InputSection)) {
14530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
14630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gLzmaCustomDecompressGuid,
14730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid))) {
14830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
14930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
15030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
15130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
15230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Authentication is set to Zero, which may be ignored.
15330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
15430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *AuthenticationStatus = 0;
15530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
15630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return LzmaUefiDecompress (
15730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
15830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION2_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION2 *) InputSection)->DataOffset,
15930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             *OutputBuffer,
16030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBuffer
16130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             );
16230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  } else {
16330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    if (!CompareGuid (
16430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng        &gLzmaCustomDecompressGuid,
165182b1d16236001427c2929284eaba558a556c495lgao        &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
16630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng      return RETURN_INVALID_PARAMETER;
16730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    }
16830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
16930f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
17030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    // Authentication is set to Zero, which may be ignored.
17130f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    //
17230f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    *AuthenticationStatus = 0;
17330f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng
17430f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng    return LzmaUefiDecompress (
17530f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             (UINT8 *) InputSection + ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
17630f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             SECTION_SIZE (InputSection) - ((EFI_GUID_DEFINED_SECTION *) InputSection)->DataOffset,
17730f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             *OutputBuffer,
17830f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng             ScratchBuffer
179306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten    );
18030f001ca5f08974c8d5a5483f8b8e1a4f46a1025lzeng  }
181306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten}
182306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
183306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
184306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten/**
185182b1d16236001427c2929284eaba558a556c495lgao  Register LzmaDecompress and LzmaDecompressGetInfo handlers with LzmaCustomerDecompressGuid.
186306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
187306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  @retval  RETURN_SUCCESS            Register successfully.
188306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to store this handler.
189306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten**/
190306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenEFI_STATUS
191306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenEFIAPI
192306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljustenLzmaDecompressLibConstructor (
193306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  )
194306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten{
195306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten  return ExtractGuidedSectionRegisterHandlers (
196306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten          &gLzmaCustomDecompressGuid,
197306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten          LzmaGuidedSectionGetInfo,
198306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten          LzmaGuidedSectionExtraction
199306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten          );
200306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten}
201306bf4e22a1139b47357b9e3fd70cfc1c0f05f9cjljusten
202