xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/MubHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // MubHandler.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 #include "../../../C/SwapBytes.h"
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/IntToString.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyString.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariant.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #include "HandlerCont.h"
18*f6dc9357SAndroid Build Coastguard Worker 
19*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
20*f6dc9357SAndroid Build Coastguard Worker using namespace NCOM;
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
23*f6dc9357SAndroid Build Coastguard Worker namespace NMub {
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_ARCH_ABI64 ((UInt32)1 << 24)
26*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_386    7
27*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_ARM   12
28*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_SPARC 14
29*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_PPC   18
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_PPC64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_PPC)
32*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386)
33*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_TYPE_ARM64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_ARM)
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_SUBTYPE_LIB64 ((UInt32)1 << 31)
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #define MACH_CPU_SUBTYPE_I386_ALL 3
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker struct CItem
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker   UInt32 Type;
42*f6dc9357SAndroid Build Coastguard Worker   UInt32 SubType;
43*f6dc9357SAndroid Build Coastguard Worker   UInt32 Offset;
44*f6dc9357SAndroid Build Coastguard Worker   UInt32 Size;
45*f6dc9357SAndroid Build Coastguard Worker   UInt32 Align;
46*f6dc9357SAndroid Build Coastguard Worker };
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kNumFilesMax = 6;
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker Z7_class_CHandler_final: public CHandlerCont
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker   Z7_IFACE_COM7_IMP(IInArchive_Cont)
53*f6dc9357SAndroid Build Coastguard Worker 
54*f6dc9357SAndroid Build Coastguard Worker   // UInt64 _startPos;
55*f6dc9357SAndroid Build Coastguard Worker   UInt64 _phySize;
56*f6dc9357SAndroid Build Coastguard Worker   UInt32 _numItems;
57*f6dc9357SAndroid Build Coastguard Worker   bool _bigEndian;
58*f6dc9357SAndroid Build Coastguard Worker   CItem _items[kNumFilesMax];
59*f6dc9357SAndroid Build Coastguard Worker 
60*f6dc9357SAndroid Build Coastguard Worker   HRESULT Open2(IInStream *stream);
61*f6dc9357SAndroid Build Coastguard Worker 
62*f6dc9357SAndroid Build Coastguard Worker   virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const Z7_override
63*f6dc9357SAndroid Build Coastguard Worker   {
64*f6dc9357SAndroid Build Coastguard Worker     const CItem &item = _items[index];
65*f6dc9357SAndroid Build Coastguard Worker     pos = item.Offset;
66*f6dc9357SAndroid Build Coastguard Worker     size = item.Size;
67*f6dc9357SAndroid Build Coastguard Worker     return NExtract::NOperationResult::kOK;
68*f6dc9357SAndroid Build Coastguard Worker   }
69*f6dc9357SAndroid Build Coastguard Worker };
70*f6dc9357SAndroid Build Coastguard Worker 
71*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
72*f6dc9357SAndroid Build Coastguard Worker {
73*f6dc9357SAndroid Build Coastguard Worker   kpidBigEndian
74*f6dc9357SAndroid Build Coastguard Worker };
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker static const Byte kProps[] =
77*f6dc9357SAndroid Build Coastguard Worker {
78*f6dc9357SAndroid Build Coastguard Worker   kpidPath,
79*f6dc9357SAndroid Build Coastguard Worker   kpidSize,
80*f6dc9357SAndroid Build Coastguard Worker   kpidOffset,
81*f6dc9357SAndroid Build Coastguard Worker   kpidClusterSize // Align
82*f6dc9357SAndroid Build Coastguard Worker };
83*f6dc9357SAndroid Build Coastguard Worker 
84*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props
85*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
86*f6dc9357SAndroid Build Coastguard Worker 
87*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
88*f6dc9357SAndroid Build Coastguard Worker {
89*f6dc9357SAndroid Build Coastguard Worker   PropVariant_Clear(value);
90*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
91*f6dc9357SAndroid Build Coastguard Worker   {
92*f6dc9357SAndroid Build Coastguard Worker     case kpidBigEndian: PropVarEm_Set_Bool(value, _bigEndian); break;
93*f6dc9357SAndroid Build Coastguard Worker     case kpidPhySize: PropVarEm_Set_UInt64(value, _phySize); break;
94*f6dc9357SAndroid Build Coastguard Worker   }
95*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker 
98*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker   PropVariant_Clear(value);
101*f6dc9357SAndroid Build Coastguard Worker   const CItem &item = _items[index];
102*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
103*f6dc9357SAndroid Build Coastguard Worker   {
104*f6dc9357SAndroid Build Coastguard Worker     case kpidExtension:
105*f6dc9357SAndroid Build Coastguard Worker     {
106*f6dc9357SAndroid Build Coastguard Worker       char temp[32];
107*f6dc9357SAndroid Build Coastguard Worker       const char *ext = NULL;
108*f6dc9357SAndroid Build Coastguard Worker       switch (item.Type)
109*f6dc9357SAndroid Build Coastguard Worker       {
110*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_386:   ext = "x86";   break;
111*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_ARM:   ext = "arm";   break;
112*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_SPARC: ext = "sparc"; break;
113*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_PPC:   ext = "ppc";   break;
114*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_AMD64: ext = "x64";   break;
115*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_ARM64: ext = "arm64"; break;
116*f6dc9357SAndroid Build Coastguard Worker         case MACH_CPU_TYPE_PPC64: ext = "ppc64"; break;
117*f6dc9357SAndroid Build Coastguard Worker         default:
118*f6dc9357SAndroid Build Coastguard Worker           temp[0] = 'c';
119*f6dc9357SAndroid Build Coastguard Worker           temp[1] = 'p';
120*f6dc9357SAndroid Build Coastguard Worker           temp[2] = 'u';
121*f6dc9357SAndroid Build Coastguard Worker           char *p = ConvertUInt32ToString(item.Type & ~MACH_CPU_ARCH_ABI64, temp + 3);
122*f6dc9357SAndroid Build Coastguard Worker           if (item.Type & MACH_CPU_ARCH_ABI64)
123*f6dc9357SAndroid Build Coastguard Worker             MyStringCopy(p, "_64");
124*f6dc9357SAndroid Build Coastguard Worker           break;
125*f6dc9357SAndroid Build Coastguard Worker       }
126*f6dc9357SAndroid Build Coastguard Worker       if (ext)
127*f6dc9357SAndroid Build Coastguard Worker         MyStringCopy(temp, ext);
128*f6dc9357SAndroid Build Coastguard Worker       if (item.SubType != 0)
129*f6dc9357SAndroid Build Coastguard Worker       if ((item.Type != MACH_CPU_TYPE_386 &&
130*f6dc9357SAndroid Build Coastguard Worker            item.Type != MACH_CPU_TYPE_AMD64)
131*f6dc9357SAndroid Build Coastguard Worker            || (item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL
132*f6dc9357SAndroid Build Coastguard Worker          )
133*f6dc9357SAndroid Build Coastguard Worker       {
134*f6dc9357SAndroid Build Coastguard Worker         unsigned pos = MyStringLen(temp);
135*f6dc9357SAndroid Build Coastguard Worker         temp[pos++] = '-';
136*f6dc9357SAndroid Build Coastguard Worker         ConvertUInt32ToString(item.SubType, temp + pos);
137*f6dc9357SAndroid Build Coastguard Worker       }
138*f6dc9357SAndroid Build Coastguard Worker       return PropVarEm_Set_Str(value, temp);
139*f6dc9357SAndroid Build Coastguard Worker     }
140*f6dc9357SAndroid Build Coastguard Worker     case kpidSize:
141*f6dc9357SAndroid Build Coastguard Worker     case kpidPackSize:
142*f6dc9357SAndroid Build Coastguard Worker       PropVarEm_Set_UInt64(value, item.Size);
143*f6dc9357SAndroid Build Coastguard Worker       break;
144*f6dc9357SAndroid Build Coastguard Worker     case kpidOffset:
145*f6dc9357SAndroid Build Coastguard Worker       PropVarEm_Set_UInt64(value, item.Offset);
146*f6dc9357SAndroid Build Coastguard Worker       break;
147*f6dc9357SAndroid Build Coastguard Worker     case kpidClusterSize:
148*f6dc9357SAndroid Build Coastguard Worker       PropVarEm_Set_UInt32(value, (UInt32)1 << item.Align);
149*f6dc9357SAndroid Build Coastguard Worker       break;
150*f6dc9357SAndroid Build Coastguard Worker   }
151*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
152*f6dc9357SAndroid Build Coastguard Worker }
153*f6dc9357SAndroid Build Coastguard Worker 
154*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::Open2(IInStream *stream)
155*f6dc9357SAndroid Build Coastguard Worker {
156*f6dc9357SAndroid Build Coastguard Worker   // RINOK(InStream_GetPos(stream, _startPos));
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kHeaderSize = 2;
159*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kRecordSize = 5;
160*f6dc9357SAndroid Build Coastguard Worker   const UInt32 kBufSize = kHeaderSize + kNumFilesMax * kRecordSize;
161*f6dc9357SAndroid Build Coastguard Worker   UInt32 buf[kBufSize];
162*f6dc9357SAndroid Build Coastguard Worker   size_t processed = kBufSize * 4;
163*f6dc9357SAndroid Build Coastguard Worker   RINOK(ReadStream(stream, buf, &processed))
164*f6dc9357SAndroid Build Coastguard Worker   processed >>= 2;
165*f6dc9357SAndroid Build Coastguard Worker   if (processed < kHeaderSize)
166*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker   bool be;
169*f6dc9357SAndroid Build Coastguard Worker   switch (buf[0])
170*f6dc9357SAndroid Build Coastguard Worker   {
171*f6dc9357SAndroid Build Coastguard Worker     case Z7_CONV_BE_TO_NATIVE_CONST32(0xCAFEBABE): be = true; break;
172*f6dc9357SAndroid Build Coastguard Worker     case Z7_CONV_BE_TO_NATIVE_CONST32(0xB9FAF10E): be = false; break;
173*f6dc9357SAndroid Build Coastguard Worker     default: return S_FALSE;
174*f6dc9357SAndroid Build Coastguard Worker   }
175*f6dc9357SAndroid Build Coastguard Worker   _bigEndian = be;
176*f6dc9357SAndroid Build Coastguard Worker   if (
177*f6dc9357SAndroid Build Coastguard Worker       #if defined(MY_CPU_BE)
178*f6dc9357SAndroid Build Coastguard Worker         !
179*f6dc9357SAndroid Build Coastguard Worker       #endif
180*f6dc9357SAndroid Build Coastguard Worker         be)
181*f6dc9357SAndroid Build Coastguard Worker     z7_SwapBytes4(&buf[1], processed - 1);
182*f6dc9357SAndroid Build Coastguard Worker   const UInt32 num = buf[1];
183*f6dc9357SAndroid Build Coastguard Worker   if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize)
184*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
185*f6dc9357SAndroid Build Coastguard Worker   if (num == 0)
186*f6dc9357SAndroid Build Coastguard Worker     return S_FALSE;
187*f6dc9357SAndroid Build Coastguard Worker   UInt64 endPosMax = kHeaderSize;
188*f6dc9357SAndroid Build Coastguard Worker 
189*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < num; i++)
190*f6dc9357SAndroid Build Coastguard Worker   {
191*f6dc9357SAndroid Build Coastguard Worker     const UInt32 *p = buf + kHeaderSize + i * kRecordSize;
192*f6dc9357SAndroid Build Coastguard Worker     CItem &sb = _items[i];
193*f6dc9357SAndroid Build Coastguard Worker     sb.Type = p[0];
194*f6dc9357SAndroid Build Coastguard Worker     sb.SubType = p[1];
195*f6dc9357SAndroid Build Coastguard Worker     sb.Offset = p[2];
196*f6dc9357SAndroid Build Coastguard Worker     sb.Size = p[3];
197*f6dc9357SAndroid Build Coastguard Worker     const UInt32 align = p[4];
198*f6dc9357SAndroid Build Coastguard Worker     sb.Align = align;
199*f6dc9357SAndroid Build Coastguard Worker     if (align > 31)
200*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
201*f6dc9357SAndroid Build Coastguard Worker     if (sb.Offset < kHeaderSize + num * kRecordSize)
202*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
203*f6dc9357SAndroid Build Coastguard Worker     if ((sb.Type & ~MACH_CPU_ARCH_ABI64) >= 0x100 ||
204*f6dc9357SAndroid Build Coastguard Worker         (sb.SubType & ~MACH_CPU_SUBTYPE_LIB64) >= 0x100)
205*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker     const UInt64 endPos = (UInt64)sb.Offset + sb.Size;
208*f6dc9357SAndroid Build Coastguard Worker     if (endPosMax < endPos)
209*f6dc9357SAndroid Build Coastguard Worker       endPosMax = endPos;
210*f6dc9357SAndroid Build Coastguard Worker   }
211*f6dc9357SAndroid Build Coastguard Worker   _numItems = num;
212*f6dc9357SAndroid Build Coastguard Worker   _phySize = endPosMax;
213*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
214*f6dc9357SAndroid Build Coastguard Worker }
215*f6dc9357SAndroid Build Coastguard Worker 
216*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
217*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* maxCheckStartPosition */,
218*f6dc9357SAndroid Build Coastguard Worker     IArchiveOpenCallback * /* openArchiveCallback */))
219*f6dc9357SAndroid Build Coastguard Worker {
220*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_BEGIN
221*f6dc9357SAndroid Build Coastguard Worker   Close();
222*f6dc9357SAndroid Build Coastguard Worker   try
223*f6dc9357SAndroid Build Coastguard Worker   {
224*f6dc9357SAndroid Build Coastguard Worker     if (Open2(inStream) != S_OK)
225*f6dc9357SAndroid Build Coastguard Worker       return S_FALSE;
226*f6dc9357SAndroid Build Coastguard Worker     _stream = inStream;
227*f6dc9357SAndroid Build Coastguard Worker   }
228*f6dc9357SAndroid Build Coastguard Worker   catch(...) { return S_FALSE; }
229*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
230*f6dc9357SAndroid Build Coastguard Worker   COM_TRY_END
231*f6dc9357SAndroid Build Coastguard Worker }
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
234*f6dc9357SAndroid Build Coastguard Worker {
235*f6dc9357SAndroid Build Coastguard Worker   _stream.Release();
236*f6dc9357SAndroid Build Coastguard Worker   _numItems = 0;
237*f6dc9357SAndroid Build Coastguard Worker   _phySize = 0;
238*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
239*f6dc9357SAndroid Build Coastguard Worker }
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker   *numItems = _numItems;
244*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
245*f6dc9357SAndroid Build Coastguard Worker }
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker namespace NBe {
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[] = {
250*f6dc9357SAndroid Build Coastguard Worker     7, 0xCA, 0xFE, 0xBA, 0xBE, 0, 0, 0,
251*f6dc9357SAndroid Build Coastguard Worker     4, 0xB9, 0xFA, 0xF1, 0x0E };
252*f6dc9357SAndroid Build Coastguard Worker 
253*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I(
254*f6dc9357SAndroid Build Coastguard Worker   "Mub", "mub", NULL, 0xE2,
255*f6dc9357SAndroid Build Coastguard Worker   k_Signature,
256*f6dc9357SAndroid Build Coastguard Worker   0,
257*f6dc9357SAndroid Build Coastguard Worker   NArcInfoFlags::kMultiSignature,
258*f6dc9357SAndroid Build Coastguard Worker   NULL)
259*f6dc9357SAndroid Build Coastguard Worker 
260*f6dc9357SAndroid Build Coastguard Worker }
261*f6dc9357SAndroid Build Coastguard Worker 
262*f6dc9357SAndroid Build Coastguard Worker }}
263