Beispiel #1
0
        /// <summary>
        /// 流写入
        /// </summary>
        /// <param name="cin">待写入的流</param>
        /// <param name="position">写入起始位置</param>
        /// <param name="count">需写入的数量</param>
        protected void WriteStream(byte[] cin, int itemNum, int count, InodeStr dinode)
        {
            int pos = _dire.BMap(dinode, itemNum / 512);

            _diskFile.OpenFile();
            _diskFile.SeekFilePosition(pos * 512 + itemNum % 512, System.IO.SeekOrigin.Begin);
            _diskFile.WriteFile(ref cin, 0, count);
            _diskFile.CloseFile();
        }
Beispiel #2
0
        /// <summary>
        /// 初始化数据块
        /// </summary>
        public void InitDataBlock()
        {
            byte[] writeTo;

            _initSuper._s_nfree = 0;
            _initSuper._s_free[_initSuper._s_nfree++] = 0;
            _diskFile.OpenFile();

            //从最后一块往前走,每100块之前的一块为管理块
            //其内容包括
            //1:该管理块管理的块数
            //2:该管理块管理的所有块号
            for (int i = _dataBlkNum - 1; i >= 0; --i)
            {
                if (_initSuper._s_nfree >= 100)
                {
                    //找到要写入的位置,将s_nfree和s_free写入i + datablkstart号磁盘块
                    _diskFile.SeekFilePosition(_diskFile.ConvertPosition(i + _dataBlkStart, 0), System.IO.SeekOrigin.Begin);

                    //转换成流,写入磁盘
                    writeTo = Helper.Struct2Bytes(_initSuper._s_nfree);
                    _diskFile.WriteFile(ref writeTo, 0, 4);

                    for (int j = 0; j < _initSuper._s_nfree; ++j)
                    {
                        //转换成流,写入磁盘
                        writeTo = Helper.Struct2Bytes(_initSuper._s_free[j]);
                        _diskFile.WriteFile(ref writeTo, 0, 4);
                    }
                    _initSuper._s_nfree = 0;
                }
                //数组元素初始化(数组元素用于管理空闲块号)
                _initSuper._s_free[_initSuper._s_nfree++] = i + _dataBlkStart;
            }
            //关闭磁盘文件
            _diskFile.CloseFile();
            //将更新后的超级快信息写回
            _initSuper.UpdateSuperBlockToDisk();
        }
Beispiel #3
0
        /// <summary>

        /// 将编译好的启动文件boot.bin按规定写入磁盘
        /// </summary>
        public void WriteBootBlock()
        {
            int bootSize = MachinePara.Boot_Size * MachinePara.Block_Size;

            byte[] writeTo = new byte[bootSize];

            //读取boot.bin
            _bootFile.OpenFile();
            _bootFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin);
            _bootFile.ReadFile(ref writeTo, 0, 512);
            _bootFile.CloseFile();

            //写入c.img
            _diskFile.OpenFile();
            _diskFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin);
            _diskFile.WriteFile(ref writeTo, 0, bootSize);
            _diskFile.CloseFile();
        }
Beispiel #4
0
        /// <summary>
        /// 将编译好的内核kernel.bin文件按规定写入磁盘
        /// </summary>
        public void WriteKernelBlock()
        {
            _kernelFile.OpenFile();
            int kernelFileLength = (int)_kernelFile.ReturnFileLength();

            byte[] writeTo;
            writeTo = new byte[kernelFileLength];

            //读出kernel.bin文件的内容
            _kernelFile.SeekFilePosition(0, System.IO.SeekOrigin.Begin);
            _kernelFile.ReadFile(ref writeTo, 0, kernelFileLength);
            _kernelFile.CloseFile();

            //将kernel.bin的内容写入c.img
            _diskFile.OpenFile();
            _diskFile.SeekFilePosition(1 * 512, System.IO.SeekOrigin.Begin);
            _diskFile.WriteFile(ref writeTo, 0, kernelFileLength);
            _diskFile.CloseFile();
        }
