private static DateTime? ProcessExtendedTime(ushort extendedFlags, DateTime? time, MarkingBinaryReader reader, int i) { uint rmode = (uint)extendedFlags >> (3 - i) * 4; if ((rmode & 8) == 0) { return null; } if (i != 0) { uint DosTime = reader.ReadUInt32(); time = Utilities.DosDateToDateTime(DosTime); } if ((rmode & 4) == 0) { time = time.Value.AddSeconds(1); } uint nanosecondHundreds = 0; int count = (int)rmode & 3; for (int j = 0; j < count; j++) { byte b = reader.ReadByte(); nanosecondHundreds |= (((uint)b) << ((j + 3 - count) * 8)); } //10^-7 to 10^-3 return time.Value.AddMilliseconds(nanosecondHundreds * Math.Pow(10, -4)); }
protected override void ReadFromReader(MarkingBinaryReader reader) { uint lowUncompressedSize = reader.ReadUInt32(); HostOS = (HostOS)(int)reader.ReadByte(); FileCRC = reader.ReadUInt32(); FileLastModifiedTime = Utilities.DosDateToDateTime(reader.ReadInt32()); RarVersion = reader.ReadByte(); PackingMethod = reader.ReadByte(); short nameSize = reader.ReadInt16(); FileAttributes = reader.ReadInt32(); uint highCompressedSize = 0; uint highUncompressedkSize = 0; if (FileFlags.HasFlag(FileFlags.LARGE)) { highCompressedSize = reader.ReadUInt32(); highUncompressedkSize = reader.ReadUInt32(); } else { if (lowUncompressedSize == 0xffffffff) { lowUncompressedSize = 0xffffffff; highUncompressedkSize = int.MaxValue; } } CompressedSize = UInt32To64(highCompressedSize, AdditionalSize); UncompressedSize = UInt32To64(highUncompressedkSize, lowUncompressedSize); nameSize = nameSize > 4 * 1024 ? (short)(4 * 1024) : nameSize; byte[] fileNameBytes = reader.ReadBytes(nameSize); switch (HeaderType) { case HeaderType.FileHeader: { if (FileFlags.HasFlag(FileFlags.UNICODE)) { int length = 0; while (length < fileNameBytes.Length && fileNameBytes[length] != 0) { length++; } if (length != nameSize) { length++; FileName = FileNameDecoder.Decode(fileNameBytes, length); } else { FileName = DecodeDefault(fileNameBytes); } } else { FileName = DecodeDefault(fileNameBytes); } FileName = ConvertPath(FileName, HostOS); } break; case HeaderType.NewSubHeader: { int datasize = HeaderSize - NEWLHD_SIZE - nameSize; if (FileFlags.HasFlag(FileFlags.SALT)) { datasize -= SALT_SIZE; } if (datasize > 0) { SubData = reader.ReadBytes(datasize); } if (NewSubHeaderType.SUBHEAD_TYPE_RR.Equals(fileNameBytes)) { RecoverySectors = SubData[8] + (SubData[9] << 8) + (SubData[10] << 16) + (SubData[11] << 24); } } break; } if (FileFlags.HasFlag(FileFlags.SALT)) { Salt = reader.ReadBytes(SALT_SIZE); } if (FileFlags.HasFlag(FileFlags.EXTTIME)) { ushort extendedFlags = reader.ReadUInt16(); FileLastModifiedTime = ProcessExtendedTime(extendedFlags, FileLastModifiedTime, reader, 0); FileCreatedTime = ProcessExtendedTime(extendedFlags, null, reader, 1); FileLastAccessedTime = ProcessExtendedTime(extendedFlags, null, reader, 2); FileArchivedTime = ProcessExtendedTime(extendedFlags, null, reader, 3); } }