1 // Archive/IsoItem.h 2 3 #ifndef ZIP7_INC_ARCHIVE_ISO_ITEM_H 4 #define ZIP7_INC_ARCHIVE_ISO_ITEM_H 5 6 #include "../../../../C/CpuArch.h" 7 8 #include "../../../Common/MyString.h" 9 #include "../../../Common/MyBuffer.h" 10 11 #include "../../../Windows/TimeUtils.h" 12 13 #include "IsoHeader.h" 14 15 namespace NArchive { 16 namespace NIso { 17 18 struct CRecordingDateTime 19 { 20 Byte Year; 21 Byte Month; 22 Byte Day; 23 Byte Hour; 24 Byte Minute; 25 Byte Second; 26 signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded. 27 GetFileTimeCRecordingDateTime28 bool GetFileTime(NWindows::NCOM::CPropVariant &prop) const 29 { 30 UInt64 v; 31 const bool res = NWindows::NTime::GetSecondsSince1601(Year + 1900, Month, Day, Hour, Minute, Second, v); 32 if (res) 33 { 34 v = (UInt64)((Int64)v - (Int64)((Int32)GmtOffset * 15 * 60)); 35 v *= 10000000; 36 prop.SetAsTimeFrom_Ft64_Prec(v, k_PropVar_TimePrec_Base); 37 } 38 return res; 39 } 40 }; 41 42 enum EPx 43 { 44 k_Px_Mode, 45 k_Px_Links, 46 k_Px_User, 47 k_Px_Group, 48 k_Px_SerialNumber 49 50 // k_Px_Num 51 }; 52 53 /* 54 enum ETf 55 { 56 k_Tf_CTime, 57 k_Tf_MTime, 58 k_Tf_ATime, 59 k_Tf_Attrib, 60 k_Tf_Backup, 61 k_Tf_Expiration, 62 k_Tf_Effective 63 64 // k_Tf_Num 65 }; 66 */ 67 68 struct CDirRecord 69 { 70 UInt32 ExtentLocation; 71 UInt32 Size; 72 CRecordingDateTime DateTime; 73 Byte FileFlags; 74 Byte FileUnitSize; 75 Byte InterleaveGapSize; 76 Byte ExtendedAttributeRecordLen; 77 UInt16 VolSequenceNumber; 78 CByteBuffer FileId; 79 CByteBuffer SystemUse; 80 AreMultiPartEqualWithCDirRecord81 bool AreMultiPartEqualWith(const CDirRecord &a) const 82 { 83 return FileId == a.FileId 84 && (FileFlags & (~NFileFlags::kNonFinalExtent)) == 85 (a.FileFlags & (~NFileFlags::kNonFinalExtent)); 86 } 87 IsDirCDirRecord88 bool IsDir() const { return (FileFlags & NFileFlags::kDirectory) != 0; } IsNonFinalExtentCDirRecord89 bool IsNonFinalExtent() const { return (FileFlags & NFileFlags::kNonFinalExtent) != 0; } 90 IsSystemItemCDirRecord91 bool IsSystemItem() const 92 { 93 if (FileId.Size() != 1) 94 return false; 95 Byte b = *(const Byte *)FileId; 96 return (b == 0 || b == 1); 97 } 98 99 FindSuspRecordCDirRecord100 const Byte* FindSuspRecord(unsigned skipSize, Byte id0, Byte id1, unsigned &lenRes) const 101 { 102 lenRes = 0; 103 if (SystemUse.Size() < skipSize) 104 return NULL; 105 const Byte *p = (const Byte *)SystemUse + skipSize; 106 unsigned rem = (unsigned)(SystemUse.Size() - skipSize); 107 while (rem >= 5) 108 { 109 unsigned len = p[2]; 110 if (len < 3 || len > rem) 111 return NULL; 112 if (p[0] == id0 && p[1] == id1 && p[3] == 1) 113 { 114 if (len < 4) 115 return NULL; // Check it 116 lenRes = len - 4; 117 return p + 4; 118 } 119 p += len; 120 rem -= len; 121 } 122 return NULL; 123 } 124 125 GetNameCurCDirRecord126 const Byte* GetNameCur(bool checkSusp, unsigned skipSize, unsigned &nameLenRes) const 127 { 128 const Byte *res = NULL; 129 unsigned len = 0; 130 if (checkSusp) 131 res = FindSuspRecord(skipSize, 'N', 'M', len); 132 if (!res || len < 1) 133 { 134 res = (const Byte *)FileId; 135 len = (unsigned)FileId.Size(); 136 } 137 else 138 { 139 res++; 140 len--; 141 } 142 unsigned i; 143 for (i = 0; i < len; i++) 144 if (res[i] == 0) 145 break; 146 nameLenRes = i; 147 return res; 148 } 149 150 GetSymLinkCDirRecord151 bool GetSymLink(unsigned skipSize, AString &link) const 152 { 153 link.Empty(); 154 const Byte *p = NULL; 155 unsigned len = 0; 156 p = FindSuspRecord(skipSize, 'S', 'L', len); 157 if (!p || len < 1) 158 return false; 159 160 if (*p != 0) 161 return false; 162 163 p++; 164 len--; 165 166 while (len != 0) 167 { 168 if (len < 2) 169 return false; 170 unsigned flags = p[0]; 171 unsigned cl = p[1]; 172 p += 2; 173 len -= 2; 174 175 if (cl > len) 176 return false; 177 178 bool needSlash = false; 179 180 if (flags & (1 << 1)) link += "./"; 181 else if (flags & (1 << 2)) link += "../"; 182 else if (flags & (1 << 3)) link.Add_Slash(); 183 else 184 needSlash = true; 185 186 for (unsigned i = 0; i < cl; i++) 187 { 188 const Byte c = p[i]; 189 if (c == 0) 190 { 191 break; 192 // return false; 193 } 194 link += (char)c; 195 } 196 197 p += cl; 198 len -= cl; 199 200 if (len == 0) 201 break; 202 203 if (needSlash) 204 link.Add_Slash(); 205 } 206 207 return true; 208 } 209 GetLe32Be32CDirRecord210 static bool GetLe32Be32(const Byte *p, UInt32 &dest) 211 { 212 UInt32 v1 = GetUi32(p); 213 UInt32 v2 = GetBe32(p + 4); 214 if (v1 == v2) 215 { 216 dest = v1; 217 return true; 218 } 219 return false; 220 } 221 222 GetPxCDirRecord223 bool GetPx(unsigned skipSize, unsigned pxType, UInt32 &val) const 224 { 225 val = 0; 226 const Byte *p = NULL; 227 unsigned len = 0; 228 p = FindSuspRecord(skipSize, 'P', 'X', len); 229 if (!p) 230 return false; 231 // px.Clear(); 232 if (len < (pxType + 1) * 8) 233 return false; 234 235 return GetLe32Be32(p + pxType * 8, val); 236 } 237 238 /* 239 bool GetTf(int skipSize, unsigned pxType, CRecordingDateTime &t) const 240 { 241 const Byte *p = NULL; 242 unsigned len = 0; 243 p = FindSuspRecord(skipSize, 'T', 'F', len); 244 if (!p) 245 return false; 246 if (len < 1) 247 return false; 248 Byte flags = *p++; 249 len--; 250 251 unsigned step = 7; 252 if (flags & 0x80) 253 { 254 step = 17; 255 return false; 256 } 257 258 if ((flags & (1 << pxType)) == 0) 259 return false; 260 261 for (unsigned i = 0; i < pxType; i++) 262 { 263 if (len < step) 264 return false; 265 if (flags & (1 << i)) 266 { 267 p += step; 268 len -= step; 269 } 270 } 271 272 if (len < step) 273 return false; 274 275 t.Year = p[0]; 276 t.Month = p[1]; 277 t.Day = p[2]; 278 t.Hour = p[3]; 279 t.Minute = p[4]; 280 t.Second = p[5]; 281 t.GmtOffset = (signed char)p[6]; 282 283 return true; 284 } 285 */ 286 CheckSuspCDirRecord287 bool CheckSusp(const Byte *p, unsigned &startPos) const 288 { 289 if (p[0] == 'S' && 290 p[1] == 'P' && 291 p[2] == 0x7 && 292 p[3] == 0x1 && 293 p[4] == 0xBE && 294 p[5] == 0xEF) 295 { 296 startPos = p[6]; 297 return true; 298 } 299 return false; 300 } 301 CheckSuspCDirRecord302 bool CheckSusp(unsigned &startPos) const 303 { 304 const Byte *p = (const Byte *)SystemUse; 305 const size_t len = SystemUse.Size(); 306 const unsigned kMinLen = 7; 307 if (len < kMinLen) 308 return false; 309 if (CheckSusp(p, startPos)) 310 return true; 311 const unsigned kOffset2 = 14; 312 if (len < kOffset2 + kMinLen) 313 return false; 314 return CheckSusp(p + kOffset2, startPos); 315 } 316 }; 317 318 }} 319 320 #endif 321