예제 #1
0
        public bool WriteStream(Stream fs, int StartCluster, int Filesize)
        {
            Log.Info("StartCluster:" + StartCluster.ToString());

            int Size = Filesize;
            int c    = StartCluster;

            while (true)
            {
                var s          = c * ClusterPerSector;
                var LastSector = 0;
                for (var sc = 0; sc < ClusterPerSector; sc++, s++)
                {
                    var Length = Size < DefaultSectorBytes ? Size : DefaultSectorBytes;
                    DiskImage.GetSector(s).Fill(0x00);
                    if (Size == 0)
                    {
                        continue;
                    }

                    var SectorBuffer = DiskImage.GetSectorDataForWrite(s);
                    fs.Read(SectorBuffer, 0, Length);
                    Size -= Length;
                    if (Length > 0)
                    {
                        LastSector = sc;
                    }
                }
                if (Size == 0)
                {
                    if (Setting.X1SMode && LastSector > 0)
                    {
                        LastSector--;
                        if ((Filesize & 0xff) == 0)
                        {
                            LastSector++;
                        }
                    }
                    SetClusterValue(c, LastSector, true);
                    break;
                }
                var next = GetNextFreeCluster(2);
                if (next < 0)
                {
                    Log.Error($"Too big filesize!: LastClaster={c}");
                    SetClusterValue(c, LastSector, true);
                    return(false);
                }
                SetClusterValue(c, next);
                c = next;
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// ファイル展開
        /// </summary>
        public void ExtractFile(Stream fs, HuFileEntry fe)
        {
            int StartCluster = fe.StartCluster;
            int Size         = fe.Size;

            bool AsciiMode = fe.IsAscii;

            int c        = StartCluster;
            int LeftSize = Size;

            int TotalOutputBytes = 0;

            bool SectorWriteMode = Size == 0;

            if (Setting.ForceAsciiMode)
            {
                AsciiMode = true;
            }
            if (Setting.ForceBinaryMode)
            {
                AsciiMode = false;
            }

            while (true)
            {
                var end  = IsEndCluster(c);
                var next = GetClusterValue(c);
                if (next == 0x00)
                {
                    Log.Warning("WARNING: Wrong cluster chain!!");
                    break;
                }
                // セクタ数
                var SectorCount = end ? (next & 0x0f) + 1 : ClusterPerSector;

                for (var i = 0; i < SectorCount; i++)
                {
                    var CurrentSector = (c * ClusterPerSector) + i;
                    var Sector        = DiskImage.GetSector(CurrentSector);

                    var Data = Sector.Data;
                    var Eof  = false;
                    if (AsciiMode)
                    {
                        var AsciiData = ConvertAscii(Sector.Data);
                        Eof  = AsciiData.Eof;
                        Data = AsciiData.Data;
                    }

                    Log.Verbose($"Cluster:{c} Sector:{CurrentSector} Position:0x{Sector.Position:X}");

                    var OutputBytes = Data.Length;

                    // セクタ書き込みモード
                    if (!SectorWriteMode)
                    {
                        // セクタサイズか残りのバイト数を書き出す
                        if (LeftSize < OutputBytes)
                        {
                            OutputBytes = LeftSize;
                        }
                        LeftSize -= OutputBytes;
                    }

                    fs.Write(Data, 0, OutputBytes);
                    TotalOutputBytes += OutputBytes;

                    // 次のクラスタに進む
                    if (Eof)
                    {
                        break;
                    }
                }
                if (end)
                {
                    break;
                }
                c = next;
            }
        }