public Errno Stat(string path, out FileEntryInfo stat) { stat = null; if (!mounted) { return(Errno.AccessDenied); } Errno err = GetFileEntry(path, out DecodedDirectoryEntry entry); if (err != Errno.NoError) { return(err); } stat = new FileEntryInfo { Attributes = new FileAttributes(), Blocks = (long)(entry.Size / 2048), // TODO: XA BlockSize = 2048, Length = (long)entry.Size, Inode = entry.Extents?[0].extent ?? 0, Links = 1, LastWriteTimeUtc = entry.Timestamp }; if (entry.Size % 2048 > 0) { stat.Blocks++; } if (entry.Flags.HasFlag(FileFlags.Directory)) { stat.Attributes |= FileAttributes.Directory; } if (entry.Flags.HasFlag(FileFlags.Hidden)) { stat.Attributes |= FileAttributes.Hidden; } if (entry.FinderInfo != null) { if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kIsAlias)) { stat.Attributes |= FileAttributes.Alias; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kIsInvisible)) { stat.Attributes |= FileAttributes.Hidden; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kHasBeenInited)) { stat.Attributes |= FileAttributes.HasBeenInited; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kHasCustomIcon)) { stat.Attributes |= FileAttributes.HasCustomIcon; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kHasNoINITs)) { stat.Attributes |= FileAttributes.HasNoINITs; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kIsOnDesk)) { stat.Attributes |= FileAttributes.IsOnDesk; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kIsShared)) { stat.Attributes |= FileAttributes.Shared; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kIsStationery)) { stat.Attributes |= FileAttributes.Stationery; } if (entry.FinderInfo.fdFlags.HasFlag(FinderFlags.kHasBundle)) { stat.Attributes |= FileAttributes.Bundle; } } if (entry.AppleIcon != null) { stat.Attributes |= FileAttributes.HasCustomIcon; } if (entry.XA != null) { if (entry.XA.Value.attributes.HasFlag(XaAttributes.GroupExecute)) { stat.Mode |= 8; } if (entry.XA.Value.attributes.HasFlag(XaAttributes.GroupRead)) { stat.Mode |= 32; } if (entry.XA.Value.attributes.HasFlag(XaAttributes.OwnerExecute)) { stat.Mode |= 64; } if (entry.XA.Value.attributes.HasFlag(XaAttributes.OwnerRead)) { stat.Mode |= 256; } if (entry.XA.Value.attributes.HasFlag(XaAttributes.SystemExecute)) { stat.Mode |= 1; } if (entry.XA.Value.attributes.HasFlag(XaAttributes.SystemRead)) { stat.Mode |= 4; } stat.UID = entry.XA.Value.user; stat.GID = entry.XA.Value.group; stat.Inode = entry.XA.Value.filenumber; } if (entry.PosixAttributes != null) { stat.Mode = (uint?)entry.PosixAttributes.Value.st_mode & 0x0FFF; if (entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Block)) { stat.Attributes |= FileAttributes.BlockDevice; } if (entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Character)) { stat.Attributes |= FileAttributes.CharDevice; } if (entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Pipe)) { stat.Attributes |= FileAttributes.Pipe; } if (entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Socket)) { stat.Attributes |= FileAttributes.Socket; } if (entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Symlink)) { stat.Attributes |= FileAttributes.Symlink; } stat.Links = entry.PosixAttributes.Value.st_nlink; stat.UID = entry.PosixAttributes.Value.st_uid; stat.GID = entry.PosixAttributes.Value.st_gid; stat.Inode = entry.PosixAttributes.Value.st_ino; } else if (entry.PosixAttributesOld != null) { stat.Mode = (uint?)entry.PosixAttributesOld.Value.st_mode & 0x0FFF; if (entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Block)) { stat.Attributes |= FileAttributes.BlockDevice; } if (entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Character)) { stat.Attributes |= FileAttributes.CharDevice; } if (entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Pipe)) { stat.Attributes |= FileAttributes.Pipe; } if (entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Socket)) { stat.Attributes |= FileAttributes.Socket; } if (entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Symlink)) { stat.Attributes |= FileAttributes.Symlink; } stat.Links = entry.PosixAttributesOld.Value.st_nlink; stat.UID = entry.PosixAttributesOld.Value.st_uid; stat.GID = entry.PosixAttributesOld.Value.st_gid; } if (entry.AmigaProtection != null) { if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupExec)) { stat.Mode |= 8; } if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupRead)) { stat.Mode |= 32; } if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupWrite)) { stat.Mode |= 16; } if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherExec)) { stat.Mode |= 1; } if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherRead)) { stat.Mode |= 4; } if (entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherWrite)) { stat.Mode |= 2; } if (entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerExec)) { stat.Mode |= 64; } if (entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerRead)) { stat.Mode |= 256; } if (entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerWrite)) { stat.Mode |= 128; } if (entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.Archive)) { stat.Attributes |= FileAttributes.Archive; } } if (entry.PosixDeviceNumber != null) { stat.DeviceNo = (entry.PosixDeviceNumber.Value.dev_t_high << 32) + entry.PosixDeviceNumber.Value.dev_t_low; } if (entry.RripModify != null) { stat.LastWriteTimeUtc = DecodeIsoDateTime(entry.RripModify); } if (entry.RripAccess != null) { stat.AccessTimeUtc = DecodeIsoDateTime(entry.RripAccess); } if (entry.RripAttributeChange != null) { stat.StatusChangeTimeUtc = DecodeIsoDateTime(entry.RripAttributeChange); } if (entry.RripBackup != null) { stat.BackupTimeUtc = DecodeIsoDateTime(entry.RripBackup); } if (entry.SymbolicLink != null) { stat.Attributes |= FileAttributes.Symlink; } if (entry.XattrLength == 0 || cdi || highSierra) { return(Errno.NoError); } if (entry.CdiSystemArea != null) { stat.UID = entry.CdiSystemArea.Value.owner; stat.GID = entry.CdiSystemArea.Value.group; if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.GroupExecute)) { stat.Mode |= 8; } if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.GroupRead)) { stat.Mode |= 32; } if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.OtherExecute)) { stat.Mode |= 1; } if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.OtherRead)) { stat.Mode |= 4; } if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.OwnerExecute)) { stat.Mode |= 64; } if (((CdiAttributes)entry.CdiSystemArea.Value.attributes).HasFlag(CdiAttributes.OwnerRead)) { stat.Mode |= 256; } } uint eaSizeInSectors = (uint)(entry.XattrLength / 2048); if (entry.XattrLength % 2048 > 0) { eaSizeInSectors++; } byte[] ea = ReadSectors(entry.Extents[0].extent, eaSizeInSectors); ExtendedAttributeRecord ear = Marshal.ByteArrayToStructureLittleEndian <ExtendedAttributeRecord>(ea); stat.UID = ear.owner; stat.GID = ear.group; stat.Mode = 0; if (ear.permissions.HasFlag(Permissions.GroupExecute)) { stat.Mode |= 8; } if (ear.permissions.HasFlag(Permissions.GroupRead)) { stat.Mode |= 32; } if (ear.permissions.HasFlag(Permissions.OwnerExecute)) { stat.Mode |= 64; } if (ear.permissions.HasFlag(Permissions.OwnerRead)) { stat.Mode |= 256; } if (ear.permissions.HasFlag(Permissions.OtherExecute)) { stat.Mode |= 1; } if (ear.permissions.HasFlag(Permissions.OtherRead)) { stat.Mode |= 4; } stat.CreationTimeUtc = DateHandlers.Iso9660ToDateTime(ear.creation_date); stat.LastWriteTimeUtc = DateHandlers.Iso9660ToDateTime(ear.modification_date); return(Errno.NoError); }
static DecodedVolumeDescriptor DecodeJolietDescriptor(PrimaryVolumeDescriptor jolietvd) { var decodedVD = new DecodedVolumeDescriptor { SystemIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.system_id).Replace('\u0000', ' '). TrimEnd(), VolumeIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.volume_id).Replace('\u0000', ' '). TrimEnd(), VolumeSetIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.volume_set_id). Replace('\u0000', ' ').TrimEnd(), PublisherIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.publisher_id).Replace('\u0000', ' '). TrimEnd(), DataPreparerIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.preparer_id). Replace('\u0000', ' ').TrimEnd(), ApplicationIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.application_id). Replace('\u0000', ' ').TrimEnd() }; if (jolietvd.creation_date[0] < 0x31 || jolietvd.creation_date[0] > 0x39) { decodedVD.CreationTime = DateTime.MinValue; } else { decodedVD.CreationTime = DateHandlers.Iso9660ToDateTime(jolietvd.creation_date); } if (jolietvd.modification_date[0] < 0x31 || jolietvd.modification_date[0] > 0x39) { decodedVD.HasModificationTime = false; } else { decodedVD.HasModificationTime = true; decodedVD.ModificationTime = DateHandlers.Iso9660ToDateTime(jolietvd.modification_date); } if (jolietvd.expiration_date[0] < 0x31 || jolietvd.expiration_date[0] > 0x39) { decodedVD.HasExpirationTime = false; } else { decodedVD.HasExpirationTime = true; decodedVD.ExpirationTime = DateHandlers.Iso9660ToDateTime(jolietvd.expiration_date); } if (jolietvd.effective_date[0] < 0x31 || jolietvd.effective_date[0] > 0x39) { decodedVD.HasEffectiveTime = false; } else { decodedVD.HasEffectiveTime = true; decodedVD.EffectiveTime = DateHandlers.Iso9660ToDateTime(jolietvd.effective_date); } decodedVD.Blocks = jolietvd.volume_space_size; decodedVD.BlockSize = jolietvd.logical_block_size; return(decodedVD); }