Example #1
0
        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);
        }
Example #2
0
        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);
        }