Beispiel #5
0
        /// <summary>
        /// 创建文件时的目录搜索
        /// 本函数共4个出口
        /// 出口1:目录搜索完毕,且满足三个条件:1.之前各级目录名都能找到,2.但没有符合的最后一级文件,3.且传入的flag为CREATFILE
        /// 出口2:目录搜索完毕,但不完全满足上述三个条件
        /// 出口3:文件(或目录)在系统中已存在,且传入flag为DELETEFILE
        /// 出口4:文件(或目录)在系统中已存在,但传入flag不为DELETEFILE
        /// </summary>
        /// <param name="path">创建文件的目录</param>
        /// <param name="DirInodeNo">父目录的inode号</param>
        /// <returns>目录项的位置</returns>
        public int NameI(string path, ref int dirInodeNo, ref InodeStr dirInode, ref int fileInodeNo, ref InodeStr fileInode, ref char[] fileName, int flag)
        {
            //用于记录在路径字符串中扫描到了哪里
            int curPos = 0;

            //用于记录inode号
            dirInodeNo = 0;
            //首先读入根目录inode
            _inode.GetInodeFromDisk(dirInode, dirInodeNo);

            //跳过开始的一个(或者多个)'/'字符
            for (; curPos < path.Length; ++curPos)
            {
                if (path[curPos] != '/')
                {
                    break;
                }
            }

            //主循环
            while (true)
            {
                //获取两个'/'当中的内容,存入dirPath中
                char[] tmp = new char[28];
                for (int i = 0; curPos < path.Length; ++curPos, ++i)
                {
                    if (path[curPos] == '/')
                    {
                        break;
                    }
                    tmp[i] = path[curPos];
                }
                tmp.CopyTo(fileName, 0);

                //跳过下一个(或者多个)'/'字符,为下一次循环(下一级目录,如果有的话)做准备
                for (; curPos < path.Length; ++curPos)
                {
                    if (path[curPos] != '/')
                    {
                        break;
                    }
                }
                //用于存储扫描当前目录文件的偏移量
                int offset = 0;
                //用于记录第一个空闲目录项的偏移量
                int firstFreeOffset = 0;
                //记录是否又空闲目录项
                int freeFlag = 0;
                //目录项项数
                int dirSize = dirInode._i_size / 32;
                //用于读取一个磁盘块
                byte[] buffer = new byte[512];

                //(次循环)在当前目录文件中搜索
                while (true)
                {
                    //出口1:对当前目录搜索完毕(用于查找是否有同名文件存在)
                    if (dirSize == 0)
                    {
                        //若当前目录索搜索完毕(没有找到相应项),且只是路径名的最后一段没有找到(要创建的文件名),则创建文件
                        if (flag == File.CREATFILE && curPos == path.Length)
                        {
                            //新分配一个inode控制块,返回该inode号
                            try
                            {
                                fileInodeNo = _inode.FetchFreeInode();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                            //根据inode号获取对应的inode(搜索到了哪一层就获取哪一层目录的inode)
                            _inode.GetInodeFromDisk(fileInode, fileInodeNo);
                            //若之前扫描途中有空闲项,则返回其偏移,否则就返回当前inode的大小(即要对当前inode进行扩充)
                            if (freeFlag == 0)
                            {
                                return(dirInode._i_size);
                            }
                            else
                            {
                                return(firstFreeOffset);
                            }
                        }
                        //出口2:若当前目录搜索完毕(没有找到相应项),且中间路径没有找到,则出错
                        else
                        {
                            Error.ErrorType = Error.SEARCHDIR;
                            return(-1);
                        }
                    }

                    //搜索完一块,需要读入新块
                    if (offset % 512 == 0)
                    {
                        _diskFile.OpenFile();
                        _diskFile.SeekFilePosition(this.BMap(dirInode, offset / 512) * 512, System.IO.SeekOrigin.Begin);
                        _diskFile.ReadFile(ref buffer, 0, 512);
                        _diskFile.CloseFile();
                    }

                    bool match = true;
                    for (int j = 0; j < 28; ++j)
                    {
                        if (Convert.ToByte(fileName[j]) != buffer[offset % 512 + j + 4])
                        {
                            match = false;
                            break;
                        }
                    }

                    //表示不匹配
                    if (!match)
                    {
                        dirSize--;
                        //如果之前的目录项为空,则将其用first_free_offset标记
                        //+4是因为每个目录项的前四个字节是inode号
                        if (buffer[offset % 512 + 4] == '\0' && firstFreeOffset == 0)
                        {
                            firstFreeOffset = offset;
                            freeFlag        = 1;
                        }
                        offset += 32;
                        continue;
                    }
                    //在当前目录中找到了和dirPath匹配的目录项
                    else
                    {
                        break;
                    }
                }

                byte[] ino = new byte[4];
                for (int k = 0; k < 4; ++k)
                {
                    ino[k] = buffer[offset % 512 + k];
                }

                /* 出口3:
                 * 删除操作
                 * pathPoint == path.Length表示:目录项已经搜索完毕*/
                if (flag == File.DELETEFILE && curPos == path.Length)
                {
                    //需删除文件的inode号
                    fileInodeNo = (int)Helper.Bytes2Struct(ino, typeof(int));
                    return(offset);
                }

                /* 出口4:
                 * 同一目录下的文件名相同,且不是要做删除操作,则出错
                 * pathPoint == path.Length表示:目录项已经搜索完毕*/
                if (flag != File.DELETEFILE && curPos == path.Length)
                {
                    Error.ErrorType = Error.SAMEFILENAME;
                    return(-1);
                }

                //如果还有下级目录,则更新dirInodeNo与dirInode,为当前目录
                dirInodeNo = (int)Helper.Bytes2Struct(ino, typeof(int));
                _inode.GetInodeFromDisk(dirInode, dirInodeNo);
            }
        }
Beispiel #6
0
        /// <summary>
        /// 将当前的超级快信息更新到磁盘
        /// </summary>
        public void UpdateSuperBlockToDisk()
        {
            byte[] writeTo;

            //定位到超级块起始位置
            _diskFile.OpenFile();
            _diskFile.SeekFilePosition(MachinePara.BootAndKernelSize * 512, System.IO.SeekOrigin.Begin);

            //inode区占据的磁盘块数
            writeTo = Helper.Struct2Bytes(_s_isize);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //总的磁盘块数,为扇区数的一半
            writeTo = Helper.Struct2Bytes(_s_fsize);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //得到直接管理块数
            writeTo = Helper.Struct2Bytes(_s_nfree);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //得到空闲列表
            for (int i = 0; i < 100; ++i)
            {
                writeTo = Helper.Struct2Bytes(_s_free[i]);
                _diskFile.WriteFile(ref writeTo, 0, 4);
            }

            //得到直接管理的inodee数量
            writeTo = Helper.Struct2Bytes(_s_ninode);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //得到空闲inode列表
            for (int i = 0; i < 100; ++i)
            {
                writeTo = Helper.Struct2Bytes(_s_inode[i]);
                _diskFile.WriteFile(ref writeTo, 0, 4);
            }

            //封锁标志
            writeTo = Helper.Struct2Bytes(_s_flock);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //inode封锁标志
            writeTo = Helper.Struct2Bytes(_s_ilock);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //已修改标志
            writeTo = Helper.Struct2Bytes(_s_fmod);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //只读标志
            writeTo = Helper.Struct2Bytes(_s_ronly);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //最后修改时间
            writeTo = Helper.Struct2Bytes(_s_time);
            _diskFile.WriteFile(ref writeTo, 0, 4);

            //填充字段
            if (_s_padding[0] == 1)
            {
                for (int i = 0; i < 47; i++)
                {
                    writeTo = Helper.Struct2Bytes(_s_padding[i]);
                    _diskFile.WriteFile(ref writeTo, 0, 4);
                }
                _s_padding[0] = 0;
            }
            _diskFile.CloseFile();
        }