public RT11(Volume volume) { if (volume.BlockSize != 512) { throw new ArgumentException("RT11 volume block size must be 512."); } mVol = volume; mDirStart = IsChecksumOK(volume[1], 510) ? volume[1].GetUInt16L(0x1d4) : defaultDirStart; mDir = new ClusteredVolume(volume, 2, mDirStart - 2, 32); }
public CPM(Volume volume) { mVol = volume; mType = "CP/M"; mBlocks = new ClusteredVolume(volume, BLOCK_SIZE / volume.BlockSize, 52); mDir = new Byte[64][]; Int32 p = 0; for (Int32 bn = 0; bn < 2; bn++) { Block B = mBlocks[bn]; for (Int32 bp = 0; bp < B.Size; bp += 32) { Byte[] DE = new Byte[32]; B.CopyTo(DE, 0, bp, 32); mDir[p++] = DE; } } }
public static FileSystem Check(Volume[] images) { if (sTests == null) { Init(); } // try to provide each file system test with a volume having the correct block size List <Entry> L = new List <Entry>(); Int32 size = -1; Type type = null; Int32 level = 0; // entries in L have passed this level foreach (FileSystem.TestDelegate test in sTests) { foreach (Volume image in images) { if (test(image, level, out size, out type)) { Debug.WriteLine(2, "Pass: {0} level {1:D0}", test.Method.DeclaringType.Name, level); L.Add(new Entry(test, image, size, type)); continue; } if ((size != -1) && (size != image.BlockSize) && ((size % image.BlockSize) == 0)) { Volume volume = new ClusteredVolume(image, size / image.BlockSize, 0); if (test(volume, level, out size, out type)) { Debug.WriteLine(2, "Pass: {0} level {1:D0} (with ClusteredVolume)", test.Method.DeclaringType.Name, level); L.Add(new Entry(test, volume, size, type)); continue; } } } } // if there were any candidates that passed level 0, continue to try them if (L.Count != 0) { Volume volume = null; while (true) { level++; List <Entry> L2 = new List <Entry>(); foreach (Entry e in L) { Int32 s; Type t; if (e.Test(e.Volume, level, out s, out t)) { Debug.WriteLine(2, "Pass: {0} level {1:D0}", e.Test.Method.DeclaringType.Name, level); volume = e.Volume; size = s; type = (level >= 2) ? t : e.Test.Method.DeclaringType; if ((level > 1) && (size != -1) && (size > volume.BlockCount)) { // grow volume if it appears that empty trailing blocks were trimmed volume = new PaddedVolume(volume, size - volume.BlockCount); } L2.Add(new Entry(e.Test, volume, size, type)); } } if ((level > 1) && (L2.Count == 1)) { // if only one test passed (and we got past level 1), choose that type if ((size != -1) && (size != volume.BlockCount)) { volume = new PaddedVolume(volume, size - volume.BlockCount); } return(ConstructFS(type, volume)); } else if (L2.Count == 0) { // if no test passed this round, the result is indeterminate level--; // L still has previous round's results break; } L = L2; } // if all tests passed for multiple types, choose the type that recognized the most blocks if (level == 6) { Int64 maxSize = -1; foreach (Entry e in L) { Int64 vsize = e.Volume.BlockSize; vsize *= e.Size; if (vsize > maxSize) { maxSize = vsize; volume = e.Volume; size = e.Size; type = e.Type; } } if ((size != -1) && (size != volume.BlockCount)) { volume = new PaddedVolume(volume, size - volume.BlockCount); } return(ConstructFS(type, volume)); } } // TODO: if L is non-empty, see if any use can be made of the knowledge // that entries in L all passed at least level 'level' tests return(((images == null) || (images.Length == 0)) ? null : new RawFS(images[0])); }