Пример #1
0
        Errno CacheFile(string path)
        {
            string[] pathElements = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            if (pathElements.Length != 1)
            {
                return(Errno.NotSupported);
            }

            string filename = pathElements[0].ToUpperInvariant();

            if (filename.Length > 30)
            {
                return(Errno.NameTooLong);
            }

            if (!catalogCache.TryGetValue(filename, out ushort ts))
            {
                return(Errno.NoSuchFile);
            }

            ulong        lba           = (ulong)(((ts & 0xFF00) >> 8) * sectorsPerTrack + (ts & 0xFF));
            MemoryStream fileMs        = new MemoryStream();
            MemoryStream tsListMs      = new MemoryStream();
            ushort       expectedBlock = 0;

            while (lba != 0)
            {
                usedSectors++;
                byte[] tsSectorB = device.ReadSector(lba);
                if (debug)
                {
                    tsListMs.Write(tsSectorB, 0, tsSectorB.Length);
                }

                // Read the track/sector list sector
                IntPtr tsPtr = Marshal.AllocHGlobal(256);
                Marshal.Copy(tsSectorB, 0, tsPtr, 256);
                TrackSectorList tsSector = (TrackSectorList)Marshal.PtrToStructure(tsPtr, typeof(TrackSectorList));
                Marshal.FreeHGlobal(tsPtr);

                if (tsSector.sectorOffset > expectedBlock)
                {
                    byte[] hole = new byte[(tsSector.sectorOffset - expectedBlock) * vtoc.bytesPerSector];
                    fileMs.Write(hole, 0, hole.Length);
                    expectedBlock = tsSector.sectorOffset;
                }

                foreach (TrackSectorListEntry entry in tsSector.entries)
                {
                    track1UsedByFiles |= entry.track == 1;
                    track2UsedByFiles |= entry.track == 2;
                    usedSectors++;

                    ulong blockLba = (ulong)(entry.track * sectorsPerTrack + entry.sector);
                    if (blockLba == 0)
                    {
                        break;
                    }

                    byte[] fileBlock = device.ReadSector(blockLba);
                    fileMs.Write(fileBlock, 0, fileBlock.Length);
                    expectedBlock++;
                }

                lba = (ulong)(tsSector.nextListTrack * sectorsPerTrack + tsSector.nextListSector);
            }

            if (fileCache.ContainsKey(filename))
            {
                fileCache.Remove(filename);
            }
            if (extentCache.ContainsKey(filename))
            {
                extentCache.Remove(filename);
            }

            fileCache.Add(filename, fileMs.ToArray());
            extentCache.Add(filename, tsListMs.ToArray());

            return(Errno.NoError);
        }
Пример #2
0
        Errno CacheFile(string path)
        {
            string[] pathElements = path.Split(new[]
            {
                '/'
            }, StringSplitOptions.RemoveEmptyEntries);

            if (pathElements.Length != 1)
            {
                return(Errno.NotSupported);
            }

            string filename = pathElements[0].ToUpperInvariant();

            if (filename.Length > 30)
            {
                return(Errno.NameTooLong);
            }

            if (!_catalogCache.TryGetValue(filename, out ushort ts))
            {
                return(Errno.NoSuchFile);
            }

            ulong  lba           = (ulong)((((ts & 0xFF00) >> 8) * _sectorsPerTrack) + (ts & 0xFF));
            var    fileMs        = new MemoryStream();
            var    tsListMs      = new MemoryStream();
            ushort expectedBlock = 0;

            while (lba != 0)
            {
                _usedSectors++;
                byte[] tsSectorB = _device.ReadSector(lba);

                if (_debug)
                {
                    tsListMs.Write(tsSectorB, 0, tsSectorB.Length);
                }

                // Read the track/sector list sector
                TrackSectorList tsSector = Marshal.ByteArrayToStructureLittleEndian <TrackSectorList>(tsSectorB);

                if (tsSector.sectorOffset > expectedBlock)
                {
                    byte[] hole = new byte[(tsSector.sectorOffset - expectedBlock) * _vtoc.bytesPerSector];
                    fileMs.Write(hole, 0, hole.Length);
                    expectedBlock = tsSector.sectorOffset;
                }

                foreach (TrackSectorListEntry entry in tsSector.entries)
                {
                    _track1UsedByFiles |= entry.track == 1;
                    _track2UsedByFiles |= entry.track == 2;
                    _usedSectors++;

                    ulong blockLba = (ulong)((entry.track * _sectorsPerTrack) + entry.sector);

                    if (blockLba == 0)
                    {
                        break;
                    }

                    byte[] fileBlock = _device.ReadSector(blockLba);
                    fileMs.Write(fileBlock, 0, fileBlock.Length);
                    expectedBlock++;
                }

                lba = (ulong)((tsSector.nextListTrack * _sectorsPerTrack) + tsSector.nextListSector);
            }

            if (_fileCache.ContainsKey(filename))
            {
                _fileCache.Remove(filename);
            }

            if (_extentCache.ContainsKey(filename))
            {
                _extentCache.Remove(filename);
            }

            _fileCache.Add(filename, fileMs.ToArray());
            _extentCache.Add(filename, tsListMs.ToArray());

            return(Errno.NoError);
        }