xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/AvbHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // AvbHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyBuffer.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariant.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
13*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "HandlerCont.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #define Get32(p) GetBe32(p)
18*f6dc9357SAndroid Build Coastguard Worker #define Get64(p) GetBe64(p)
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #define G32(_offs_, dest) dest = Get32(p + (_offs_))
21*f6dc9357SAndroid Build Coastguard Worker #define G64(_offs_, dest) dest = Get64(p + (_offs_))
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker namespace NExt {
28*f6dc9357SAndroid Build Coastguard Worker API_FUNC_IsArc IsArc_Ext_PhySize(const Byte *p, size_t size, UInt64 *phySize);
29*f6dc9357SAndroid Build Coastguard Worker }
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker namespace NAvb {
32*f6dc9357SAndroid Build Coastguard Worker 
AddNameToString(AString & s,const Byte * name,unsigned size,bool strictConvert)33*f6dc9357SAndroid Build Coastguard Worker static void AddNameToString(AString &s, const Byte *name, unsigned size, bool strictConvert)
34*f6dc9357SAndroid Build Coastguard Worker {
35*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < size; i++)
36*f6dc9357SAndroid Build Coastguard Worker   {
37*f6dc9357SAndroid Build Coastguard Worker     Byte c = name[i];
38*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
39*f6dc9357SAndroid Build Coastguard Worker       return;
40*f6dc9357SAndroid Build Coastguard Worker     if (strictConvert && c < 32)
41*f6dc9357SAndroid Build Coastguard Worker       c = '_';
42*f6dc9357SAndroid Build Coastguard Worker     s += (char)c;
43*f6dc9357SAndroid Build Coastguard Worker   }
44*f6dc9357SAndroid Build Coastguard Worker }
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker /* Maximum size of a vbmeta image - 64 KiB. */
47*f6dc9357SAndroid Build Coastguard Worker #define VBMETA_MAX_SIZE (64 * 1024)
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker #define SIGNATURE { 'A', 'V', 'B', 'f', 0, 0, 0, 1 }
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_SignatureSize = 8;
52*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[k_SignatureSize] = SIGNATURE;
53*f6dc9357SAndroid Build Coastguard Worker 
54*f6dc9357SAndroid Build Coastguard Worker // #define AVB_FOOTER_MAGIC "AVBf"
55*f6dc9357SAndroid Build Coastguard Worker // #define AVB_FOOTER_MAGIC_LEN 4
56*f6dc9357SAndroid Build Coastguard Worker /* The current footer version used - keep in sync with avbtool. */
57*f6dc9357SAndroid Build Coastguard Worker #define AVB_FOOTER_VERSION_MAJOR 1
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker /* The struct used as a footer used on partitions, used to find the
60*f6dc9357SAndroid Build Coastguard Worker  * AvbVBMetaImageHeader struct. This struct is always stored at the
61*f6dc9357SAndroid Build Coastguard Worker  * end of a partition.
62*f6dc9357SAndroid Build Coastguard Worker  */
63*f6dc9357SAndroid Build Coastguard Worker // #define AVB_FOOTER_SIZE 64
64*f6dc9357SAndroid Build Coastguard Worker static const unsigned kFooterSize = 64;
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker struct CFooter
67*f6dc9357SAndroid Build Coastguard Worker {
68*f6dc9357SAndroid Build Coastguard Worker   /*   0: Four bytes equal to "AVBf" (AVB_FOOTER_MAGIC). */
69*f6dc9357SAndroid Build Coastguard Worker   // Byte magic[AVB_FOOTER_MAGIC_LEN];
70*f6dc9357SAndroid Build Coastguard Worker   /*   4: The major version of the footer struct. */
71*f6dc9357SAndroid Build Coastguard Worker   UInt32 version_major;
72*f6dc9357SAndroid Build Coastguard Worker   /*   8: The minor version of the footer struct. */
73*f6dc9357SAndroid Build Coastguard Worker   UInt32 version_minor;
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker   /*  12: The original size of the image on the partition. */
76*f6dc9357SAndroid Build Coastguard Worker   UInt64 original_image_size;
77*f6dc9357SAndroid Build Coastguard Worker 
78*f6dc9357SAndroid Build Coastguard Worker   /*  20: The offset of the |AvbVBMetaImageHeader| struct. */
79*f6dc9357SAndroid Build Coastguard Worker   UInt64 vbmeta_offset;
80*f6dc9357SAndroid Build Coastguard Worker 
81*f6dc9357SAndroid Build Coastguard Worker   /*  28: The size of the vbmeta block (header + auth + aux blocks). */
82*f6dc9357SAndroid Build Coastguard Worker   UInt64 vbmeta_size;
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker   /*  36: Padding to ensure struct is size AVB_FOOTER_SIZE bytes. This
85*f6dc9357SAndroid Build Coastguard Worker    * must be set to zeroes.
86*f6dc9357SAndroid Build Coastguard Worker    */
87*f6dc9357SAndroid Build Coastguard Worker   Byte reserved[28];
88*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NAvb::CFooter89*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
90*f6dc9357SAndroid Build Coastguard Worker   {
91*f6dc9357SAndroid Build Coastguard Worker     G32 (4, version_major);
92*f6dc9357SAndroid Build Coastguard Worker     G32 (8, version_minor);
93*f6dc9357SAndroid Build Coastguard Worker     G64 (12, original_image_size);
94*f6dc9357SAndroid Build Coastguard Worker     G64 (20, vbmeta_offset);
95*f6dc9357SAndroid Build Coastguard Worker     G64 (28, vbmeta_size);
96*f6dc9357SAndroid Build Coastguard Worker   }
97*f6dc9357SAndroid Build Coastguard Worker };
98*f6dc9357SAndroid Build Coastguard Worker 
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker /* Size of the vbmeta image header. */
101*f6dc9357SAndroid Build Coastguard Worker #define AVB_VBMETA_IMAGE_HEADER_SIZE 256
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker /* Magic for the vbmeta image header. */
104*f6dc9357SAndroid Build Coastguard Worker // #define AVB_MAGIC "AVB0"
105*f6dc9357SAndroid Build Coastguard Worker // #define AVB_MAGIC_LEN 4
106*f6dc9357SAndroid Build Coastguard Worker /* Maximum size of the release string including the terminating NUL byte. */
107*f6dc9357SAndroid Build Coastguard Worker #define AVB_RELEASE_STRING_SIZE 48
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker struct AvbVBMetaImageHeader
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker   /*   0: Four bytes equal to "AVB0" (AVB_MAGIC). */
112*f6dc9357SAndroid Build Coastguard Worker   // Byte magic[AVB_MAGIC_LEN];
113*f6dc9357SAndroid Build Coastguard Worker 
114*f6dc9357SAndroid Build Coastguard Worker   /*   4: The major version of libavb required for this header. */
115*f6dc9357SAndroid Build Coastguard Worker   UInt32 required_libavb_version_major;
116*f6dc9357SAndroid Build Coastguard Worker   /*   8: The minor version of libavb required for this header. */
117*f6dc9357SAndroid Build Coastguard Worker   UInt32 required_libavb_version_minor;
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker   /*  12: The size of the signature block. */
120*f6dc9357SAndroid Build Coastguard Worker   UInt64 authentication_data_block_size;
121*f6dc9357SAndroid Build Coastguard Worker   /*  20: The size of the auxiliary data block. */
122*f6dc9357SAndroid Build Coastguard Worker   UInt64 auxiliary_data_block_size;
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker   /*  28: The verification algorithm used, see |AvbAlgorithmType| enum. */
125*f6dc9357SAndroid Build Coastguard Worker   UInt32 algorithm_type;
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker   /*  32: Offset into the "Authentication data" block of hash data. */
128*f6dc9357SAndroid Build Coastguard Worker   UInt64 hash_offset;
129*f6dc9357SAndroid Build Coastguard Worker   /*  40: Length of the hash data. */
130*f6dc9357SAndroid Build Coastguard Worker   UInt64 hash_size;
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker   /*  48: Offset into the "Authentication data" block of signature data. */
133*f6dc9357SAndroid Build Coastguard Worker   UInt64 signature_offset;
134*f6dc9357SAndroid Build Coastguard Worker   /*  56: Length of the signature data. */
135*f6dc9357SAndroid Build Coastguard Worker   UInt64 signature_size;
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker   /*  64: Offset into the "Auxiliary data" block of public key data. */
138*f6dc9357SAndroid Build Coastguard Worker   UInt64 public_key_offset;
139*f6dc9357SAndroid Build Coastguard Worker   /*  72: Length of the public key data. */
140*f6dc9357SAndroid Build Coastguard Worker   UInt64 public_key_size;
141*f6dc9357SAndroid Build Coastguard Worker 
142*f6dc9357SAndroid Build Coastguard Worker   /*  80: Offset into the "Auxiliary data" block of public key metadata. */
143*f6dc9357SAndroid Build Coastguard Worker   UInt64 public_key_metadata_offset;
144*f6dc9357SAndroid Build Coastguard Worker   /*  88: Length of the public key metadata. Must be set to zero if there
145*f6dc9357SAndroid Build Coastguard Worker    *  is no public key metadata.
146*f6dc9357SAndroid Build Coastguard Worker    */
147*f6dc9357SAndroid Build Coastguard Worker   UInt64 public_key_metadata_size;
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker   /*  96: Offset into the "Auxiliary data" block of descriptor data. */
150*f6dc9357SAndroid Build Coastguard Worker   UInt64 descriptors_offset;
151*f6dc9357SAndroid Build Coastguard Worker   /* 104: Length of descriptor data. */
152*f6dc9357SAndroid Build Coastguard Worker   UInt64 descriptors_size;
153*f6dc9357SAndroid Build Coastguard Worker 
154*f6dc9357SAndroid Build Coastguard Worker   /* 112: The rollback index which can be used to prevent rollback to
155*f6dc9357SAndroid Build Coastguard Worker    *  older versions.
156*f6dc9357SAndroid Build Coastguard Worker    */
157*f6dc9357SAndroid Build Coastguard Worker   UInt64 rollback_index;
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker   /* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be
160*f6dc9357SAndroid Build Coastguard Worker    * set to zero if the vbmeta image is not a top-level image.
161*f6dc9357SAndroid Build Coastguard Worker    */
162*f6dc9357SAndroid Build Coastguard Worker   UInt32 flags;
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker   /* 124: The location of the rollback index defined in this header.
165*f6dc9357SAndroid Build Coastguard Worker    * Only valid for the main vbmeta. For chained partitions, the rollback
166*f6dc9357SAndroid Build Coastguard Worker    * index location must be specified in the AvbChainPartitionDescriptor
167*f6dc9357SAndroid Build Coastguard Worker    * and this value must be set to 0.
168*f6dc9357SAndroid Build Coastguard Worker    */
169*f6dc9357SAndroid Build Coastguard Worker   UInt32 rollback_index_location;
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker   /* 128: The release string from avbtool, e.g. "avbtool 1.0.0" or
172*f6dc9357SAndroid Build Coastguard Worker    * "avbtool 1.0.0 xyz_board Git-234abde89". Is guaranteed to be NUL
173*f6dc9357SAndroid Build Coastguard Worker    * terminated. Applications must not make assumptions about how this
174*f6dc9357SAndroid Build Coastguard Worker    * string is formatted.
175*f6dc9357SAndroid Build Coastguard Worker    */
176*f6dc9357SAndroid Build Coastguard Worker   Byte release_string[AVB_RELEASE_STRING_SIZE];
177*f6dc9357SAndroid Build Coastguard Worker 
178*f6dc9357SAndroid Build Coastguard Worker   /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
179*f6dc9357SAndroid Build Coastguard Worker    * bytes. This must be set to zeroes.
180*f6dc9357SAndroid Build Coastguard Worker    */
181*f6dc9357SAndroid Build Coastguard Worker   // Byte reserved[80];
182*f6dc9357SAndroid Build Coastguard Worker   bool Parse(const Byte *p);
183*f6dc9357SAndroid Build Coastguard Worker };
184*f6dc9357SAndroid Build Coastguard Worker 
Parse(const Byte * p)185*f6dc9357SAndroid Build Coastguard Worker bool AvbVBMetaImageHeader::Parse(const Byte *p)
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker   // Byte magic[AVB_MAGIC_LEN];
188*f6dc9357SAndroid Build Coastguard Worker   if (Get32(p) != 0x41564230) // "AVB0"
189*f6dc9357SAndroid Build Coastguard Worker     return false;
190*f6dc9357SAndroid Build Coastguard Worker   G32 (4, required_libavb_version_major);
191*f6dc9357SAndroid Build Coastguard Worker   if (required_libavb_version_major != AVB_FOOTER_VERSION_MAJOR) // "AVB0"
192*f6dc9357SAndroid Build Coastguard Worker     return false;
193*f6dc9357SAndroid Build Coastguard Worker   G32 (8, required_libavb_version_minor);
194*f6dc9357SAndroid Build Coastguard Worker   G64 (12, authentication_data_block_size);
195*f6dc9357SAndroid Build Coastguard Worker   G64 (20, auxiliary_data_block_size);
196*f6dc9357SAndroid Build Coastguard Worker   G32 (28, algorithm_type);
197*f6dc9357SAndroid Build Coastguard Worker   G64 (32, hash_offset);
198*f6dc9357SAndroid Build Coastguard Worker   G64 (40, hash_size);
199*f6dc9357SAndroid Build Coastguard Worker   G64 (48, signature_offset);
200*f6dc9357SAndroid Build Coastguard Worker   G64 (56, signature_size);
201*f6dc9357SAndroid Build Coastguard Worker   G64 (64, public_key_offset);
202*f6dc9357SAndroid Build Coastguard Worker   G64 (72, public_key_size);
203*f6dc9357SAndroid Build Coastguard Worker   G64 (80, public_key_metadata_offset);
204*f6dc9357SAndroid Build Coastguard Worker   G64 (88, public_key_metadata_size);
205*f6dc9357SAndroid Build Coastguard Worker   G64 (96, descriptors_offset);
206*f6dc9357SAndroid Build Coastguard Worker   G64 (104, descriptors_size);
207*f6dc9357SAndroid Build Coastguard Worker   G64 (112, rollback_index);
208*f6dc9357SAndroid Build Coastguard Worker   G32 (120, flags);
209*f6dc9357SAndroid Build Coastguard Worker   G32 (124, rollback_index_location);
210*f6dc9357SAndroid Build Coastguard Worker   memcpy(release_string, p + 128, AVB_RELEASE_STRING_SIZE);
211*f6dc9357SAndroid Build Coastguard Worker 
212*f6dc9357SAndroid Build Coastguard Worker   /* 176: Padding to ensure struct is size AVB_VBMETA_IMAGE_HEADER_SIZE
213*f6dc9357SAndroid Build Coastguard Worker    * bytes. This must be set to zeroes.
214*f6dc9357SAndroid Build Coastguard Worker    */
215*f6dc9357SAndroid Build Coastguard Worker   // Byte reserved[80];
216*f6dc9357SAndroid Build Coastguard Worker   return true;
217*f6dc9357SAndroid Build Coastguard Worker }
218*f6dc9357SAndroid Build Coastguard Worker 
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_Descriptor_Size = 16;
221*f6dc9357SAndroid Build Coastguard Worker 
222*f6dc9357SAndroid Build Coastguard Worker enum AvbDescriptorTag
223*f6dc9357SAndroid Build Coastguard Worker {
224*f6dc9357SAndroid Build Coastguard Worker   AVB_DESCRIPTOR_TAG_PROPERTY,
225*f6dc9357SAndroid Build Coastguard Worker   AVB_DESCRIPTOR_TAG_HASHTREE,
226*f6dc9357SAndroid Build Coastguard Worker   AVB_DESCRIPTOR_TAG_HASH,
227*f6dc9357SAndroid Build Coastguard Worker   AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
228*f6dc9357SAndroid Build Coastguard Worker   AVB_DESCRIPTOR_TAG_CHAIN_PARTITION
229*f6dc9357SAndroid Build Coastguard Worker };
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker struct AvbDescriptor
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker   UInt64 Tag;
234*f6dc9357SAndroid Build Coastguard Worker   UInt64 Size;
235*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NAvb::AvbDescriptor236*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
237*f6dc9357SAndroid Build Coastguard Worker   {
238*f6dc9357SAndroid Build Coastguard Worker     G64 (0, Tag);
239*f6dc9357SAndroid Build Coastguard Worker     G64 (8, Size);
240*f6dc9357SAndroid Build Coastguard Worker   }
241*f6dc9357SAndroid Build Coastguard Worker };
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker enum AvbHashtreeDescriptorFlags
245*f6dc9357SAndroid Build Coastguard Worker {
246*f6dc9357SAndroid Build Coastguard Worker   AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB = (1 << 0),
247*f6dc9357SAndroid Build Coastguard Worker   AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE = (1 << 1)
248*f6dc9357SAndroid Build Coastguard Worker };
249*f6dc9357SAndroid Build Coastguard Worker 
250*f6dc9357SAndroid Build Coastguard Worker /* A descriptor containing information about a dm-verity hashtree.
251*f6dc9357SAndroid Build Coastguard Worker  *
252*f6dc9357SAndroid Build Coastguard Worker  * Hash-trees are used to verify large partitions typically containing
253*f6dc9357SAndroid Build Coastguard Worker  * file systems. See
254*f6dc9357SAndroid Build Coastguard Worker  * https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity for more
255*f6dc9357SAndroid Build Coastguard Worker  * information about dm-verity.
256*f6dc9357SAndroid Build Coastguard Worker  *
257*f6dc9357SAndroid Build Coastguard Worker  * Following this struct are |partition_name_len| bytes of the
258*f6dc9357SAndroid Build Coastguard Worker  * partition name (UTF-8 encoded), |salt_len| bytes of salt, and then
259*f6dc9357SAndroid Build Coastguard Worker  * |root_digest_len| bytes of the root digest.
260*f6dc9357SAndroid Build Coastguard Worker  *
261*f6dc9357SAndroid Build Coastguard Worker  * The |reserved| field is for future expansion and must be set to NUL
262*f6dc9357SAndroid Build Coastguard Worker  * bytes.
263*f6dc9357SAndroid Build Coastguard Worker  *
264*f6dc9357SAndroid Build Coastguard Worker  * Changes in v1.1:
265*f6dc9357SAndroid Build Coastguard Worker  *   - flags field is added which supports AVB_HASHTREE_DESCRIPTOR_FLAGS_USE_AB
266*f6dc9357SAndroid Build Coastguard Worker  *   - digest_len may be zero, which indicates the use of a persistent digest
267*f6dc9357SAndroid Build Coastguard Worker  */
268*f6dc9357SAndroid Build Coastguard Worker 
269*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_Hashtree_Size_Min = 164;
270*f6dc9357SAndroid Build Coastguard Worker 
271*f6dc9357SAndroid Build Coastguard Worker struct AvbHashtreeDescriptor
272*f6dc9357SAndroid Build Coastguard Worker {
273*f6dc9357SAndroid Build Coastguard Worker   UInt32 dm_verity_version;
274*f6dc9357SAndroid Build Coastguard Worker   UInt64 image_size;
275*f6dc9357SAndroid Build Coastguard Worker   UInt64 tree_offset;
276*f6dc9357SAndroid Build Coastguard Worker   UInt64 tree_size;
277*f6dc9357SAndroid Build Coastguard Worker   UInt32 data_block_size;
278*f6dc9357SAndroid Build Coastguard Worker   UInt32 hash_block_size;
279*f6dc9357SAndroid Build Coastguard Worker   UInt32 fec_num_roots;
280*f6dc9357SAndroid Build Coastguard Worker   UInt64 fec_offset;
281*f6dc9357SAndroid Build Coastguard Worker   UInt64 fec_size;
282*f6dc9357SAndroid Build Coastguard Worker   Byte hash_algorithm[32];
283*f6dc9357SAndroid Build Coastguard Worker   UInt32 partition_name_len;
284*f6dc9357SAndroid Build Coastguard Worker   UInt32 salt_len;
285*f6dc9357SAndroid Build Coastguard Worker   UInt32 root_digest_len;
286*f6dc9357SAndroid Build Coastguard Worker   UInt32 flags;
287*f6dc9357SAndroid Build Coastguard Worker   Byte reserved[60];
ParseNArchive::NAvb::AvbHashtreeDescriptor288*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
289*f6dc9357SAndroid Build Coastguard Worker   {
290*f6dc9357SAndroid Build Coastguard Worker     G32 (0, dm_verity_version);
291*f6dc9357SAndroid Build Coastguard Worker     G64 (4, image_size);
292*f6dc9357SAndroid Build Coastguard Worker     G64 (12, tree_offset);
293*f6dc9357SAndroid Build Coastguard Worker     G64 (20, tree_size);
294*f6dc9357SAndroid Build Coastguard Worker     G32 (28, data_block_size);
295*f6dc9357SAndroid Build Coastguard Worker     G32 (32, hash_block_size);
296*f6dc9357SAndroid Build Coastguard Worker     G32 (36, fec_num_roots);
297*f6dc9357SAndroid Build Coastguard Worker     G64 (40, fec_offset);
298*f6dc9357SAndroid Build Coastguard Worker     G64 (48, fec_size);
299*f6dc9357SAndroid Build Coastguard Worker     memcpy(hash_algorithm, p + 56, 32);
300*f6dc9357SAndroid Build Coastguard Worker     G32 (88, partition_name_len);
301*f6dc9357SAndroid Build Coastguard Worker     G32 (92, salt_len);
302*f6dc9357SAndroid Build Coastguard Worker     G32 (96, root_digest_len);
303*f6dc9357SAndroid Build Coastguard Worker     G32 (100, flags);
304*f6dc9357SAndroid Build Coastguard Worker   }
305*f6dc9357SAndroid Build Coastguard Worker };
306*f6dc9357SAndroid Build Coastguard Worker 
307*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_PropertyDescriptor_Size_Min = 16;
308*f6dc9357SAndroid Build Coastguard Worker 
309*f6dc9357SAndroid Build Coastguard Worker struct AvbPropertyDescriptor
310*f6dc9357SAndroid Build Coastguard Worker {
311*f6dc9357SAndroid Build Coastguard Worker   UInt64 key_num_bytes;
312*f6dc9357SAndroid Build Coastguard Worker   UInt64 value_num_bytes;
313*f6dc9357SAndroid Build Coastguard Worker 
ParseNArchive::NAvb::AvbPropertyDescriptor314*f6dc9357SAndroid Build Coastguard Worker   void Parse(const Byte *p)
315*f6dc9357SAndroid Build Coastguard Worker   {
316*f6dc9357SAndroid Build Coastguard Worker     G64 (0, key_num_bytes);
317*f6dc9357SAndroid Build Coastguard Worker     G64 (8, value_num_bytes);
318*f6dc9357SAndroid Build Coastguard Worker   }
319*f6dc9357SAndroid Build Coastguard Worker };
320*f6dc9357SAndroid Build Coastguard Worker 
321*f6dc9357SAndroid Build Coastguard Worker Z7_class_CHandler_final: public CHandlerCont
322*f6dc9357SAndroid Build Coastguard Worker {
323*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IInArchive_Cont)
324*f6dc9357SAndroid Build Coastguard Worker 
325*f6dc9357SAndroid Build Coastguard Worker   // UInt64 _startOffset;
326*f6dc9357SAndroid Build Coastguard Worker   UInt64 _phySize;
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker   CFooter Footer;
329*f6dc9357SAndroid Build Coastguard Worker   AString Name;
330*f6dc9357SAndroid Build Coastguard Worker   const char *Ext;
331*f6dc9357SAndroid Build Coastguard Worker 
332*f6dc9357SAndroid Build Coastguard Worker   HRESULT Open2(IInStream *stream);
333*f6dc9357SAndroid Build Coastguard Worker 
334*f6dc9357SAndroid Build Coastguard Worker   virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override
335*f6dc9357SAndroid Build Coastguard Worker   {
336*f6dc9357SAndroid Build Coastguard Worker     if (index != 0)
337*f6dc9357SAndroid Build Coastguard Worker       return NExtract::NOperationResult::kUnavailable;
338*f6dc9357SAndroid Build Coastguard Worker     // pos = _startOffset;
339*f6dc9357SAndroid Build Coastguard Worker     pos = 0;
340*f6dc9357SAndroid Build Coastguard Worker     size = Footer.original_image_size;
341*f6dc9357SAndroid Build Coastguard Worker     return NExtract::NOperationResult::kOK;
342*f6dc9357SAndroid Build Coastguard Worker   }
343*f6dc9357SAndroid Build Coastguard Worker };
344*f6dc9357SAndroid Build Coastguard Worker 
345*f6dc9357SAndroid Build Coastguard Worker 
346*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::Open2(IInStream *stream)
347*f6dc9357SAndroid Build Coastguard Worker {
348*f6dc9357SAndroid Build Coastguard Worker   UInt64 fileSize;
349*f6dc9357SAndroid Build Coastguard Worker   {
350*f6dc9357SAndroid Build Coastguard Worker     Byte buf[kFooterSize];
351*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_GetSize_SeekToEnd(stream, fileSize))
352*f6dc9357SAndroid Build Coastguard Worker     if (fileSize < kFooterSize)
353*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
354*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_SeekSet(stream, fileSize - kFooterSize))
355*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, buf, kFooterSize))
356*f6dc9357SAndroid Build Coastguard Worker     if (memcmp(buf, k_Signature, k_SignatureSize) != 0)
357*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
358*f6dc9357SAndroid Build Coastguard Worker     Footer.Parse(buf);
359*f6dc9357SAndroid Build Coastguard Worker     if (Footer.vbmeta_size > VBMETA_MAX_SIZE ||
360*f6dc9357SAndroid Build Coastguard Worker         Footer.vbmeta_size < AVB_VBMETA_IMAGE_HEADER_SIZE)
361*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
362*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 36; i < kFooterSize; i++)
363*f6dc9357SAndroid Build Coastguard Worker       if (buf[i] != 0)
364*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
365*f6dc9357SAndroid Build Coastguard Worker   }
366*f6dc9357SAndroid Build Coastguard Worker   {
367*f6dc9357SAndroid Build Coastguard Worker     CByteBuffer buf;
368*f6dc9357SAndroid Build Coastguard Worker     buf.Alloc((size_t)Footer.vbmeta_size);
369*f6dc9357SAndroid Build Coastguard Worker     RINOK(InStream_SeekSet(stream, Footer.vbmeta_offset))
370*f6dc9357SAndroid Build Coastguard Worker     RINOK(ReadStream_FALSE(stream, buf, (size_t)Footer.vbmeta_size))
371*f6dc9357SAndroid Build Coastguard Worker 
372*f6dc9357SAndroid Build Coastguard Worker     AvbVBMetaImageHeader meta;
373*f6dc9357SAndroid Build Coastguard Worker     if (!meta.Parse(buf))
374*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
375*f6dc9357SAndroid Build Coastguard Worker 
376*f6dc9357SAndroid Build Coastguard Worker     unsigned offset = (unsigned)AVB_VBMETA_IMAGE_HEADER_SIZE;
377*f6dc9357SAndroid Build Coastguard Worker     unsigned rem = (unsigned)(Footer.vbmeta_size - offset);
378*f6dc9357SAndroid Build Coastguard Worker 
379*f6dc9357SAndroid Build Coastguard Worker     if (meta.authentication_data_block_size != 0)
380*f6dc9357SAndroid Build Coastguard Worker     {
381*f6dc9357SAndroid Build Coastguard Worker       if (rem < meta.authentication_data_block_size)
382*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
383*f6dc9357SAndroid Build Coastguard Worker       const unsigned u = (unsigned)meta.authentication_data_block_size;
384*f6dc9357SAndroid Build Coastguard Worker       offset += u;
385*f6dc9357SAndroid Build Coastguard Worker       rem -= u;
386*f6dc9357SAndroid Build Coastguard Worker     }
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker     if (rem < meta.descriptors_offset ||
389*f6dc9357SAndroid Build Coastguard Worker         rem - meta.descriptors_offset < meta.descriptors_size)
390*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
391*f6dc9357SAndroid Build Coastguard Worker     rem = (unsigned)meta.descriptors_size;
392*f6dc9357SAndroid Build Coastguard Worker     while (rem != 0)
393*f6dc9357SAndroid Build Coastguard Worker     {
394*f6dc9357SAndroid Build Coastguard Worker       if (rem < k_Descriptor_Size)
395*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
396*f6dc9357SAndroid Build Coastguard Worker       AvbDescriptor desc;
397*f6dc9357SAndroid Build Coastguard Worker       desc.Parse(buf + offset);
398*f6dc9357SAndroid Build Coastguard Worker       offset += k_Descriptor_Size;
399*f6dc9357SAndroid Build Coastguard Worker       rem -= k_Descriptor_Size;
400*f6dc9357SAndroid Build Coastguard Worker       if (desc.Size > rem)
401*f6dc9357SAndroid Build Coastguard Worker         return S_FALSE;
402*f6dc9357SAndroid Build Coastguard Worker       const unsigned descSize = (unsigned)desc.Size;
403*f6dc9357SAndroid Build Coastguard Worker       if (desc.Tag == AVB_DESCRIPTOR_TAG_HASHTREE)
404*f6dc9357SAndroid Build Coastguard Worker       {
405*f6dc9357SAndroid Build Coastguard Worker         if (descSize < k_Hashtree_Size_Min)
406*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
407*f6dc9357SAndroid Build Coastguard Worker         AvbHashtreeDescriptor ht;
408*f6dc9357SAndroid Build Coastguard Worker         ht.Parse(buf + offset);
409*f6dc9357SAndroid Build Coastguard Worker         unsigned pos = k_Hashtree_Size_Min;
410*f6dc9357SAndroid Build Coastguard Worker 
411*f6dc9357SAndroid Build Coastguard Worker         if (pos + ht.partition_name_len > descSize)
412*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
413*f6dc9357SAndroid Build Coastguard Worker         Name.Empty(); // UTF-8
414*f6dc9357SAndroid Build Coastguard Worker         AddNameToString(Name, buf + offset + pos, ht.partition_name_len, false);
415*f6dc9357SAndroid Build Coastguard Worker         pos += ht.partition_name_len;
416*f6dc9357SAndroid Build Coastguard Worker 
417*f6dc9357SAndroid Build Coastguard Worker         if (pos + ht.salt_len > descSize)
418*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
419*f6dc9357SAndroid Build Coastguard Worker         CByteBuffer salt;
420*f6dc9357SAndroid Build Coastguard Worker         salt.CopyFrom(buf + offset + pos, ht.salt_len);
421*f6dc9357SAndroid Build Coastguard Worker         pos += ht.salt_len;
422*f6dc9357SAndroid Build Coastguard Worker 
423*f6dc9357SAndroid Build Coastguard Worker         if (pos + ht.root_digest_len > descSize)
424*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
425*f6dc9357SAndroid Build Coastguard Worker         CByteBuffer digest;
426*f6dc9357SAndroid Build Coastguard Worker         digest.CopyFrom(buf + offset + pos, ht.root_digest_len);
427*f6dc9357SAndroid Build Coastguard Worker         pos += ht.root_digest_len;
428*f6dc9357SAndroid Build Coastguard Worker         // what is that digest?
429*f6dc9357SAndroid Build Coastguard Worker       }
430*f6dc9357SAndroid Build Coastguard Worker       else if (desc.Tag == AVB_DESCRIPTOR_TAG_PROPERTY)
431*f6dc9357SAndroid Build Coastguard Worker       {
432*f6dc9357SAndroid Build Coastguard Worker         if (descSize < k_PropertyDescriptor_Size_Min + 2)
433*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
434*f6dc9357SAndroid Build Coastguard Worker         AvbPropertyDescriptor pt;
435*f6dc9357SAndroid Build Coastguard Worker         pt.Parse(buf + offset);
436*f6dc9357SAndroid Build Coastguard Worker         unsigned pos = k_PropertyDescriptor_Size_Min;
437*f6dc9357SAndroid Build Coastguard Worker 
438*f6dc9357SAndroid Build Coastguard Worker         if (pt.key_num_bytes > descSize - pos - 1)
439*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
440*f6dc9357SAndroid Build Coastguard Worker         AString key; // UTF-8
441*f6dc9357SAndroid Build Coastguard Worker         AddNameToString(key, buf + offset + pos, (unsigned)pt.key_num_bytes, false);
442*f6dc9357SAndroid Build Coastguard Worker         pos += (unsigned)pt.key_num_bytes + 1;
443*f6dc9357SAndroid Build Coastguard Worker 
444*f6dc9357SAndroid Build Coastguard Worker         if (descSize < pos)
445*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
446*f6dc9357SAndroid Build Coastguard Worker         if (pt.value_num_bytes > descSize - pos - 1)
447*f6dc9357SAndroid Build Coastguard Worker           return S_FALSE;
448*f6dc9357SAndroid Build Coastguard Worker         AString value; // UTF-8
449*f6dc9357SAndroid Build Coastguard Worker         AddNameToString(value, buf + offset + pos, (unsigned)pt.value_num_bytes, false);
450*f6dc9357SAndroid Build Coastguard Worker         pos += (unsigned)pt.value_num_bytes + 1;
451*f6dc9357SAndroid Build Coastguard Worker       }
452*f6dc9357SAndroid Build Coastguard Worker       offset += descSize;
453*f6dc9357SAndroid Build Coastguard Worker       rem -= descSize;
454*f6dc9357SAndroid Build Coastguard Worker     }
455*f6dc9357SAndroid Build Coastguard Worker 
456*f6dc9357SAndroid Build Coastguard Worker     _phySize = fileSize;
457*f6dc9357SAndroid Build Coastguard Worker 
458*f6dc9357SAndroid Build Coastguard Worker     // _startOffset = 0;
459*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
460*f6dc9357SAndroid Build Coastguard Worker   }
461*f6dc9357SAndroid Build Coastguard Worker }
462*f6dc9357SAndroid Build Coastguard Worker 
463*f6dc9357SAndroid Build Coastguard Worker 
464*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
465*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* maxCheckStartPosition */,
466*f6dc9357SAndroid Build Coastguard Worker     IArchiveOpenCallback * /* openArchiveCallback */))
467*f6dc9357SAndroid Build Coastguard Worker {
468*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
469*f6dc9357SAndroid Build Coastguard Worker   Close();
470*f6dc9357SAndroid Build Coastguard Worker   try
471*f6dc9357SAndroid Build Coastguard Worker   {
472*f6dc9357SAndroid Build Coastguard Worker     if (Open2(stream) != S_OK)
473*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
474*f6dc9357SAndroid Build Coastguard Worker     _stream = stream;
475*f6dc9357SAndroid Build Coastguard Worker 
476*f6dc9357SAndroid Build Coastguard Worker     {
477*f6dc9357SAndroid Build Coastguard Worker       CMyComPtr<ISequentialInStream> parseStream;
478*f6dc9357SAndroid Build Coastguard Worker       if (GetStream(0, &parseStream) == S_OK && parseStream)
479*f6dc9357SAndroid Build Coastguard Worker       {
480*f6dc9357SAndroid Build Coastguard Worker         const size_t kParseSize = 1 << 11;
481*f6dc9357SAndroid Build Coastguard Worker         Byte buf[kParseSize];
482*f6dc9357SAndroid Build Coastguard Worker         if (ReadStream_FAIL(parseStream, buf, kParseSize) == S_OK)
483*f6dc9357SAndroid Build Coastguard Worker         {
484*f6dc9357SAndroid Build Coastguard Worker           UInt64 extSize;
485*f6dc9357SAndroid Build Coastguard Worker           if (NExt::IsArc_Ext_PhySize(buf, kParseSize, &extSize) == k_IsArc_Res_YES)
486*f6dc9357SAndroid Build Coastguard Worker             if (extSize == Footer.original_image_size)
487*f6dc9357SAndroid Build Coastguard Worker               Ext = "ext";
488*f6dc9357SAndroid Build Coastguard Worker         }
489*f6dc9357SAndroid Build Coastguard Worker       }
490*f6dc9357SAndroid Build Coastguard Worker     }
491*f6dc9357SAndroid Build Coastguard Worker   }
492*f6dc9357SAndroid Build Coastguard Worker   catch(...) { return S_FALSE; }
493*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
494*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
495*f6dc9357SAndroid Build Coastguard Worker }
496*f6dc9357SAndroid Build Coastguard Worker 
497*f6dc9357SAndroid Build Coastguard Worker 
498*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
499*f6dc9357SAndroid Build Coastguard Worker {
500*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
501*f6dc9357SAndroid Build Coastguard Worker   // _startOffset = 0;
502*f6dc9357SAndroid Build Coastguard Worker   _phySize = 0;
503*f6dc9357SAndroid Build Coastguard Worker   Ext = NULL;
504*f6dc9357SAndroid Build Coastguard Worker   Name.Empty();
505*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
506*f6dc9357SAndroid Build Coastguard Worker }
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
510*f6dc9357SAndroid Build Coastguard Worker {
511*f6dc9357SAndroid Build Coastguard Worker   kpidName
512*f6dc9357SAndroid Build Coastguard Worker };
513*f6dc9357SAndroid Build Coastguard Worker 
514*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
515*f6dc9357SAndroid Build Coastguard Worker {
516*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
517*f6dc9357SAndroid Build Coastguard Worker   kpidPackSize,
518*f6dc9357SAndroid Build Coastguard Worker };
519*f6dc9357SAndroid Build Coastguard Worker 
520*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
521*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker 
524*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
525*f6dc9357SAndroid Build Coastguard Worker {
526*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
527*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
528*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
529*f6dc9357SAndroid Build Coastguard Worker   {
530*f6dc9357SAndroid Build Coastguard Worker     case kpidMainSubfile: prop = (UInt32)0; break;
531*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize: prop = _phySize; break;
532*f6dc9357SAndroid Build Coastguard Worker     case kpidName:
533*f6dc9357SAndroid Build Coastguard Worker     {
534*f6dc9357SAndroid Build Coastguard Worker       if (!Name.IsEmpty())
535*f6dc9357SAndroid Build Coastguard Worker       {
536*f6dc9357SAndroid Build Coastguard Worker         AString s (Name);
537*f6dc9357SAndroid Build Coastguard Worker         s += ".avb";
538*f6dc9357SAndroid Build Coastguard Worker         prop = s;
539*f6dc9357SAndroid Build Coastguard Worker       }
540*f6dc9357SAndroid Build Coastguard Worker       break;
541*f6dc9357SAndroid Build Coastguard Worker     }
542*f6dc9357SAndroid Build Coastguard Worker   }
543*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
544*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
545*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
546*f6dc9357SAndroid Build Coastguard Worker }
547*f6dc9357SAndroid Build Coastguard Worker 
548*f6dc9357SAndroid Build Coastguard Worker 
549*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value))
550*f6dc9357SAndroid Build Coastguard Worker {
551*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
552*f6dc9357SAndroid Build Coastguard Worker   NCOM::CPropVariant prop;
553*f6dc9357SAndroid Build Coastguard Worker 
554*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
555*f6dc9357SAndroid Build Coastguard Worker   {
556*f6dc9357SAndroid Build Coastguard Worker     case kpidPath:
557*f6dc9357SAndroid Build Coastguard Worker     {
558*f6dc9357SAndroid Build Coastguard Worker       if (!Name.IsEmpty())
559*f6dc9357SAndroid Build Coastguard Worker       {
560*f6dc9357SAndroid Build Coastguard Worker         AString s (Name);
561*f6dc9357SAndroid Build Coastguard Worker         s += '.';
562*f6dc9357SAndroid Build Coastguard Worker         s += Ext ? Ext : "img";
563*f6dc9357SAndroid Build Coastguard Worker         prop = s;
564*f6dc9357SAndroid Build Coastguard Worker       }
565*f6dc9357SAndroid Build Coastguard Worker       break;
566*f6dc9357SAndroid Build Coastguard Worker     }
567*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
568*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
569*f6dc9357SAndroid Build Coastguard Worker       prop = Footer.original_image_size;
570*f6dc9357SAndroid Build Coastguard Worker       break;
571*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension: prop = (Ext ? Ext : "img"); break;
572*f6dc9357SAndroid Build Coastguard Worker   }
573*f6dc9357SAndroid Build Coastguard Worker 
574*f6dc9357SAndroid Build Coastguard Worker   prop.Detach(value);
575*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
576*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
577*f6dc9357SAndroid Build Coastguard Worker }
578*f6dc9357SAndroid Build Coastguard Worker 
579*f6dc9357SAndroid Build Coastguard Worker 
580*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
581*f6dc9357SAndroid Build Coastguard Worker {
582*f6dc9357SAndroid Build Coastguard Worker   *numItems = 1;
583*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
584*f6dc9357SAndroid Build Coastguard Worker }
585*f6dc9357SAndroid Build Coastguard Worker 
586*f6dc9357SAndroid Build Coastguard Worker 
587*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I_NO_SIG(
588*f6dc9357SAndroid Build Coastguard Worker   "AVB", "avb img", NULL, 0xc0,
589*f6dc9357SAndroid Build Coastguard Worker   /* k_Signature, */
590*f6dc9357SAndroid Build Coastguard Worker   0,
591*f6dc9357SAndroid Build Coastguard Worker   /* NArcInfoFlags::kUseGlobalOffset | */
592*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kBackwardOpen
593*f6dc9357SAndroid Build Coastguard Worker   ,
594*f6dc9357SAndroid Build Coastguard Worker   NULL)
595*f6dc9357SAndroid Build Coastguard Worker 
596*f6dc9357SAndroid Build Coastguard Worker }}
597