public bool Identify(IMediaImage imagePlugin, Partition partition) { uint sbSize = (uint)(Marshal.SizeOf <RefsVolumeHeader>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <RefsVolumeHeader>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbSize >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <RefsVolumeHeader>()) { return(false); } RefsVolumeHeader refsVhdr = Marshal.ByteArrayToStructureLittleEndian <RefsVolumeHeader>(sector); return(refsVhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) && refsVhdr.signature.SequenceEqual(refsSignature)); }
// TODO: This can be optimized public bool WriteSectors(byte[] data, ulong sectorAddress, uint length) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length % imageInfo.SectorSize != 0) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress + length > imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } // Ignore empty sectors if (ArrayHelpers.ArrayIsNullOrEmpty(data)) { if (currentChunk.type == CHUNK_TYPE_COPY) { chunks.Add(currentChunk.sector, currentChunk); currentChunk = new BlockChunk { type = CHUNK_TYPE_NOCOPY, sector = currentSector }; } currentChunk.sectors += (ulong)(data.Length / imageInfo.SectorSize); currentSector += (ulong)(data.Length / imageInfo.SectorSize); masterChecksum.Update(data); ErrorMessage = ""; return(true); } for (uint i = 0; i < length; i++) { byte[] tmp = new byte[imageInfo.SectorSize]; Array.Copy(data, i * imageInfo.SectorSize, tmp, 0, imageInfo.SectorSize); if (!WriteSector(tmp, sectorAddress + i)) { return(false); } } ErrorMessage = ""; return(true); }
public bool Identify(IMediaImage imagePlugin, Partition partition) { RefsVolumeHeader refsVhdr = new RefsVolumeHeader(); uint sbSize = (uint)(Marshal.SizeOf(refsVhdr) / imagePlugin.Info.SectorSize); if (Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbSize >= partition.End) { return(false); } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf(refsVhdr)) { return(false); } IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(refsVhdr)); Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(refsVhdr)); refsVhdr = (RefsVolumeHeader)Marshal.PtrToStructure(sbPtr, typeof(RefsVolumeHeader)); Marshal.FreeHGlobal(sbPtr); return(refsVhdr.identifier == FSRS && ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) && refsVhdr.signature.SequenceEqual(refsSignature)); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); byte[] hdrB = new byte[Marshal.SizeOf <RsIdeHeader>()]; stream.Read(hdrB, 0, hdrB.Length); RsIdeHeader hdr = Marshal.ByteArrayToStructureLittleEndian <RsIdeHeader>(hdrB); if (!hdr.magic.SequenceEqual(signature)) { return(false); } dataOff = hdr.dataOff; imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.SectorSize = (uint)(hdr.flags.HasFlag(RsIdeFlags.HalfSectors) ? 256 : 512); imageInfo.ImageSize = (ulong)(stream.Length - dataOff); imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.Version = $"{hdr.revision >> 8}.{hdr.revision & 0x0F}"; if (!ArrayHelpers.ArrayIsNullOrEmpty(hdr.identify)) { identify = new byte[512]; Array.Copy(hdr.identify, 0, identify, 0, hdr.identify.Length); Identify.IdentifyDevice?ataId = Decoders.ATA.Identify.Decode(identify); if (ataId.HasValue) { imageInfo.ReadableMediaTags.Add(MediaTagType.ATA_IDENTIFY); imageInfo.Cylinders = ataId.Value.Cylinders; imageInfo.Heads = ataId.Value.Heads; imageInfo.SectorsPerTrack = ataId.Value.SectorsPerCard; imageInfo.DriveFirmwareRevision = ataId.Value.FirmwareRevision; imageInfo.DriveModel = ataId.Value.Model; imageInfo.DriveSerialNumber = ataId.Value.SerialNumber; imageInfo.MediaSerialNumber = ataId.Value.MediaSerial; imageInfo.MediaManufacturer = ataId.Value.MediaManufacturer; } } if (imageInfo.Cylinders == 0 || imageInfo.Heads == 0 || imageInfo.SectorsPerTrack == 0) { imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; } rsIdeImageFilter = imageFilter; return(true); }
public bool Identify(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); if ((stream.Length - Marshal.SizeOf <DriFooter>()) % 512 != 0) { return(false); } byte[] buffer = new byte[Marshal.SizeOf <DriFooter>()]; stream.Seek(-buffer.Length, SeekOrigin.End); stream.Read(buffer, 0, buffer.Length); DriFooter tmpFooter = Marshal.ByteArrayToStructureLittleEndian <DriFooter>(buffer); string sig = StringHandlers.CToString(tmpFooter.signature); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.signature = \"{0}\"", sig); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.five = {0}", tmpFooter.bpb.five); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.driveCode = {0}", tmpFooter.bpb.driveCode); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown = {0}", tmpFooter.bpb.unknown); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.cylinders = {0}", tmpFooter.bpb.cylinders); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown2 = {0}", tmpFooter.bpb.unknown2); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.bps = {0}", tmpFooter.bpb.bps); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spc = {0}", tmpFooter.bpb.spc); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.rsectors = {0}", tmpFooter.bpb.rsectors); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.fats_no = {0}", tmpFooter.bpb.fats_no); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sectors = {0}", tmpFooter.bpb.sectors); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.media_descriptor = {0}", tmpFooter.bpb.media_descriptor); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spfat = {0}", tmpFooter.bpb.spfat); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack = {0}", tmpFooter.bpb.sptrack); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.heads = {0}", tmpFooter.bpb.heads); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.hsectors = {0}", tmpFooter.bpb.hsectors); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.drive_no = {0}", tmpFooter.bpb.drive_no); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown3 = {0}", tmpFooter.bpb.unknown3); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown4 = {0}", tmpFooter.bpb.unknown4); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack2 = {0}", tmpFooter.bpb.sptrack2); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "ArrayHelpers.ArrayIsNullOrEmpty(tmp_footer.bpb.unknown5) = {0}", ArrayHelpers.ArrayIsNullOrEmpty(tmpFooter.bpb.unknown5)); Regex regexSignature = new Regex(REGEX_DRI); Match matchSignature = regexSignature.Match(sig); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "MatchSignature.Success? = {0}", matchSignature.Success); if (!matchSignature.Success) { return(false); } if (tmpFooter.bpb.sptrack * tmpFooter.bpb.cylinders * tmpFooter.bpb.heads != tmpFooter.bpb.sectors) { return(false); } return(tmpFooter.bpb.sectors * tmpFooter.bpb.bps + Marshal.SizeOf <DriFooter>() == stream.Length); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; var sb = new StringBuilder(); int sbSizeInBytes = Marshal.SizeOf <SuperBlock>(); uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize); if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0) { sbSizeInSectors++; } byte[] sbSector = imagePlugin.ReadSectors(partition.Start, sbSizeInSectors); SuperBlock supblk = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sbSector); sb.AppendFormat("{0} bytes per zone", supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} zones in volume ({1} bytes)", supblk.s_nzones, supblk.s_nzones * supblk.s_zone_size). AppendLine(); sb.AppendFormat("{0} inodes", supblk.s_ninodes).AppendLine(); sb.AppendFormat("{0} data zones ({1} bytes)", supblk.s_ndatazones, supblk.s_ndatazones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} imap zones ({1} bytes)", supblk.s_imap_zones, supblk.s_imap_zones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("{0} zmap zones ({1} bytes)", supblk.s_zmap_zones, supblk.s_zmap_zones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("First data zone: {0}", supblk.s_firstdatazone).AppendLine(); sb.AppendFormat("Maximum filesize is {0} bytes ({1} MiB)", supblk.s_max_size, supblk.s_max_size / 1048576). AppendLine(); sb.AppendFormat("{0} zones reserved for kernel images ({1} bytes)", supblk.s_kernzones, supblk.s_kernzones * supblk.s_zone_size).AppendLine(); sb.AppendFormat("First kernel zone: {0}", supblk.s_firstkernzone).AppendLine(); XmlFsType = new FileSystemType { Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(supblk.s_boot_segment), Clusters = supblk.s_nzones, ClusterSize = supblk.s_zone_size, Type = "Xia filesystem" }; information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = new Radix50(); information = ""; StringBuilder sb = new StringBuilder(); byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start); GCHandle handle = GCHandle.Alloc(hbSector, GCHandleType.Pinned); RT11HomeBlock homeblock = (RT11HomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(RT11HomeBlock)); handle.Free(); /* TODO: Is this correct? * Assembler: * MOV address, R0 * CLR R1 * MOV #255., R2 * 10$: ADD (R0)+, R1 * SOB R2, 10$ * MOV 1,@R0 */ ushort check = 0; for (int i = 0; i < 512; i += 2) { check += BitConverter.ToUInt16(hbSector, i); } sb.AppendFormat("Volume format is {0}", StringHandlers.SpacePaddedToString(homeblock.format, Encoding.ASCII)).AppendLine(); sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512) .AppendLine(); sb.AppendFormat("First directory segment starts at block {0}", homeblock.rootBlock).AppendLine(); sb.AppendFormat("Volume owner is \"{0}\"", Encoding.GetString(homeblock.ownername).TrimEnd()).AppendLine(); sb.AppendFormat("Volume label: \"{0}\"", Encoding.GetString(homeblock.volname).TrimEnd()).AppendLine(); sb.AppendFormat("Checksum: 0x{0:X4} (calculated 0x{1:X4})", homeblock.checksum, check).AppendLine(); byte[] bootBlock = imagePlugin.ReadSector(0); XmlFsType = new FileSystemType { Type = "RT-11", ClusterSize = homeblock.cluster * 512, Clusters = homeblock.cluster, VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding), Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock) }; information = sb.ToString(); }
public bool WriteSector(byte[] data, ulong sectorAddress) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length != _imageInfo.SectorSize) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress >= _imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } // Ignore empty sectors if (ArrayHelpers.ArrayIsNullOrEmpty(data)) { return(true); } ulong index = sectorAddress * _vHdr.sectorSize / _vHdr.blockSize; ulong secOff = sectorAddress * _vHdr.sectorSize % _vHdr.blockSize; uint ibmOff = _ibm[index]; if (ibmOff == VDI_EMPTY) { ibmOff = (_currentWritingPosition - _vHdr.offsetData) / _vHdr.blockSize; _ibm[index] = ibmOff; _currentWritingPosition += _vHdr.blockSize; _vHdr.allocatedBlocks++; } ulong imageOff = _vHdr.offsetData + (ibmOff * _vHdr.blockSize); _writingStream.Seek((long)imageOff, SeekOrigin.Begin); _writingStream.Seek((long)secOff, SeekOrigin.Current); _writingStream.Write(data, 0, data.Length); ErrorMessage = ""; return(true); }
public bool WriteSector(byte[] data, ulong sectorAddress) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length != 512) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress >= imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } // Ignore empty sectors if (ArrayHelpers.ArrayIsNullOrEmpty(data)) { return(true); } ulong index = sectorAddress / pHdr.cluster_size; ulong secOff = sectorAddress % pHdr.cluster_size; uint batOff = bat[index]; if (batOff == 0) { batOff = (uint)(currentWritingPosition / 512); bat[index] = batOff; currentWritingPosition += pHdr.cluster_size * 512; } ulong imageOff = batOff * 512; writingStream.Seek((long)imageOff, SeekOrigin.Begin); writingStream.Seek((long)secOff * 512, SeekOrigin.Current); writingStream.Write(data, 0, data.Length); ErrorMessage = ""; return(true); }
// TODO: This can be optimized public bool WriteSectors(byte[] data, ulong sectorAddress, uint length) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length % _imageInfo.SectorSize != 0) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress + length > _imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } // Ignore empty sectors if (ArrayHelpers.ArrayIsNullOrEmpty(data)) { return(true); } for (uint i = 0; i < length; i++) { byte[] tmp = new byte[_imageInfo.SectorSize]; Array.Copy(data, i * _imageInfo.SectorSize, tmp, 0, _imageInfo.SectorSize); if (!WriteSector(tmp, sectorAddress + i)) { return(false); } } ErrorMessage = ""; return(true); }
// TODO: Find root directory on volumes with DiscRecord // TODO: Support big directories (ADFS-G?) // TODO: Find the real freemap on volumes with DiscRecord, as DiscRecord's discid may be empty but this one isn't public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); StringBuilder sbInformation = new StringBuilder(); XmlFsType = new FileSystemType(); information = ""; ulong sbSector; byte[] sector; uint sectorsToRead; GCHandle ptr; ulong bytes; // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions if (partition.Start == 0) { sector = imagePlugin.ReadSector(0); byte oldChk0 = AcornMapChecksum(sector, 255); ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldMapSector0 oldMap0 = (OldMapSector0)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector0)); sector = imagePlugin.ReadSector(1); byte oldChk1 = AcornMapChecksum(sector, 255); ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldMapSector1 oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1)); // According to documentation map1 MUST start on sector 1. On ADFS-D it starts at 0x100, not on sector 1 (0x400) if (oldMap0.checksum == oldChk0 && oldMap1.checksum != oldChk1 && sector.Length >= 512) { sector = imagePlugin.ReadSector(0); byte[] tmp = new byte[256]; Array.Copy(sector, 256, tmp, 0, 256); oldChk1 = AcornMapChecksum(tmp, 255); ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned); oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1)); } if (oldMap0.checksum == oldChk0 && oldMap1.checksum == oldChk1 && oldMap0.checksum != 0 && oldMap1.checksum != 0) { bytes = (ulong)((oldMap0.size[2] << 16) + (oldMap0.size[1] << 8) + oldMap0.size[0]) * 256; byte[] namebytes = new byte[10]; for (int i = 0; i < 5; i++) { namebytes[i * 2] = oldMap0.name[i]; namebytes[i * 2 + 1] = oldMap1.name[i]; } XmlFsType = new FileSystemType { Bootable = oldMap1.boot != 0, // Or not? Clusters = (long)(bytes / imagePlugin.Info.SectorSize), ClusterSize = (int)imagePlugin.Info.SectorSize, Type = "Acorn Advanced Disc Filing System" }; if (ArrayHelpers.ArrayIsNullOrEmpty(namebytes)) { sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize; if (OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); if (sector.Length > OLD_DIRECTORY_SIZE) { byte[] tmp = new byte[OLD_DIRECTORY_SIZE]; Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53); Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53); sector = tmp; } ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldDirectory oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory)); if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC) { namebytes = oldRoot.tail.name; } else { // RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that... sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize; if (NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); if (sector.Length > OLD_DIRECTORY_SIZE) { byte[] tmp = new byte[OLD_DIRECTORY_SIZE]; Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53); Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53); sector = tmp; } ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory)); if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC) { namebytes = oldRoot.tail.name; } else { sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); if (sector.Length > NEW_DIRECTORY_SIZE) { byte[] tmp = new byte[NEW_DIRECTORY_SIZE]; Array.Copy(sector, 0, tmp, 0, NEW_DIRECTORY_SIZE - 41); Array.Copy(sector, sector.Length - 42, tmp, NEW_DIRECTORY_SIZE - 42, 41); sector = tmp; } ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); NewDirectory newRoot = (NewDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(NewDirectory)); if (newRoot.header.magic == NEW_DIR_MAGIC && newRoot.tail.magic == NEW_DIR_MAGIC) { namebytes = newRoot.tail.title; } } } } sbInformation.AppendLine("Acorn Advanced Disc Filing System"); sbInformation.AppendLine(); sbInformation.AppendFormat("{0} bytes per sector", imagePlugin.Info.SectorSize).AppendLine(); sbInformation.AppendFormat("Volume has {0} bytes", bytes).AppendLine(); sbInformation.AppendFormat("Volume name: {0}", StringHandlers.CToString(namebytes, Encoding)) .AppendLine(); if (oldMap1.discId > 0) { XmlFsType.VolumeSerial = $"{oldMap1.discId:X4}"; sbInformation.AppendFormat("Volume ID: {0:X4}", oldMap1.discId).AppendLine(); } if (!ArrayHelpers.ArrayIsNullOrEmpty(namebytes)) { XmlFsType.VolumeName = StringHandlers.CToString(namebytes, Encoding); } information = sbInformation.ToString(); return; } } // Partitioning or not, new formats follow: DiscRecord drSb; sector = imagePlugin.ReadSector(partition.Start); byte newChk = NewMapChecksum(sector); DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk); DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]); sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize; if (BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead); int bootChk = 0; for (int i = 0; i < 0x1FF; i++) { bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i]; } DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk); DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]); if (newChk == sector[0] && newChk != 0) { ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); NewMap nmap = (NewMap)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(NewMap)); ptr.Free(); drSb = nmap.discRecord; } else if (bootChk == bootSector[0x1FF]) { ptr = GCHandle.Alloc(bootSector, GCHandleType.Pinned); BootBlock bBlock = (BootBlock)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(BootBlock)); ptr.Free(); drSb = bBlock.discRecord; } else { return; } DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.spt = {0}", drSb.spt); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.heads = {0}", drSb.heads); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.density = {0}", drSb.density); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2bpmb = {0}", drSb.log2bpmb); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.skew = {0}", drSb.skew); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.bootoption = {0}", drSb.bootoption); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.lowsector = {0}", drSb.lowsector); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones = {0}", drSb.nzones); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.zone_spare = {0}", drSb.zone_spare); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root = {0}", drSb.root); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_id = {0}", drSb.disc_id); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_name = {0}", StringHandlers.CToString(drSb.disc_name, Encoding)); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_type = {0}", drSb.disc_type); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.flags = {0}", drSb.flags); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones_high = {0}", drSb.nzones_high); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.format_version = {0}", drSb.format_version); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root_size = {0}", drSb.root_size); if (drSb.log2secsize < 8 || drSb.log2secsize > 10) { return; } if (drSb.idlen < drSb.log2secsize + 3 || drSb.idlen > 19) { return; } if (drSb.disc_size_high >> drSb.log2secsize != 0) { return; } if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved)) { return; } bytes = drSb.disc_size_high; bytes *= 0x100000000; bytes += drSb.disc_size; ulong zones = drSb.nzones_high; zones *= 0x100000000; zones += drSb.nzones; if (bytes > imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize) { return; } XmlFsType = new FileSystemType(); sbInformation.AppendLine("Acorn Advanced Disc Filing System"); sbInformation.AppendLine(); sbInformation.AppendFormat("Version {0}", drSb.format_version).AppendLine(); sbInformation.AppendFormat("{0} bytes per sector", 1 << drSb.log2secsize).AppendLine(); sbInformation.AppendFormat("{0} sectors per track", drSb.spt).AppendLine(); sbInformation.AppendFormat("{0} heads", drSb.heads).AppendLine(); sbInformation.AppendFormat("Density code: {0}", drSb.density).AppendLine(); sbInformation.AppendFormat("Skew: {0}", drSb.skew).AppendLine(); sbInformation.AppendFormat("Boot option: {0}", drSb.bootoption).AppendLine(); // TODO: What the hell is this field refering to? sbInformation.AppendFormat("Root starts at frag {0}", drSb.root).AppendLine(); //sbInformation.AppendFormat("Root is {0} bytes long", drSb.root_size).AppendLine(); sbInformation.AppendFormat("Volume has {0} bytes in {1} zones", bytes, zones).AppendLine(); sbInformation.AppendFormat("Volume flags: 0x{0:X4}", drSb.flags).AppendLine(); if (drSb.disc_id > 0) { XmlFsType.VolumeSerial = $"{drSb.disc_id:X4}"; sbInformation.AppendFormat("Volume ID: {0:X4}", drSb.disc_id).AppendLine(); } if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.disc_name)) { string discname = StringHandlers.CToString(drSb.disc_name, Encoding); XmlFsType.VolumeName = discname; sbInformation.AppendFormat("Volume name: {0}", discname).AppendLine(); } information = sbInformation.ToString(); XmlFsType.Bootable |= drSb.bootoption != 0; // Or not? XmlFsType.Clusters = (long)(bytes / (ulong)(1 << drSb.log2secsize)); XmlFsType.ClusterSize = 1 << drSb.log2secsize; XmlFsType.Type = "Acorn Advanced Disc Filing System"; }
static void ReadBufferDma(string devPath, Device dev) { start: System.Console.Clear(); bool sense = dev.ReadBufferDma(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending READ BUFFER DMA to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Decode error registers."); AaruConsole.WriteLine("3.- Send command again."); AaruConsole.WriteLine("0.- Return to 28-bit ATA commands menu."); AaruConsole.Write("Choose: "); string strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out int item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to 28-bit ATA commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ BUFFER DMA response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ BUFFER DMA status registers:"); AaruConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: goto start; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = Encoding.UTF8; information = ""; uint sbSize = (uint)(Marshal.SizeOf <RefsVolumeHeader>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <RefsVolumeHeader>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } if (partition.Start + sbSize >= partition.End) { return; } byte[] sector = imagePlugin.ReadSectors(partition.Start, sbSize); if (sector.Length < Marshal.SizeOf <RefsVolumeHeader>()) { return; } RefsVolumeHeader refsVhdr = Marshal.ByteArrayToStructureLittleEndian <RefsVolumeHeader>(sector); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.jump empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.jump)); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.signature = {0}", StringHandlers.CToString(refsVhdr.signature)); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.mustBeZero empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero)); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.identifier = {0}", StringHandlers.CToString(BitConverter.GetBytes(refsVhdr.identifier))); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.length = {0}", refsVhdr.length); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.checksum = 0x{0:X4}", refsVhdr.checksum); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.sectors = {0}", refsVhdr.sectors); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.bytesPerSector = {0}", refsVhdr.bytesPerSector); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.sectorsPerCluster = {0}", refsVhdr.sectorsPerCluster); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown1 zero? = {0}", refsVhdr.unknown1 == 0); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown2 zero? = {0}", refsVhdr.unknown2 == 0); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown3 zero? = {0}", refsVhdr.unknown3 == 0); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown4 zero? = {0}", refsVhdr.unknown4 == 0); AaruConsole.DebugWriteLine("ReFS plugin", "VolumeHeader.unknown5 empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.unknown5)); if (refsVhdr.identifier != FSRS || !ArrayHelpers.ArrayIsNullOrEmpty(refsVhdr.mustBeZero) || !refsVhdr.signature.SequenceEqual(refsSignature)) { return; } var sb = new StringBuilder(); sb.AppendLine("Microsoft Resilient File System"); sb.AppendFormat("Volume uses {0} bytes per sector", refsVhdr.bytesPerSector).AppendLine(); sb.AppendFormat("Volume uses {0} sectors per cluster ({1} bytes)", refsVhdr.sectorsPerCluster, refsVhdr.sectorsPerCluster * refsVhdr.bytesPerSector).AppendLine(); sb.AppendFormat("Volume has {0} sectors ({1} bytes)", refsVhdr.sectors, refsVhdr.sectors * refsVhdr.bytesPerSector).AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "Resilient File System", ClusterSize = refsVhdr.bytesPerSector * refsVhdr.sectorsPerCluster, Clusters = refsVhdr.sectors / refsVhdr.sectorsPerCluster }; }
static void ReadCdDa(string devPath, Device dev) { uint address = 0; uint length = 1; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for READ CD-DA command:"); AaruConsole.WriteLine("LBA: {0}", address); AaruConsole.WriteLine("Will transfer {0} sectors", length); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to NEC vendor commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to NEC vendor commands menu..."); return; case 1: AaruConsole.Write("Logical Block Address?: "); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out address)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); address = 0; System.Console.ReadKey(); continue; } AaruConsole.Write("How many sectors to transfer?: "); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out length)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); length = 1; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.NecReadCdDa(out byte[] buffer, out byte[] senseBuffer, address, length, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending READ CD-DA to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Print sense buffer."); AaruConsole.WriteLine("3.- Decode sense buffer."); AaruConsole.WriteLine("4.- Send command again."); AaruConsole.WriteLine("5.- Change parameters."); AaruConsole.WriteLine("0.- Return to NEC vendor commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to NEC vendor commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ CD-DA response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ CD-DA sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ CD-DA decoded sense:"); AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; case 5: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding, Dictionary <string, string> options, string @namespace) { device = imagePlugin; Encoding = encoding ?? new Apple2(); if (options == null) { options = GetDefaultOptions(); } if (options.TryGetValue("debug", out string debugString)) { bool.TryParse(debugString, out debug); } if (device.Info.Sectors < 3) { return(Errno.InvalidArgument); } multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1); // Blocks 0 and 1 are boot code catalogBlocks = device.ReadSectors(multiplier * 2, multiplier); // On Apple //, it's little endian // TODO: Fix //BigEndianBitConverter.IsLittleEndian = // multiplier == 2 ? !BitConverter.IsLittleEndian : BitConverter.IsLittleEndian; mountedVolEntry.FirstBlock = BigEndianBitConverter.ToInt16(catalogBlocks, 0x00); mountedVolEntry.LastBlock = BigEndianBitConverter.ToInt16(catalogBlocks, 0x02); mountedVolEntry.EntryType = (PascalFileKind)BigEndianBitConverter.ToInt16(catalogBlocks, 0x04); mountedVolEntry.VolumeName = new byte[8]; Array.Copy(catalogBlocks, 0x06, mountedVolEntry.VolumeName, 0, 8); mountedVolEntry.Blocks = BigEndianBitConverter.ToInt16(catalogBlocks, 0x0E); mountedVolEntry.Files = BigEndianBitConverter.ToInt16(catalogBlocks, 0x10); mountedVolEntry.Dummy = BigEndianBitConverter.ToInt16(catalogBlocks, 0x12); mountedVolEntry.LastBoot = BigEndianBitConverter.ToInt16(catalogBlocks, 0x14); mountedVolEntry.Tail = BigEndianBitConverter.ToInt32(catalogBlocks, 0x16); if (mountedVolEntry.FirstBlock != 0 || mountedVolEntry.LastBlock <= mountedVolEntry.FirstBlock || (ulong)mountedVolEntry.LastBlock > (device.Info.Sectors / multiplier) - 2 || (mountedVolEntry.EntryType != PascalFileKind.Volume && mountedVolEntry.EntryType != PascalFileKind.Secure) || mountedVolEntry.VolumeName[0] > 7 || mountedVolEntry.Blocks < 0 || (ulong)mountedVolEntry.Blocks != device.Info.Sectors / multiplier || mountedVolEntry.Files < 0) { return(Errno.InvalidArgument); } catalogBlocks = device.ReadSectors(multiplier * 2, (uint)(mountedVolEntry.LastBlock - mountedVolEntry.FirstBlock - 2) * multiplier); int offset = 26; fileEntries = new List <PascalFileEntry>(); while (offset + 26 < catalogBlocks.Length) { var entry = new PascalFileEntry { Filename = new byte[16], FirstBlock = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x00), LastBlock = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x02), EntryType = (PascalFileKind)BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x04), LastBytes = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x16), ModificationTime = BigEndianBitConverter.ToInt16(catalogBlocks, offset + 0x18) }; Array.Copy(catalogBlocks, offset + 0x06, entry.Filename, 0, 16); if (entry.Filename[0] <= 15 && entry.Filename[0] > 0) { fileEntries.Add(entry); } offset += 26; } bootBlocks = device.ReadSectors(0, 2 * multiplier); XmlFsType = new FileSystemType { Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlocks), Clusters = (ulong)mountedVolEntry.Blocks, ClusterSize = device.Info.SectorSize, Files = (ulong)mountedVolEntry.Files, FilesSpecified = true, Type = "UCSD Pascal", VolumeName = StringHandlers.PascalToString(mountedVolEntry.VolumeName, Encoding) }; mounted = true; return(Errno.NoError); }
static void Unlock(string devPath, Device dev) { start: System.Console.Clear(); bool sense = dev.KreonDeprecatedUnlock(out byte[] senseBuffer, dev.Timeout, out double duration); menu: DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("Sending UNLOCK to the device:"); DicConsole.WriteLine("Command took {0} ms.", duration); DicConsole.WriteLine("Sense is {0}.", sense); DicConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); DicConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); DicConsole.WriteLine("UNLOCK decoded sense:"); DicConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); DicConsole.WriteLine(); DicConsole.WriteLine("Choose what to do:"); DicConsole.WriteLine("1.- Print sense buffer."); DicConsole.WriteLine("2.- Send command again."); DicConsole.WriteLine("0.- Return to Kreon vendor commands menu."); DicConsole.Write("Choose: "); string strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out int item)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: DicConsole.WriteLine("Returning to Kreon vendor commands menu..."); return; case 1: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("UNLOCK sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: goto start; default: DicConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset) { partitions = new List <Partition>(); // I think Apricot can't chain partitions so. if (sectorOffset != 0) { return(false); } byte[] sector = imagePlugin.ReadSector(0); if (sector.Length < 512) { return(false); } Label label = Marshal.ByteArrayToStructureLittleEndian <Label>(sector); // Not much to check but... ulong deviceSectors = imagePlugin.Info.Sectors; ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt; if (label.operatingSystem > 4 || label.bootType > 5 || label.partitionCount > 8 || deviceSizeAccordingToLabel > deviceSectors || label.firstDataBlock > deviceSectors) { return(false); } AaruConsole.DebugWriteLine("Apricot partitions", "label.version = \"{0}\"", StringHandlers.CToString(label.version)); AaruConsole.DebugWriteLine("Apricot partitions", "label.operatingSystem = {0} ({1})", label.operatingSystem, label.operatingSystem < _operatingSystemCodes.Length ? _operatingSystemCodes[label.operatingSystem] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.writeProtected = {0}", label.writeProtected); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyProtected = {0}", label.copyProtected); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootType = {0} ({1})", label.bootType, label.bootType < _bootTypeCodes.Length ? _bootTypeCodes[label.bootType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitionCount = {0}", label.partitionCount); AaruConsole.DebugWriteLine("Apricot partitions", "label.winchester = {0}", label.winchester); AaruConsole.DebugWriteLine("Apricot partitions", "label.sectorSize = {0}", label.sectorSize); AaruConsole.DebugWriteLine("Apricot partitions", "label.spt = {0}", label.spt); AaruConsole.DebugWriteLine("Apricot partitions", "label.cylinders = {0}", label.cylinders); AaruConsole.DebugWriteLine("Apricot partitions", "label.heads = {0}", label.heads); AaruConsole.DebugWriteLine("Apricot partitions", "label.interleave = {0}", label.interleave); AaruConsole.DebugWriteLine("Apricot partitions", "label.skew = {0}", label.skew); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootLocation = {0}", label.bootLocation); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootSize = {0}", label.bootSize); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootAddress = 0x{0:X8}", label.bootAddress); AaruConsole.DebugWriteLine("Apricot partitions", "label.bootOffset:label.bootSegment = {0:X4}:{1:X4}", label.bootOffset, label.bootSegment); AaruConsole.DebugWriteLine("Apricot partitions", "label.firstDataBlock = {0}", label.firstDataBlock); AaruConsole.DebugWriteLine("Apricot partitions", "label.generation = {0}", label.generation); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyCount = {0}", label.copyCount); AaruConsole.DebugWriteLine("Apricot partitions", "label.maxCopies = {0}", label.maxCopies); AaruConsole.DebugWriteLine("Apricot partitions", "label.serialNumber = \"{0}\"", StringHandlers.CToString(label.serialNumber)); AaruConsole.DebugWriteLine("Apricot partitions", "label.partNumber = \"{0}\"", StringHandlers.CToString(label.partNumber)); AaruConsole.DebugWriteLine("Apricot partitions", "label.copyright = \"{0}\"", StringHandlers.CToString(label.copyright)); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.bps = {0}", label.mainBPB.bps); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spc = {0}", label.mainBPB.spc); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.sectors = {0}", label.mainBPB.sectors); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.media = {0}", label.mainBPB.media); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.spfat = {0}", label.mainBPB.spfat); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.diskType = {0} ({1})", label.mainBPB.diskType, label.mainBPB.diskType < _diskTypeCodes.Length ? _diskTypeCodes[label.mainBPB.diskType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.mainBPB.startSector = {0}", label.mainBPB.startSector); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontName = \"{0}\"", StringHandlers.CToString(label.fontName)); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardName = \"{0}\"", StringHandlers.CToString(label.keyboardName)); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMajorVersion = {0}", label.biosMajorVersion); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosMinorVersion = {0}", label.biosMinorVersion); AaruConsole.DebugWriteLine("Apricot partitions", "label.diagnosticsFlag = {0}", label.diagnosticsFlag); AaruConsole.DebugWriteLine("Apricot partitions", "label.prnDevice = {0} ({1})", label.prnDevice, label.prnDevice < _printDevices.Length ? _printDevices[label.prnDevice] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.bellVolume = {0}", label.bellVolume); AaruConsole.DebugWriteLine("Apricot partitions", "label.enableCache = {0}", label.enableCache); AaruConsole.DebugWriteLine("Apricot partitions", "label.enableGraphics = {0}", label.enableGraphics); AaruConsole.DebugWriteLine("Apricot partitions", "label.dosLength = {0}", label.dosLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontLength = {0}", label.fontLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardLength = {0}", label.keyboardLength); AaruConsole.DebugWriteLine("Apricot partitions", "label.dosStart = {0}", label.dosStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.fontStart = {0}", label.fontStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardStart = {0}", label.keyboardStart); AaruConsole.DebugWriteLine("Apricot partitions", "label.keyboardVolume = {0}", label.keyboardVolume); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeat = {0}", label.autorepeat); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn); AaruConsole.DebugWriteLine("Apricot partitions", "label.autorepeatInterval = {0}", label.autorepeatInterval); AaruConsole.DebugWriteLine("Apricot partitions", "label.microscreenMode = {0}", label.microscreenMode); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareKeyboard is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard)); AaruConsole.DebugWriteLine("Apricot partitions", "label.lineMode = {0} ({1} lines)", label.lineMode, label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.lineWidth = {0} ({1} columns)", label.lineWidth, label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.imageOff = {0}", label.imageOff); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareScreen is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen)); AaruConsole.DebugWriteLine("Apricot partitions", "label.txBaudRate = {0} ({1} bps)", label.txBaudRate, label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBaudRate = {0} ({1} bps)", label.rxBaudRate, label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.txBits = {0}", label.txBits); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxBits = {0}", label.rxBits); AaruConsole.DebugWriteLine("Apricot partitions", "label.stopBits = {0} ({1} bits)", label.stopBits, label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0); AaruConsole.DebugWriteLine("Apricot partitions", "label.parityCheck = {0}", label.parityCheck); AaruConsole.DebugWriteLine("Apricot partitions", "label.parityType = {0} ({1})", label.parityType, label.parityType < _parityTypes.Length ? _parityTypes[label.parityType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.txXonXoff = {0}", label.txXonXoff); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoff = {0}", label.rxXonXoff); AaruConsole.DebugWriteLine("Apricot partitions", "label.xonCharacter = {0}", label.xonCharacter); AaruConsole.DebugWriteLine("Apricot partitions", "label.xoffCharacter = {0}", label.xoffCharacter); AaruConsole.DebugWriteLine("Apricot partitions", "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer); AaruConsole.DebugWriteLine("Apricot partitions", "label.dtrDsr = {0}", label.dtrDsr); AaruConsole.DebugWriteLine("Apricot partitions", "label.ctsRts = {0}", label.ctsRts); AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterCr = {0}", label.nullsAfterCr); AaruConsole.DebugWriteLine("Apricot partitions", "label.nullsAfterFF = {0}", label.nullsAfterFF); AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportSerial = {0}", label.biosErrorReportSerial); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareSerial is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial)); AaruConsole.DebugWriteLine("Apricot partitions", "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel); AaruConsole.DebugWriteLine("Apricot partitions", "label.selectLine = {0}", label.selectLine); AaruConsole.DebugWriteLine("Apricot partitions", "label.paperEmpty = {0}", label.paperEmpty); AaruConsole.DebugWriteLine("Apricot partitions", "label.faultLine = {0}", label.faultLine); AaruConsole.DebugWriteLine("Apricot partitions", "label.biosErrorReportParallel = {0}", label.biosErrorReportParallel); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareParallel is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel)); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareWinchester is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester)); AaruConsole.DebugWriteLine("Apricot partitions", "label.parkingEnabled = {0}", label.parkingEnabled); AaruConsole.DebugWriteLine("Apricot partitions", "label.formatProtection = {0}", label.formatProtection); AaruConsole.DebugWriteLine("Apricot partitions", "label.spareRamDisk is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk)); for (int i = 0; i < 32; i++) { AaruConsole.DebugWriteLine("Apricot partitions", "label.badBlocks[{1}] = {0}", label.badBlocks[i], i); } for (int i = 0; i < 8; i++) { AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].bps = {0}", label.partitions[i].bps, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spc = {0}", label.partitions[i].spc, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].rsectors = {0}", label.partitions[i].rsectors, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].fats_no = {0}", label.partitions[i].fats_no, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].root_ent = {0}", label.partitions[i].root_ent, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].sectors = {0}", label.partitions[i].sectors, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].media = {0}", label.partitions[i].media, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].spfat = {0}", label.partitions[i].spfat, i); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].diskType = {0} ({2})", label.partitions[i].diskType, i, label.partitions[i].diskType < _diskTypeCodes.Length ? _diskTypeCodes[label.partitions[i].diskType] : "Unknown"); AaruConsole.DebugWriteLine("Apricot partitions", "label.partitions[{1}].startSector = {0}", label.partitions[i].startSector, i); } AaruConsole.DebugWriteLine("Apricot partitions", "label.spare is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spare)); AaruConsole.DebugWriteLine("Apricot partitions", "label.cpmDoubleSided = {0}", label.cpmDoubleSided); // Only hard disks can contain partitions if (!label.winchester) { return(false); } for (byte i = 0; i < label.partitionCount; i++) { var part = new Partition { Start = label.partitions[i].startSector, Size = (ulong)(label.partitions[i].sectors * label.sectorSize), Length = label.partitions[i].sectors, Type = "ACT Apricot partition", Sequence = i, Scheme = Name, Offset = (ulong)(label.partitions[i].startSector * label.sectorSize) }; if (part.Start < deviceSectors && part.End < deviceSectors) { partitions.Add(part); } } return(partitions.Count > 0); }
/// <summary> /// Lists special Apple Lisa filesystem features as extended attributes /// </summary> /// <returns>Error number.</returns> /// <param name="fileId">File identifier.</param> /// <param name="xattrs">Extended attributes.</param> Errno ListXAttr(short fileId, out List <string> xattrs) { xattrs = null; if (!mounted) { return(Errno.AccessDenied); } // System files if (fileId < 4) { if (!debug || fileId == 0) { return(Errno.InvalidArgument); } xattrs = new List <string>(); // Only MDDF contains an extended attributes if (fileId == FILEID_MDDF) { byte[] buf = Encoding.ASCII.GetBytes(mddf.password); // If the MDDF contains a password, show it if (buf.Length > 0) { xattrs.Add("com.apple.lisa.password"); } } } else { // Search for the file Errno error = ReadExtentsFile(fileId, out ExtentFile file); if (error != Errno.NoError) { return(error); } xattrs = new List <string>(); // Password field is never emptied, check if valid if (file.password_valid > 0) { xattrs.Add("com.apple.lisa.password"); } // Check for a valid copy-protection serial number if (file.serial > 0) { xattrs.Add("com.apple.lisa.serial"); } // Check if the label contains something or is empty if (!ArrayHelpers.ArrayIsNullOrEmpty(file.LisaInfo)) { xattrs.Add("com.apple.lisa.label"); } } // On debug mode allow sector tags to be accessed as an xattr if (debug) { xattrs.Add("com.apple.lisa.tags"); } xattrs.Sort(); return(Errno.NoError); }
public Errno ListXAttr(string path, out List <string> xattrs) { xattrs = null; if (!mounted) { return(Errno.AccessDenied); } string[] pathElements = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (pathElements.Length != 1) { return(Errno.NotSupported); } path = pathElements[0]; xattrs = new List <string>(); if (debug) { if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0) { if (device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag)) { xattrs.Add("com.apple.macintosh.tags"); } return(Errno.NoError); } } if (!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId)) { return(Errno.NoSuchFile); } if (!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry)) { return(Errno.NoSuchFile); } if (entry.flRLgLen > 0) { xattrs.Add("com.apple.ResourceFork"); if (debug && device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag)) { xattrs.Add("com.apple.ResourceFork.tags"); } } if (!ArrayHelpers.ArrayIsNullOrEmpty(entry.flUsrWds)) { xattrs.Add("com.apple.FinderInfo"); } if (debug && device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) && entry.flLgLen > 0) { xattrs.Add("com.apple.macintosh.tags"); } xattrs.Sort(); return(Errno.NoError); }
static void RequestBlockAddress(string devPath, Device dev) { uint lba = 0; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for REQUEST BLOCK ADDRESS command:"); AaruConsole.WriteLine("LBA: {0}", lba); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to Archive vendor commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Archive vendor commands menu..."); return; case 1: AaruConsole.Write("LBA?: "); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out lba)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); lba = 0; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.ArchiveCorpRequestBlockAddress(out byte[] buffer, out byte[] senseBuffer, lba, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending REQUEST BLOCK ADDRESS to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Print sense buffer."); AaruConsole.WriteLine("3.- Decode sense buffer."); AaruConsole.WriteLine("4.- Send command again."); AaruConsole.WriteLine("5.- Change parameters."); AaruConsole.WriteLine("0.- Return to Archive vendor commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Archive vendor commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("REQUEST BLOCK ADDRESS response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("REQUEST BLOCK ADDRESS sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("REQUEST BLOCK ADDRESS decoded sense:"); AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; case 5: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
static void Read(string devPath, Device dev, bool multiple) { uint address = 0; uint blockSize = 512; uint count = 1; bool byteAddr = false; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for READ_{0}_BLOCK command:", multiple ? "MULTIPLE" : "SINGLE"); AaruConsole.WriteLine("Read from {1}: {0}", address, byteAddr ? "byte" : "block"); AaruConsole.WriteLine("Expected block size: {0} bytes", blockSize); if (multiple) { AaruConsole.WriteLine("Will read {0} blocks", count); } AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to SecureDigital commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to SecureDigital commands menu..."); return; case 1: AaruConsole.Write("Use byte addressing?: "); strDev = System.Console.ReadLine(); if (!bool.TryParse(strDev, out byteAddr)) { AaruConsole.WriteLine("Not a boolean. Press any key to continue..."); byteAddr = false; System.Console.ReadKey(); continue; } AaruConsole.Write("Read from {0}?: ", byteAddr ? "byte" : "block"); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out address)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); address = 0; System.Console.ReadKey(); continue; } if (multiple) { AaruConsole.Write("How many blocks to read?"); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out count)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); count = 1; System.Console.ReadKey(); continue; } } AaruConsole.Write("How many bytes to expect in a block?"); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out blockSize)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); blockSize = 512; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.Read(out byte[] buffer, out uint[] response, address, blockSize, multiple ? count : 1, byteAddr, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending READ_{0}_BLOCK to the device:", multiple ? "MULTIPLE" : "SINGLE"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Response has {0} elements.", response?.Length.ToString() ?? "null"); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Print response buffer."); AaruConsole.WriteLine("3.- Send command again."); AaruConsole.WriteLine("4.- Change parameters."); AaruConsole.WriteLine("0.- Return to SecureDigital commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to SecureDigital commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ_{0}_BLOCK buffer:", multiple ? "MULTIPLE" : "SINGLE"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ_{0}_BLOCK response:", multiple ? "MULTIPLE" : "SINGLE"); if (response != null) { foreach (uint res in response) { AaruConsole.Write("0x{0:x8} ", res); } AaruConsole.WriteLine(); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: goto start; case 4: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
static void ExtractSecuritySectors(string devPath, Device dev) { byte requestNumber = 0; string strDev; int item; parameters: while (true) { System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("Parameters for EXTRACT SS command:"); DicConsole.WriteLine("Request number: {0}", requestNumber); DicConsole.WriteLine(); DicConsole.WriteLine("Choose what to do:"); DicConsole.WriteLine("1.- Change parameters."); DicConsole.WriteLine("2.- Send command with these parameters."); DicConsole.WriteLine("0.- Return to Kreon vendor commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: DicConsole.WriteLine("Returning to Kreon vendor commands menu..."); return; case 1: DicConsole.Write("Request number?: "); strDev = System.Console.ReadLine(); if (!byte.TryParse(strDev, out requestNumber)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); requestNumber = 0; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.KreonExtractSs(out byte[] buffer, out byte[] senseBuffer, dev.Timeout, out double duration, requestNumber); menu: DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("Sending EXTRACT SS to the device:"); DicConsole.WriteLine("Command took {0} ms.", duration); DicConsole.WriteLine("Sense is {0}.", sense); DicConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); DicConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); DicConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); DicConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); DicConsole.WriteLine(); DicConsole.WriteLine("Choose what to do:"); DicConsole.WriteLine("1.- Print buffer."); DicConsole.WriteLine("2.- Print sense buffer."); DicConsole.WriteLine("3.- Decode sense buffer."); DicConsole.WriteLine("4.- Send command again."); DicConsole.WriteLine("5.- Change parameters."); DicConsole.WriteLine("0.- Return to Kreon vendor commands menu."); DicConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: DicConsole.WriteLine("Returning to Kreon vendor commands menu..."); return; case 1: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("EXTRACT SS response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("EXTRACT SS sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("EXTRACT SS decoded sense:"); DicConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; case 5: goto parameters; default: DicConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
static void SendScr(string devPath, Device dev) { start: System.Console.Clear(); bool sense = dev.ReadScr(out byte[] buffer, out uint[] response, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending SEND_SCR to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Response has {0} elements.", response?.Length.ToString() ?? "null"); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Decode buffer."); AaruConsole.WriteLine("3.- Print response buffer."); AaruConsole.WriteLine("4.- Send command again."); AaruConsole.WriteLine("0.- Return to SecureDigital commands menu."); AaruConsole.Write("Choose: "); string strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out int item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to SecureDigital commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("SEND_SCR buffer:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("SEND_SCR decoded buffer:"); if (buffer != null) { AaruConsole.WriteLine("{0}", Decoders.SecureDigital.Decoders.PrettifySCR(buffer)); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("SEND_SCR response:"); if (response != null) { foreach (uint res in response) { AaruConsole.Write("0x{0:x8} ", res); } AaruConsole.WriteLine(); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
// TODO: BBC Master hard disks are untested... public bool Identify(IMediaImage imagePlugin, Partition partition) { if (partition.Start >= partition.End) { return(false); } ulong sbSector; uint sectorsToRead; if (imagePlugin.Info.SectorSize < 256) { return(false); } byte[] sector; GCHandle ptr; // ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions if (partition.Start == 0) { sector = imagePlugin.ReadSector(0); byte oldChk0 = AcornMapChecksum(sector, 255); ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldMapSector0 oldMap0 = (OldMapSector0)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector0)); sector = imagePlugin.ReadSector(1); byte oldChk1 = AcornMapChecksum(sector, 255); ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldMapSector1 oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1)); DicConsole.DebugWriteLine("ADFS Plugin", "oldMap0.checksum = {0}", oldMap0.checksum); DicConsole.DebugWriteLine("ADFS Plugin", "oldChk0 = {0}", oldChk0); // According to documentation map1 MUST start on sector 1. On ADFS-D it starts at 0x100, not on sector 1 (0x400) if (oldMap0.checksum == oldChk0 && oldMap1.checksum != oldChk1 && sector.Length >= 512) { sector = imagePlugin.ReadSector(0); byte[] tmp = new byte[256]; Array.Copy(sector, 256, tmp, 0, 256); oldChk1 = AcornMapChecksum(tmp, 255); ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned); oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1)); } DicConsole.DebugWriteLine("ADFS Plugin", "oldMap1.checksum = {0}", oldMap1.checksum); DicConsole.DebugWriteLine("ADFS Plugin", "oldChk1 = {0}", oldChk1); if (oldMap0.checksum == oldChk0 && oldMap1.checksum == oldChk1 && oldMap0.checksum != 0 && oldMap1.checksum != 0) { sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize; if (OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); if (sector.Length > OLD_DIRECTORY_SIZE) { byte[] tmp = new byte[OLD_DIRECTORY_SIZE]; Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53); Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53); sector = tmp; } ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); OldDirectory oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory)); byte dirChk = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.header.magic at 0x200 = {0}", oldRoot.header.magic); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.magic at 0x200 = {0}", oldRoot.tail.magic); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.checkByte at 0x200 = {0}", oldRoot.tail.checkByte); DicConsole.DebugWriteLine("ADFS Plugin", "dirChk at 0x200 = {0}", dirChk); if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC || oldRoot.header.magic == NEW_DIR_MAGIC && oldRoot.tail.magic == NEW_DIR_MAGIC) { return(true); } // RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that... sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize; if (NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } sector = imagePlugin.ReadSectors(sbSector, sectorsToRead); if (sector.Length > OLD_DIRECTORY_SIZE) { byte[] tmp = new byte[OLD_DIRECTORY_SIZE]; Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53); Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53); sector = tmp; } ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory)); dirChk = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.header.magic at 0x400 = {0}", oldRoot.header.magic); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.magic at 0x400 = {0}", oldRoot.tail.magic); DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.tail.checkByte at 0x400 = {0}", oldRoot.tail.checkByte); DicConsole.DebugWriteLine("ADFS Plugin", "dirChk at 0x400 = {0}", dirChk); if (oldRoot.header.magic == OLD_DIR_MAGIC && oldRoot.tail.magic == OLD_DIR_MAGIC || oldRoot.header.magic == NEW_DIR_MAGIC && oldRoot.tail.magic == NEW_DIR_MAGIC) { return(true); } } } // Partitioning or not, new formats follow: DiscRecord drSb; sector = imagePlugin.ReadSector(partition.Start); byte newChk = NewMapChecksum(sector); DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk); DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]); sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize; sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize; if (BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) { sectorsToRead++; } if (sbSector + partition.Start + sectorsToRead >= partition.End) { return(false); } byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead); int bootChk = 0; for (int i = 0; i < 0x1FF; i++) { bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i]; } DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk); DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]); if (newChk == sector[0] && newChk != 0) { ptr = GCHandle.Alloc(sector, GCHandleType.Pinned); NewMap nmap = (NewMap)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(NewMap)); ptr.Free(); drSb = nmap.discRecord; } else if (bootChk == bootSector[0x1FF]) { ptr = GCHandle.Alloc(bootSector, GCHandleType.Pinned); BootBlock bBlock = (BootBlock)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(BootBlock)); ptr.Free(); drSb = bBlock.discRecord; } else { return(false); } DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high); DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size); DicConsole.DebugWriteLine("ADFS Plugin", "IsNullOrEmpty(drSb.reserved) = {0}", ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved)); if (drSb.log2secsize < 8 || drSb.log2secsize > 10) { return(false); } if (drSb.idlen < drSb.log2secsize + 3 || drSb.idlen > 19) { return(false); } if (drSb.disc_size_high >> drSb.log2secsize != 0) { return(false); } if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved)) { return(false); } ulong bytes = drSb.disc_size_high; bytes *= 0x100000000; bytes += drSb.disc_size; return(bytes <= imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize); }
public Errno GetXattr(string path, string xattr, ref byte[] buf) { if (!mounted) { return(Errno.AccessDenied); } string[] pathElements = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (pathElements.Length != 1) { return(Errno.NotSupported); } path = pathElements[0]; if (debug) { if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 || string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0) { if (device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) && string.Compare(xattr, "com.apple.macintosh.tags", StringComparison.InvariantCulture) == 0) { if (string.Compare(path, "$", StringComparison.InvariantCulture) == 0) { buf = new byte[directoryTags.Length]; Array.Copy(directoryTags, 0, buf, 0, buf.Length); return(Errno.NoError); } if (string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0) { buf = new byte[bitmapTags.Length]; Array.Copy(bitmapTags, 0, buf, 0, buf.Length); return(Errno.NoError); } if (string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0) { buf = new byte[bootTags.Length]; Array.Copy(bootTags, 0, buf, 0, buf.Length); return(Errno.NoError); } if (string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0) { buf = new byte[mdbTags.Length]; Array.Copy(mdbTags, 0, buf, 0, buf.Length); return(Errno.NoError); } } else { return(Errno.NoSuchExtendedAttribute); } } } Errno error; if (!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId)) { return(Errno.NoSuchFile); } if (!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry)) { return(Errno.NoSuchFile); } if (entry.flRLgLen > 0 && string.Compare(xattr, "com.apple.ResourceFork", StringComparison.InvariantCulture) == 0) { error = ReadFile(path, out buf, true, false); return(error); } if (entry.flRLgLen > 0 && string.Compare(xattr, "com.apple.ResourceFork.tags", StringComparison.InvariantCulture) == 0) { error = ReadFile(path, out buf, true, true); return(error); } if (!ArrayHelpers.ArrayIsNullOrEmpty(entry.flUsrWds) && string.Compare(xattr, "com.apple.FinderInfo", StringComparison.InvariantCulture) == 0) { buf = new byte[16]; Array.Copy(entry.flUsrWds, 0, buf, 0, 16); return(Errno.NoError); } if (!debug || !device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) || string.Compare(xattr, "com.apple.macintosh.tags", StringComparison.InvariantCulture) != 0) { return(Errno.NoSuchExtendedAttribute); } error = ReadFile(path, out buf, false, true); return(error); }
static void ReadLog(string devPath, Device dev) { byte address = 0; string strDev; int item; parameters: while (true) { System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("Parameters for READ LOG command:"); DicConsole.WriteLine("Log address: {0}", address); DicConsole.WriteLine(); DicConsole.WriteLine("Choose what to do:"); DicConsole.WriteLine("1.- Change parameters."); DicConsole.WriteLine("2.- Send command with these parameters."); DicConsole.WriteLine("0.- Return to S.M.A.R.T. commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: DicConsole.WriteLine("Returning to S.M.A.R.T. commands menu..."); return; case 1: DicConsole.Write("Log address?: "); strDev = System.Console.ReadLine(); if (!byte.TryParse(strDev, out address)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); address = 0; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.SmartReadLog(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, address, dev.Timeout, out double duration); menu: DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("Sending READ LOG to the device:"); DicConsole.WriteLine("Command took {0} ms.", duration); DicConsole.WriteLine("Sense is {0}.", sense); DicConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); DicConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); DicConsole.WriteLine(); DicConsole.WriteLine("Choose what to do:"); DicConsole.WriteLine("1.- Print buffer."); DicConsole.WriteLine("2.- Decode error registers."); DicConsole.WriteLine("3.- Send command again."); DicConsole.WriteLine("4.- Change parameters."); DicConsole.WriteLine("0.- Return to S.M.A.R.T. commands menu."); DicConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { DicConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: DicConsole.WriteLine("Returning to S.M.A.R.T. commands menu..."); return; case 1: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("READ LOG response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); DicConsole.WriteLine("READ LOG status registers:"); DicConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters)); DicConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); DicConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: goto start; case 4: goto parameters; default: DicConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
/// <summary> /// Lists special Apple Lisa filesystem features as extended attributes /// </summary> /// <returns>Error number.</returns> /// <param name="fileId">File identifier.</param> /// <param name="xattr">Extended attribute name.</param> /// <param name="buf">Buffer where the extended attribute will be stored.</param> Errno GetXattr(short fileId, string xattr, out byte[] buf) { buf = null; if (!mounted) { return(Errno.AccessDenied); } // System files if (fileId < 4) { if (!debug || fileId == 0) { return(Errno.InvalidArgument); } // Only MDDF contains an extended attributes if (fileId == FILEID_MDDF) { if (xattr == "com.apple.lisa.password") { buf = Encoding.ASCII.GetBytes(mddf.password); return(Errno.NoError); } } // But on debug mode even system files contain tags if (debug && xattr == "com.apple.lisa.tags") { return(ReadSystemFile(fileId, out buf, true)); } return(Errno.NoSuchExtendedAttribute); } // Search for the file Errno error = ReadExtentsFile(fileId, out ExtentFile file); if (error != Errno.NoError) { return(error); } switch (xattr) { case "com.apple.lisa.password" when file.password_valid > 0: buf = new byte[8]; Array.Copy(file.password, 0, buf, 0, 8); return(Errno.NoError); case "com.apple.lisa.serial" when file.serial > 0: buf = Encoding.ASCII.GetBytes(file.serial.ToString()); return(Errno.NoError); } if (!ArrayHelpers.ArrayIsNullOrEmpty(file.LisaInfo) && xattr == "com.apple.lisa.label") { buf = new byte[128]; Array.Copy(file.LisaInfo, 0, buf, 0, 128); return(Errno.NoError); } if (debug && xattr == "com.apple.lisa.tags") { return(ReadFile(fileId, out buf, true)); } return(Errno.NoSuchExtendedAttribute); }
static void ReadSectorLocation(string devPath, Device dev) { uint address = 0; bool physical = false; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for READ SECTOR LOCATION command:"); AaruConsole.WriteLine("{0} Block Address: {1}", physical ? "Physical" : "Logical", address); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Plasmon vendor commands menu..."); return; case 1: AaruConsole.Write("Physical address?: "); strDev = System.Console.ReadLine(); if (!bool.TryParse(strDev, out physical)) { AaruConsole.WriteLine("Not a boolean. Press any key to continue..."); physical = false; System.Console.ReadKey(); continue; } AaruConsole.Write("{0} Block Address?: ", physical ? "Physical" : "Logical"); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out address)) { AaruConsole.WriteLine("Not a numbr. Press any key to continue..."); address = 0; System.Console.ReadKey(); } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.PlasmonReadSectorLocation(out byte[] buffer, out byte[] senseBuffer, address, physical, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending READ SECTOR LOCATION to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Print sense buffer."); AaruConsole.WriteLine("3.- Decode sense buffer."); AaruConsole.WriteLine("4.- Send command again."); AaruConsole.WriteLine("5.- Change parameters."); AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Plasmon vendor commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ SECTOR LOCATION response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ SECTOR LOCATION sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ SECTOR LOCATION decoded sense:"); AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; case 5: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
static void TranslateSectorLba(string devPath, Device dev) { uint lba = 0; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for TRANSLATE SECTOR command:"); AaruConsole.WriteLine("LBA: {0}", lba); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to CompactFlash commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to CompactFlash commands menu..."); return; case 1: AaruConsole.Write("What logical block address?: "); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out lba)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); lba = 0; System.Console.ReadKey(); continue; } if (lba > 0xFFFFFFF) { AaruConsole. WriteLine("Logical block address cannot be bigger than {0}. Setting it to {0}...", 0xFFFFFFF); lba = 0xFFFFFFF; } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.TranslateSector(out byte[] buffer, out AtaErrorRegistersLba28 errorRegisters, lba, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending TRANSLATE SECTOR to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Decode error registers."); AaruConsole.WriteLine("3.- Send command again."); AaruConsole.WriteLine("4.- Change parameters."); AaruConsole.WriteLine("0.- Return to CompactFlash commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to CompactFlash commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("TRANSLATE SECTOR response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("TRANSLATE SECTOR status registers:"); AaruConsole.Write("{0}", MainClass.DecodeAtaRegisters(errorRegisters)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: goto start; case 4: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }
static void ReadLong(string devPath, Device dev) { bool relative = false; uint address = 0; ushort length = 1; ushort bps = 512; bool physical = false; bool sectorCount = true; string strDev; int item; parameters: while (true) { System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Parameters for READ LONG command:"); AaruConsole.WriteLine("{0} Block Address: {1}", physical ? "Physical" : "Logical", address); AaruConsole.WriteLine("Relative?: {0}", relative); AaruConsole.WriteLine("Will transfer {0} {1}", length, sectorCount ? "sectors" : "bytes"); if (sectorCount) { AaruConsole.WriteLine("Expected sector size: {0} bytes", bps); } AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Change parameters."); AaruConsole.WriteLine("2.- Send command with these parameters."); AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu."); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); continue; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Plasmon vendor commands menu..."); return; case 1: AaruConsole.Write("Physical address?: "); strDev = System.Console.ReadLine(); if (!bool.TryParse(strDev, out physical)) { AaruConsole.WriteLine("Not a boolean. Press any key to continue..."); physical = false; System.Console.ReadKey(); continue; } AaruConsole.Write("Relative address?: "); strDev = System.Console.ReadLine(); if (!bool.TryParse(strDev, out relative)) { AaruConsole.WriteLine("Not a boolean. Press any key to continue..."); relative = false; System.Console.ReadKey(); continue; } AaruConsole.Write("{0} Block Address?: ", physical ? "Physical" : "Logical"); strDev = System.Console.ReadLine(); if (!uint.TryParse(strDev, out address)) { AaruConsole.WriteLine("Not a numbr. Press any key to continue..."); address = 0; System.Console.ReadKey(); continue; } AaruConsole.Write("Transfer sectors?: "); strDev = System.Console.ReadLine(); if (!bool.TryParse(strDev, out sectorCount)) { AaruConsole.WriteLine("Not a boolean. Press any key to continue..."); sectorCount = true; System.Console.ReadKey(); continue; } AaruConsole.Write("How many {0} to transfer?: ", sectorCount ? "sectors" : "bytes"); strDev = System.Console.ReadLine(); if (!ushort.TryParse(strDev, out length)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); length = (ushort)(sectorCount ? 1 : 512); System.Console.ReadKey(); continue; } if (sectorCount) { AaruConsole.Write("How many bytes to expect per sector?"); strDev = System.Console.ReadLine(); if (!ushort.TryParse(strDev, out bps)) { AaruConsole.WriteLine("Not a numbr. Press any key to continue..."); bps = 512; System.Console.ReadKey(); } } break; case 2: goto start; } } start: System.Console.Clear(); bool sense = dev.PlasmonReadLong(out byte[] buffer, out byte[] senseBuffer, relative, address, length, bps, physical, sectorCount, dev.Timeout, out double duration); menu: AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("Sending READ LONG to the device:"); AaruConsole.WriteLine("Command took {0} ms.", duration); AaruConsole.WriteLine("Sense is {0}.", sense); AaruConsole.WriteLine("Buffer is {0} bytes.", buffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(buffer)); AaruConsole.WriteLine("Sense buffer is {0} bytes.", senseBuffer?.Length.ToString() ?? "null"); AaruConsole.WriteLine("Sense buffer is null or empty? {0}", ArrayHelpers.ArrayIsNullOrEmpty(senseBuffer)); AaruConsole.WriteLine(); AaruConsole.WriteLine("Choose what to do:"); AaruConsole.WriteLine("1.- Print buffer."); AaruConsole.WriteLine("2.- Print sense buffer."); AaruConsole.WriteLine("3.- Decode sense buffer."); AaruConsole.WriteLine("4.- Send command again."); AaruConsole.WriteLine("5.- Change parameters."); AaruConsole.WriteLine("0.- Return to Plasmon vendor commands menu."); AaruConsole.Write("Choose: "); strDev = System.Console.ReadLine(); if (!int.TryParse(strDev, out item)) { AaruConsole.WriteLine("Not a number. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } switch (item) { case 0: AaruConsole.WriteLine("Returning to Plasmon vendor commands menu..."); return; case 1: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ LONG response:"); if (buffer != null) { PrintHex.PrintHexArray(buffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 2: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ LONG sense:"); if (senseBuffer != null) { PrintHex.PrintHexArray(senseBuffer, 64); } AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 3: System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); AaruConsole.WriteLine("READ LONG decoded sense:"); AaruConsole.Write("{0}", Sense.PrettifySense(senseBuffer)); AaruConsole.WriteLine("Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); AaruConsole.WriteLine("Device: {0}", devPath); goto menu; case 4: goto start; case 5: goto parameters; default: AaruConsole.WriteLine("Incorrect option. Press any key to continue..."); System.Console.ReadKey(); System.Console.Clear(); goto menu; } }