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