| 124 | |
| 125 | |
| 126 | bool Archive::IsArchive(bool EnableBroken) |
| 127 | { |
| 128 | Encrypted=false; |
| 129 | BrokenHeader=false; // Might be left from previous volume. |
| 130 | |
| 131 | #ifndef SFX_MODULE |
| 132 | if (IsDevice()) |
| 133 | { |
| 134 | uiMsg(UIERROR_INVALIDNAME,FileName,FileName); |
| 135 | return false; |
| 136 | } |
| 137 | #endif |
| 138 | if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3) |
| 139 | return false; |
| 140 | SFXSize=0; |
| 141 | |
| 142 | RARFORMAT Type; |
| 143 | if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE) |
| 144 | { |
| 145 | Format=Type; |
| 146 | if (Format==RARFMT14) |
| 147 | Seek(Tell()-SIZEOF_MARKHEAD3,SEEK_SET); |
| 148 | } |
| 149 | else |
| 150 | { |
| 151 | Array<char> Buffer(MAXSFXSIZE); |
| 152 | long CurPos=(long)Tell(); |
| 153 | int ReadSize=Read(&Buffer[0],Buffer.Size()-16); |
| 154 | for (int I=0;I<ReadSize;I++) |
| 155 | if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE) |
| 156 | { |
| 157 | Format=Type; |
| 158 | if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31) |
| 159 | { |
| 160 | char *D=&Buffer[28-CurPos]; |
| 161 | if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58) |
| 162 | continue; |
| 163 | } |
| 164 | SFXSize=CurPos+I; |
| 165 | Seek(SFXSize,SEEK_SET); |
| 166 | if (Format==RARFMT15 || Format==RARFMT50) |
| 167 | Read(MarkHead.Mark,SIZEOF_MARKHEAD3); |
| 168 | break; |
| 169 | } |
| 170 | if (SFXSize==0) |
| 171 | return false; |
| 172 | } |
| 173 | if (Format==RARFMT_FUTURE) |
| 174 | { |
| 175 | uiMsg(UIERROR_NEWRARFORMAT,FileName); |
| 176 | return false; |
| 177 | } |
| 178 | if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer. |
| 179 | { |
| 180 | if (Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1)!=1 || MarkHead.Mark[SIZEOF_MARKHEAD3]!=0) |
| 181 | return false; |
| 182 | MarkHead.HeadSize=SIZEOF_MARKHEAD5; |
| 183 | } |
no test coverage detected