CreateFile函数直接读写硬盘实现的文件系统的完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;

namespace ReadWriteDisk
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr CreateFile(string fileName, uint desiredAccess, uint shareMode, uint securityAttributes, uint creationDisposition, uint flagsAndAttributes, uint templateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int ReadFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern int CloseHandle(IntPtr hObject);

        readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

        static class DESIREDACCESS
        {
            public const uint GENERIC_READ = 0x80000000;
            public const uint GENERIC_WRITE = 0x40000000;
            public const uint GENERIC_EXECUTE = 0x20000000;
            public const uint GENERIC_ALL = 0x10000000;
        }
        /// <summary>
        /// Sharing mode of the file or object
        ///</summary>
        static class SHAREMODE
        {
            public const uint FILE_SHARE_READ = 0x00000001;
            public const uint FILE_SHARE_WRITE = 0x00000002;
            public const uint FILE_SHARE_DELETE = 0x00000004;
        }
        /// <summary>
        /// Action to take on files that exist, and which action to take when files do not exist.
        /// </summary>
        static class CREATIONDISPOSITION
        {
            public const uint CREATE_NEW = 1;
            public const uint CREATE_ALWAYS = 2;
            public const uint OPEN_EXISTING = 3;
            public const uint OPEN_ALWAYS = 4;
            public const uint TRUNCATE_EXISTING = 5;
        }
        /// <summary>
        /// File attributes and flags for the file.
        /// </summary>
        static class FLAGSANDATTRIBUTES
        {
            public const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
            public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
            public const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
            public const uint FILE_FLAG_RANDOM_ACCESS = 0x10000000;
            public const uint FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000;
            public const uint FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
            public const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
            public const uint FILE_FLAG_POSIX_SEMANTICS = 0x01000000;
            public const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000;
            public const uint FILE_FLAG_OPEN_NO_RECALL = 0x00100000;
            public const uint FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
        }

        struct OVERLAPPED
        {
            public uint Internal;
            public uint InternalHigh;
            public uint Offset;
            public uint OffsetHigh;
            public uint hEvent;
        }

        uint Status = 0, NumStatus = 0;
        uint SubStatus = 0, NumSubStatus = 0;

        public Form1()
        {
            InitializeComponent();
        }

        IntPtr CreateForRead(byte number)
        {
            IntPtr handle = CreateFile("\\\\.\\PHYSICALDRIVE" + number.ToString(),
               DESIREDACCESS.GENERIC_READ,
               SHAREMODE.FILE_SHARE_READ | SHAREMODE.FILE_SHARE_WRITE,
               0,
               CREATIONDISPOSITION.OPEN_EXISTING,
               0,
               0);

            if (handle == INVALID_HANDLE_VALUE)
                throw new Exception();

            return handle;
        }

        byte[] ReadSectors(IntPtr handle, uint offsetSector, ushort numSectors)
        {
            if (numSectors > 1024)
                throw new Exception();

            uint size = 512u * numSectors;
            byte[] buffer = new byte[size];

            uint _size;

            ulong offset = 512 * (ulong)offsetSector;
            OVERLAPPED over = new OVERLAPPED();
            over.Offset = (uint)(offset & 0xFFFFFFFF);
            over.OffsetHigh = (uint)((offset & 0xFFFFFFFF00000000) >> 32);

            if (ReadFile(handle, buffer, size, out _size, ref over) == 0)
            {
                CloseHandle(handle);
                throw new Exception();
            }

            return buffer;
        }

        IntPtr CreateForWrite(byte number)
        {
            IntPtr handle = CreateFile("\\\\.\\PHYSICALDRIVE" + number.ToString(),
                DESIREDACCESS.GENERIC_WRITE,
                SHAREMODE.FILE_SHARE_WRITE,
                0,
                CREATIONDISPOSITION.OPEN_EXISTING,
                0,
                0);

            if (handle == INVALID_HANDLE_VALUE)
                throw new Exception();

            return handle;
        }

        void WriteSectors(IntPtr handle, uint offsetSector, ushort numSectors, byte[] buffer)
        {
            if (numSectors > 1024)
                throw new Exception();

            uint size = 512u * numSectors;
            if (buffer.Length != size)
                throw new Exception();

            uint _size;

            ulong offset = 512 * (ulong)offsetSector;
            OVERLAPPED over = new OVERLAPPED();
            over.Offset = (uint)(offset & 0xFFFFFFFF);
            over.OffsetHigh = (uint)((offset & 0xFFFFFFFF00000000) >> 32);

            if (WriteFile(handle, buffer, size, out _size, ref over) == 0)
            {
                CloseHandle(handle);
                throw new Exception();
            }
        }

        class SubFile
        {
            public string FileName;
            public uint FileID;
        }

        class DirNode
        {
            public string DirName;
            public LinkedList<DirNode> SubDirs;
            public LinkedList<SubFile> SubFiles;
        }

        void MyWriteSizedString(BinaryWriter w, string str)
        {
            if (str.Length > UInt16.MaxValue)
                throw new Exception();

            w.Write((UInt16)str.Length);
            if (str.Length > 0)
                w.Write((char[])str.ToCharArray());
        }

        string MyReadSizedString(BinaryReader r)
        {
            ushort size = r.ReadUInt16();
            return size == 0 ? "" : new string(r.ReadChars(size));
        }

        void OutputDirStream(DirNode node, BinaryWriter w)
        {
            if (w.BaseStream is MemoryStream == false)
                throw new Exception();

            MyWriteSizedString(w, node.DirName);

            if (node.SubDirs.Count > UInt16.MaxValue)
                throw new Exception();
            w.Write((UInt16)node.SubDirs.Count);
            if (node.SubDirs.Count > 0)
            {
                foreach (DirNode d in node.SubDirs)
                {
                    OutputDirStream(d, w);
                }
            }

            if (node.SubFiles.Count > UInt16.MaxValue)
                throw new Exception();
            w.Write((UInt16)node.SubFiles.Count);
            if (node.SubFiles.Count > 0)
            {
                foreach (SubFile f in node.SubFiles)
                {
                    MyWriteSizedString(w, f.FileName);
                    w.Write((UInt32)f.FileID);
                }
            }
        }

        void InputDirStream(BinaryReader r, DirNode node)
        {
            if (r.BaseStream is MemoryStream == false)
                throw new Exception();

            node.DirName = MyReadSizedString(r);

            UInt16 numSubDirs = r.ReadUInt16();
            node.SubDirs = new LinkedList<DirNode>();
            if (numSubDirs > 0)
            {
                for (UInt16 i = 0; i < numSubDirs; i++)
                {
                    DirNode tmp = new DirNode();
                    node.SubDirs.AddLast(tmp);
                    InputDirStream(r, tmp);
                }
            }

            UInt16 numSubFiles = r.ReadUInt16();
            node.SubFiles = new LinkedList<SubFile>();
            if (numSubFiles > 0)
            {
                for (UInt16 i = 0; i < numSubFiles; i++)
                {
                    SubFile tmp = new SubFile();
                    node.SubFiles.AddLast(tmp);
                    tmp.FileName = MyReadSizedString(r);
                    tmp.FileID = r.ReadUInt32();
                }
            }
        }

        byte[] ReadDirStreamFromDisk(IntPtr handle, uint offsetSector)
        {
            byte[] bufLen = ReadSectors(handle, offsetSector, 1);
            uint len = BitConverter.ToUInt32(bufLen, 0);

            uint numAllSectors = (uint)len % (uint)512u == 0 ? (uint)len / (uint)512u : (uint)len / (uint)512 + 1;
            List<byte> bytes = new List<byte>((int)numAllSectors * 512);

            NumSubStatus = NumStatus = numAllSectors;
            SubStatus = Status = 0;

            for (uint i = 0; i < numAllSectors; i += 1024)
            {
                SubStatus = Status = i;

                if (numAllSectors - i >= 1024)
                {
                    bytes.AddRange(ReadSectors(handle, offsetSector + 1 + i, 1024));
                }
                else
                {
                    bytes.AddRange(ReadSectors(handle, offsetSector + 1 + i, (ushort)(numAllSectors - i)));
                }
            }

            NumSubStatus = NumStatus = 0;
            SubStatus = Status = 0;

            byte[] _bytes = new byte[len];
            bytes.CopyTo(0, _bytes, 0, (int)len);

            return _bytes;
        }

        void WriteDirStreamToDisk(IntPtr handle, uint offsetSector, byte[] bytes)
        {
            byte[] bufLen = new byte[512];
            BitConverter.GetBytes((UInt32)bytes.Length).CopyTo(bufLen, 0);

            WriteSectors(handle, offsetSector, 1, bufLen);

            List<byte[]> _bytes = new List<byte[]>();

            for (int i = 0; i < bytes.Length; i += 512 * 1024)
            {
                if (bytes.Length - i >= 512 * 1024)
                {
                    byte[] tmp = new byte[512 * 1024];
                    Array.Copy(bytes, i, tmp, 0, 512 * 1024);
                    _bytes.Add(tmp);
                }
                else
                {
                    int tSize = bytes.Length - i;
                    int _tSize = (int)tSize % (int)512 == 0 ? (int)tSize / (int)512 : ((int)tSize / (int)512) * 512 + 512;
                    byte[] tmp = new byte[_tSize];
                    Array.Copy(bytes, bytes.Length - tSize, tmp, 0, tSize);
                    _bytes.Add(tmp);
                }
            }

            NumSubStatus = NumStatus = (uint)_bytes.Count;
            SubStatus = Status = 0;

            for (int i = 0; i < _bytes.Count; i++)
            {
                SubStatus = Status = (uint)i;

                WriteSectors(handle, offsetSector + 1 + (uint)(i * 1024), (ushort)(_bytes[i].Length / 512), _bytes[i]);
            }

            NumSubStatus = NumStatus = 0;
            SubStatus = Status = 0;
        }

        void CreateTree(DirectoryInfo mainDirInfo, out DirNode root, out List<string> files)
        {
            root = new DirNode();
            root.DirName = "";

            files = new List<string>();

            root.SubDirs = new LinkedList<DirNode>();
            DirectoryInfo[] dirInfos = mainDirInfo.GetDirectories();
            if (dirInfos.Length > 0)
            {
                foreach (DirectoryInfo d in dirInfos)
                {
                    DirNode tmp = new DirNode();
                    root.SubDirs.AddLast(tmp);
                    CreateTreeRec(d, tmp, files);
                }
            }

            root.SubFiles = new LinkedList<SubFile>();
            FileInfo[] fileInfos = mainDirInfo.GetFiles();
            if (fileInfos.Length > 0)
            {
                foreach (FileInfo f in fileInfos)
                {
                    SubFile tmp = new SubFile();
                    root.SubFiles.AddLast(tmp);
                    tmp.FileName = f.Name;
                    files.Add(f.FullName);
                    tmp.FileID = (uint)(files.Count - 1);
                }
            }
        }

        void CreateTreeRec(DirectoryInfo dirInfo, DirNode node, List<string> files)
        {
            node.DirName = dirInfo.Name;

            node.SubDirs = new LinkedList<DirNode>();
            DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
            if (dirInfos.Length > 0)
            {
                foreach (DirectoryInfo d in dirInfos)
                {
                    DirNode tmp = new DirNode();
                    node.SubDirs.AddLast(tmp);
                    CreateTreeRec(d, tmp, files);
                }
            }

            node.SubFiles = new LinkedList<SubFile>();
            FileInfo[] fileInfos = dirInfo.GetFiles();
            if (fileInfos.Length > 0)
            {
                foreach (FileInfo f in fileInfos)
                {
                    SubFile tmp = new SubFile();
                    node.SubFiles.AddLast(tmp);
                    tmp.FileName = f.Name;
                    files.Add(f.FullName);
                    tmp.FileID = (uint)(files.Count - 1);
                }
            }
        }

        struct FileDesc
        {
            public uint OffsetSector;
            public uint NumSectors;
            public ushort SizeLastSector;
        }

        void MakeAll(IntPtr handle, List<string> files, byte[] dirStream)
        {
            uint numFiles = (uint)files.Count;

            uint offsetSectorFileCount = 2;
            uint offsetSectorOfOffsetSectorDirStream = offsetSectorFileCount + 1;
            uint offsetSectorFileTable = offsetSectorOfOffsetSectorDirStream + 1;
            uint offsetSectorFiles = offsetSectorFileTable + numFiles;

            FileDesc[] fileTable = new FileDesc[numFiles];

            FileInfo _fileInfo = new FileInfo(files[0]);

            fileTable[0].OffsetSector = offsetSectorFiles;
            fileTable[0].SizeLastSector = (ushort)(_fileInfo.Length % 512 == 0 ? 512 : (_fileInfo.Length % 512));
            fileTable[0].NumSectors = (uint)(_fileInfo.Length / 512 + (fileTable[0].SizeLastSector == 512 ? 0 : 1));

            for (int i = 1; i < numFiles; i++)
            {
                FileInfo fileInfo = new FileInfo(files[i]);

                fileTable[i].OffsetSector = fileTable[i - 1].OffsetSector + fileTable[i - 1].NumSectors;
                fileTable[i].SizeLastSector = (ushort)(fileInfo.Length % 512 == 0 ? 512 : (fileInfo.Length % 512));
                fileTable[i].NumSectors = (uint)(fileInfo.Length / 512 + (fileTable[i].SizeLastSector == 512 ? 0 : 1));
            }

            uint offsetSectorDirStream = fileTable[numFiles - 1].OffsetSector + fileTable[numFiles - 1].NumSectors;

            List<byte[]> bytes = new List<byte[]>();

            byte[] bytesFileCount = new byte[512];
            BitConverter.GetBytes(numFiles).CopyTo(bytesFileCount, 0);
            bytes.Add(bytesFileCount);

            byte[] bytesOffsetSectorDirStream = new byte[512];
            BitConverter.GetBytes(offsetSectorDirStream).CopyTo(bytesOffsetSectorDirStream, 0);
            bytes.Add(bytesOffsetSectorDirStream);

            for (int i = 0; i < numFiles; i++)
            {
                byte[] bytesFileDesc = new byte[512];
                BitConverter.GetBytes((UInt32)fileTable[i].OffsetSector).CopyTo(bytesFileDesc, 0);
                BitConverter.GetBytes((UInt32)fileTable[i].NumSectors).CopyTo(bytesFileDesc, 4);
                BitConverter.GetBytes((UInt16)fileTable[i].SizeLastSector).CopyTo(bytesFileDesc, 8);
                bytes.Add(bytesFileDesc);
            }

            List<byte[]> _bytes = new List<byte[]>();

            for (int i = 0; i < bytes.Count; i += 1024)
            {
                if (bytes.Count - i >= 1024)
                {
                    byte[] tmp = new byte[512 * 1024];
                    for (int j = 0; j < 1024; j++)
                        bytes[i + j].CopyTo(tmp, j * 512);
                    _bytes.Add(tmp);
                }
                else
                {
                    byte[] tmp = new byte[512 * (bytes.Count - i)];
                    for (int j = 0; j < bytes.Count - i; j++)
                        bytes[i + j].CopyTo(tmp, j * 512);
                    _bytes.Add(tmp);
                }
            }

            NumStatus = 1 + numFiles;
            Status = 0;

            NumSubStatus = (uint)_bytes.Count;
            SubStatus = 0;

            for (int i = 0; i < _bytes.Count; i++)
            {
                SubStatus = (uint)i;

                WriteSectors(handle, offsetSectorFileCount + (uint)(i * 1024), (ushort)(_bytes[i].Length / 512), _bytes[i]);
            }

            for (int i = 0; i < numFiles; i++)
            {
                Status = (uint)(1 + i);

                FileStream fs = new FileStream(files[i], FileMode.Open, FileAccess.Read, FileShare.Read);
                BinaryReader r = new BinaryReader(fs);

                NumSubStatus = fileTable[i].NumSectors;
                SubStatus = 0;

                for (int j = 0; j < fileTable[i].NumSectors; j += 1024)
                {
                    SubStatus = (uint)j;

                    if (fileTable[i].NumSectors - j > 1024)
                    {
                        byte[] buffer = r.ReadBytes(512 * 1024);
                        WriteSectors(handle, fileTable[i].OffsetSector + (uint)j, 1024, buffer);
                    }
                    else if (fileTable[i].NumSectors - j == 1024)
                    {
                        byte[] _buffer = r.ReadBytes(512 * 1023 + fileTable[i].SizeLastSector);
                        byte[] buffer = new byte[512 * 1024];
                        _buffer.CopyTo(buffer, 0);
                        WriteSectors(handle, fileTable[i].OffsetSector + (uint)j, 1024, buffer);
                    }
                    else
                    {
                        byte[] _buffer = r.ReadBytes((int)((fileTable[i].NumSectors - j - 1) * 512 + fileTable[i].SizeLastSector));
                        if (fs.Position != fs.Length)
                            throw new Exception();
                        byte[] buffer = new byte[(fileTable[i].NumSectors - j) * 512];
                        _buffer.CopyTo(buffer, 0);
                        WriteSectors(handle, fileTable[i].OffsetSector + (uint)j, (ushort)(buffer.Length / 512), buffer);
                    }
                }

                r.Close();
            }

            NumSubStatus = NumStatus = 0;
            SubStatus = Status = 0;

            WriteDirStreamToDisk(handle, offsetSectorDirStream, dirStream);
        }

        uint GetOffsetSectorDirStream(IntPtr handle)
        {
            uint offsetSectorFileCount = 2;
            uint offsetSectorOfOffsetSectorDirStream = offsetSectorFileCount + 1;
            //uint offsetSectorFileTable = offsetSectorOfOffsetSectorDirStream + 1;

            byte[] bytes = ReadSectors(handle, offsetSectorOfOffsetSectorDirStream, 1);

            for (int i = 4; i < bytes.Length; i++)
                if (bytes[i] != 0)
                    throw new Exception();

            return BitConverter.ToUInt32(bytes, 0);
        }

        void GetFile(IntPtr handle, uint fileID, DirectoryInfo dirInfoSaveTo, string fileNameSaveTo, bool overwrite)
        {
            uint offsetSectorFileCount = 2;
            uint offsetSectorOfOffsetSectorDirStream = offsetSectorFileCount + 1;
            uint offsetSectorFileTable = offsetSectorOfOffsetSectorDirStream + 1;

            byte[] bytes = ReadSectors(handle, offsetSectorFileTable + fileID, 1);

            for (int i = 12; i < bytes.Length; i++)
                if (bytes[i] != 0)
                    throw new Exception();

            FileDesc fileDesc = new FileDesc();
            fileDesc.OffsetSector = BitConverter.ToUInt32(bytes, 0);
            fileDesc.NumSectors = BitConverter.ToUInt32(bytes, 4);
            fileDesc.SizeLastSector = BitConverter.ToUInt16(bytes, 8);

            FileStream fs = new FileStream(dirInfoSaveTo.FullName + '\\' + fileNameSaveTo, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.Write, FileShare.None);
            BinaryWriter w = new BinaryWriter(fs);

            NumSubStatus = NumStatus = fileDesc.NumSectors;
            SubStatus = Status = 0;

            for (int i = 0; i < fileDesc.NumSectors; i += 1024)
            {
                SubStatus = Status = (uint)i;

                if (fileDesc.NumSectors - i > 1024)
                {
                    byte[] buffer = ReadSectors(handle, fileDesc.OffsetSector + (uint)i, 1024);
                    w.Write(buffer);
                }
                else if (fileDesc.NumSectors - i == 1024)
                {
                    byte[] buffer = ReadSectors(handle, fileDesc.OffsetSector + (uint)i, 1024);
                    w.Write(buffer, 0, 1023 * 512 + fileDesc.SizeLastSector);
                }
                else
                {
                    byte[] buffer = ReadSectors(handle, fileDesc.OffsetSector + (uint)i, (ushort)(fileDesc.NumSectors - i));
                    w.Write(buffer, 0, buffer.Length - 512 + fileDesc.SizeLastSector);
                }
            }

            NumSubStatus = NumStatus = 0;
            SubStatus = Status = 0;

            w.Close();
        }

        void FormatQuick(IntPtr handle)
        {
            byte[] bytes = new byte[512 * 2];
            for (int i = 0; i < bytes.Length; i++)
                bytes[i] = 0x88;

            WriteSectors(handle, 0, 2, bytes);
        }

        bool CheckFormat(IntPtr handle)
        {
            byte[] bytes = ReadSectors(handle, 0, 2);

            foreach (byte b in bytes)
                if (b != 0x88)
                    return false;

            return true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            byte number;
            try
            {
                number = byte.Parse(textBox3.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid HDD number!");
                return;
            }

            DirectoryInfo path;
            try
            {
                path = new DirectoryInfo(textBox1.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Path is not found!");
                return;
            }

            IntPtr handle_;
            try
            {
                handle_ = CreateForRead(number);
            }
            catch (Exception)
            {
                MessageBox.Show("HDD is not found!");
                return;
            }

            bool b = CheckFormat(handle_);
            CloseHandle(handle_);

            if (!b)
            {
                MessageBox.Show("Unsupported HDD format!");
                return;
            }

            MemoryStream ms = new MemoryStream();
            BinaryWriter w = new BinaryWriter(ms);

            DirNode root;
            List<string> files;
            CreateTree(path, out root, out files);

            OutputDirStream(root, w);

            byte[] bytes = ms.ToArray();
            ms.Close();

            IntPtr handle = CreateForWrite(number);

            button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = false;
            bool flag = false;
            Thread thread = new Thread(delegate()
            {
                try
                {
                    MakeAll(handle, files, bytes);
                    flag = true;
                }
                catch (Exception)
                {
                    flag = false;
                }
            });
            thread.Start();
            while (thread.ThreadState == ThreadState.Running)
            {
                Application.DoEvents();

                progressBar1.Minimum = 0;
                progressBar1.Maximum = NumStatus == 0 ? 0 : (int)(NumStatus - 1);
                progressBar1.Value = (int)Status;

                progressBar2.Minimum = 0;
                progressBar2.Maximum = NumSubStatus == 0 ? 0 : (int)(NumSubStatus - 1);
                progressBar2.Value = (int)SubStatus;
            }
            button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = true;
            
            CloseHandle(handle);

            MessageBox.Show(flag ? "Done!" : "Failed!");
        }

        void ShowDirs(DirNode node, TreeNodeCollection viewNodes)
        {
            if (node.SubDirs.Count > 0)
            {
                foreach (DirNode d in node.SubDirs)
                {
                    TreeNode tmp = new TreeNode();
                    tmp.Text = d.DirName + "    <DIR>";
                    tmp.Tag = null;
                    viewNodes.Add(tmp);

                    ShowDirs(d, tmp.Nodes);
                }
            }
            
            if (node.SubFiles.Count > 0)
            {
                foreach (SubFile f in node.SubFiles)
                {
                    TreeNode tmp = new TreeNode();
                    tmp.Text = f.FileName;
                    tmp.Tag = f.FileID;
                    viewNodes.Add(tmp);
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            byte number;
            try
            {
                number = byte.Parse(textBox4.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid HDD number!");
                return;
            }

            IntPtr handle_;
            try
            {
                handle_ = CreateForRead(number);
            }
            catch (Exception)
            {
                MessageBox.Show("HDD is not found!");
                return;
            }

            bool b = CheckFormat(handle_);
            CloseHandle(handle_);

            if (!b)
            {
                MessageBox.Show("Unsupported HDD format!");
                return;
            }

            IntPtr handle = CreateForRead(number);
            DirNode root = new DirNode();
            InputDirStream(new BinaryReader(new MemoryStream(ReadDirStreamFromDisk(handle, GetOffsetSectorDirStream(handle)))), root);
            CloseHandle(handle);

            treeView1.Nodes.Clear();
            ShowDirs(root, treeView1.Nodes);

            treeView1.Tag = number;

            MessageBox.Show("Done!");
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (treeView1.SelectedNode == null || treeView1.SelectedNode.Tag == null)
            {
                MessageBox.Show("No file is selected!");
                return;
            }

            byte number = (byte)treeView1.Tag;
            textBox4.Text = number.ToString();

            DirectoryInfo path;
            try
            {
                path = new DirectoryInfo(textBox2.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Path is not found!");
                return;
            }

            IntPtr handle_;
            try
            {
                handle_ = CreateForRead(number);
            }
            catch (Exception)
            {
                MessageBox.Show("HDD is not found!");
                return;
            }

            bool b = CheckFormat(handle_);
            CloseHandle(handle_);

            if (!b)
            {
                MessageBox.Show("Unsupported HDD format!");
                return;
            }

            IntPtr handle = CreateForRead(number);

            button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = false;
            uint fileID = (uint)treeView1.SelectedNode.Tag;
            string fileNameSaveTo = treeView1.SelectedNode.Text;
            bool overwrite = checkBox1.Checked;
            bool flag = false;
            Thread thread = new Thread(delegate()
            {
                try
                {
                    GetFile(handle, fileID, path, fileNameSaveTo, overwrite);
                    flag = true;
                }
                catch (Exception)
                {
                    flag = false;
                }
            });
            thread.Start();
            while (thread.ThreadState == ThreadState.Running)
            {
                Application.DoEvents();

                progressBar1.Minimum = 0;
                progressBar1.Maximum = NumStatus == 0 ? 0 : (int)(NumStatus - 1);
                progressBar1.Value = (int)Status;

                progressBar2.Minimum = 0;
                progressBar2.Maximum = NumSubStatus == 0 ? 0 : (int)(NumSubStatus - 1);
                progressBar2.Value = (int)SubStatus;
            }
            button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = true;

            CloseHandle(handle);

            MessageBox.Show(flag ? "Done!" : "Failed!");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            byte number;
            try
            {
                number = byte.Parse(textBox5.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Invalid HDD number!");
                return;
            }

            IntPtr handle_;
            try
            {
                handle_ = CreateForRead(number);
            }
            catch (Exception)
            {
                MessageBox.Show("HDD is not found!");
                return;
            }

            bool b = CheckFormat(handle_);
            CloseHandle(handle_);

            if (b)
            {
                MessageBox.Show("Already formatted!");
                return;
            }
            else
            {
                if (MessageBox.Show("Not formatted, format now?", "Format", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    IntPtr handle = CreateForWrite(number);
                    FormatQuick(handle);
                    CloseHandle(handle);

                    MessageBox.Show("Done!");
                }
            }
        }
    }
}

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值