Kaynağa Gözat

commit: LargeRamDisk added

HOME 5 yıl önce
ebeveyn
işleme
694531f53d

+ 2 - 0
DiskAccessLibrary/DiskAccessLibrary.csproj

@@ -209,6 +209,8 @@
     <Compile Include="Mod\DiskImageCreator.cs" />
     <Compile Include="Mod\DiskImageCreator.cs" />
     <Compile Include="Mod\DiskImageFormat.cs" />
     <Compile Include="Mod\DiskImageFormat.cs" />
     <Compile Include="Mod\DiskImageType.cs" />
     <Compile Include="Mod\DiskImageType.cs" />
+    <Compile Include="Mod\LargeRamDisk.cs" />
+    <Compile Include="Mod\UnmanagedLargeRamDisk.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionEntry.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionEntry.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionEntryCollection.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionEntryCollection.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionTable.cs" />
     <Compile Include="PartitionTables\GuidPartitionTable\GuidPartitionTable.cs" />

+ 1 - 1
DiskAccessLibrary/Mod/Consts.cs

@@ -10,6 +10,6 @@ namespace DiskAccessLibrary.Mod
     {
     {
         public const int KiloByte = 1024;
         public const int KiloByte = 1024;
         public const int MegaByte = 1024 * KiloByte;
         public const int MegaByte = 1024 * KiloByte;
-
+        public const int Gigabyte = 1024 * MegaByte;
     }
     }
 }
 }

+ 97 - 0
DiskAccessLibrary/Mod/LargeRaMDisk.cs

@@ -0,0 +1,97 @@
+using System;
+
+namespace DiskAccessLibrary.Mod
+{
+    public class LargeRamDisk : Disk
+    {
+        private const int SectorSize = 512;
+        private const int BlockSize = Consts.Gigabyte;
+
+        private byte[][] _blocks;
+
+        public LargeRamDisk(int sizeInGigabyte)
+        {
+            var arr = new byte[sizeInGigabyte][];
+            for (var i = 0; i < sizeInGigabyte; i++)
+            {
+                arr[i] = new byte[Consts.Gigabyte];
+            }
+
+            _blocks = arr;
+            Size = (long)sizeInGigabyte * Consts.Gigabyte;
+        }
+
+        public void Free()
+        {
+            for (var i = 0; i < _blocks.Length; i++)
+            {
+                _blocks[i] = null;
+            }
+            _blocks = null;
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+        }
+
+        private void ReadBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
+        {
+            Buffer.BlockCopy(_blocks[blockIndex], blockOffset, buffer, offset, count);
+        }
+
+        private void WriteBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
+        {
+            Buffer.BlockCopy(buffer, offset, _blocks[blockIndex], blockOffset, count);
+        }
+
+        public override byte[] ReadSectors(long sectorIndex, int sectorCount)
+        {
+            var rawOffset = sectorIndex * SectorSize;
+            var rawSize = sectorCount * SectorSize;
+
+            var buffer = new byte[rawSize];
+
+            for (var i = 0; i < rawSize;)
+            {
+                var blockIndex = (int)(rawOffset / BlockSize);
+                var blockOffset = (int)(rawOffset % BlockSize);
+                var bytesToRead = BlockSize - blockOffset;
+
+                if (i + bytesToRead > rawSize)
+                {
+                    bytesToRead = rawSize - i;
+                }
+
+                ReadBlock(buffer, i, bytesToRead, blockIndex, blockOffset);
+
+                i += bytesToRead;
+                rawOffset += bytesToRead;
+            }
+
+            return buffer;
+        }
+
+        public override void WriteSectors(long sectorIndex, byte[] data)
+        {
+            var rawOffset = sectorIndex * SectorSize;
+
+            for (var i = 0; i < data.Length;)
+            {
+                var blockIndex = (int)(rawOffset / BlockSize);
+                var blockOffset = (int)(rawOffset % BlockSize);
+                var bytesToWrite = BlockSize - blockOffset;
+
+                if (i + bytesToWrite > data.Length)
+                {
+                    bytesToWrite = data.Length - i;
+                }
+
+                WriteBlock(data, i, bytesToWrite, blockIndex, blockOffset);
+
+                i += bytesToWrite;
+                rawOffset += bytesToWrite;
+            }
+        }
+
+        public override int BytesPerSector => SectorSize;
+        public override long Size { get; }
+    }
+}

+ 102 - 0
DiskAccessLibrary/Mod/UnmanagedLargeRamDisk.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace DiskAccessLibrary.Mod
+{
+    public class UnmanagedLargeRamDisk : Disk
+    {
+        private const int SectorSize = 512;
+        private const int BlockSize = Consts.Gigabyte;
+
+        private IntPtr[] _blocks;
+
+        public UnmanagedLargeRamDisk(int sizeInGigabyte)
+        {
+            _blocks = new IntPtr[sizeInGigabyte];
+            Size = (long)sizeInGigabyte * Consts.Gigabyte;
+        }
+
+        public void Allocate()
+        {
+            for (var i = 0; i < _blocks.Length; i++)
+            {
+                _blocks[i] = Marshal.AllocHGlobal(BlockSize);
+                //Marshal.WriteByte(_blocks[i], BlockSize - 1, 1);
+                //Marshal.WriteByte(_blocks[i], BlockSize - 1, 0);
+            }
+        }
+
+        public void Free()
+        {
+            foreach (var block in _blocks)
+            {
+                if (block != IntPtr.Zero) Marshal.FreeHGlobal(block);
+            }
+            _blocks = null;
+            GC.Collect();
+            GC.WaitForPendingFinalizers();
+        }
+
+        private void ReadBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
+        {
+            Marshal.Copy(_blocks[blockIndex] + blockOffset, buffer, offset, count);
+        }
+
+        private void WriteBlock(byte[] buffer, int offset, int count, int blockIndex, int blockOffset)
+        {
+            Marshal.Copy(buffer, offset, _blocks[blockIndex] + blockOffset, count);
+        }
+
+        public override byte[] ReadSectors(long sectorIndex, int sectorCount)
+        {
+            var rawOffset = sectorIndex * SectorSize;
+            var rawSize = sectorCount * SectorSize;
+
+            var buffer = new byte[rawSize];
+
+            for (var i = 0; i < rawSize;)
+            {
+                var blockIndex = (int)(rawOffset / BlockSize);
+                var blockOffset = (int)(rawOffset % BlockSize);
+                var bytesToRead = BlockSize - blockOffset;
+
+                if (i + bytesToRead > rawSize)
+                {
+                    bytesToRead = rawSize - i;
+                }
+
+                ReadBlock(buffer, i, bytesToRead, blockIndex, blockOffset);
+
+                i += bytesToRead;
+                rawOffset += bytesToRead;
+            }
+
+            return buffer;
+        }
+
+        public override void WriteSectors(long sectorIndex, byte[] data)
+        {
+            var rawOffset = sectorIndex * SectorSize;
+
+            for (var i = 0; i < data.Length;)
+            {
+                var blockIndex = (int)(rawOffset / BlockSize);
+                var blockOffset = (int)(rawOffset % BlockSize);
+                var bytesToWrite = BlockSize - blockOffset;
+
+                if (i + bytesToWrite > data.Length)
+                {
+                    bytesToWrite = data.Length - i;
+                }
+
+                WriteBlock(data, i, bytesToWrite, blockIndex, blockOffset);
+
+                i += bytesToWrite;
+                rawOffset += bytesToWrite;
+            }
+        }
+
+        public override int BytesPerSector => SectorSize;
+        public override long Size { get; }
+    }
+}

+ 1 - 1
ISCSIConsole/AddTargetForm.cs

@@ -46,7 +46,7 @@ namespace ISCSIConsole
                 DialogResult result = createRAMDisk.ShowDialog();
                 DialogResult result = createRAMDisk.ShowDialog();
                 if (result == DialogResult.OK)
                 if (result == DialogResult.OK)
                 {
                 {
-                    RAMDisk ramDisk = createRAMDisk.RAMDisk;
+                    var ramDisk = createRAMDisk.RAMDisk;
                     AddDisk(ramDisk);
                     AddDisk(ramDisk);
                 }
                 }
             }
             }

+ 28 - 12
ISCSIConsole/CreateRAMDiskForm.Designer.cs

@@ -31,9 +31,10 @@ namespace ISCSIConsole
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CreateRAMDiskForm));
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CreateRAMDiskForm));
             this.numericDiskSize = new System.Windows.Forms.NumericUpDown();
             this.numericDiskSize = new System.Windows.Forms.NumericUpDown();
             this.lblSize = new System.Windows.Forms.Label();
             this.lblSize = new System.Windows.Forms.Label();
-            this.label1 = new System.Windows.Forms.Label();
             this.btnOK = new System.Windows.Forms.Button();
             this.btnOK = new System.Windows.Forms.Button();
             this.btnCancel = new System.Windows.Forms.Button();
             this.btnCancel = new System.Windows.Forms.Button();
+            this.MbRadioButton = new System.Windows.Forms.RadioButton();
+            this.GbRadioButton = new System.Windows.Forms.RadioButton();
             ((System.ComponentModel.ISupportInitialize)(this.numericDiskSize)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.numericDiskSize)).BeginInit();
             this.SuspendLayout();
             this.SuspendLayout();
             // 
             // 
@@ -69,15 +70,6 @@ namespace ISCSIConsole
             this.lblSize.TabIndex = 1;
             this.lblSize.TabIndex = 1;
             this.lblSize.Text = "Size:";
             this.lblSize.Text = "Size:";
             // 
             // 
-            // label1
-            // 
-            this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(148, 18);
-            this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(17, 12);
-            this.label1.TabIndex = 2;
-            this.label1.Text = "MB";
-            // 
             // btnOK
             // btnOK
             // 
             // 
             this.btnOK.Location = new System.Drawing.Point(224, 88);
             this.btnOK.Location = new System.Drawing.Point(224, 88);
@@ -99,15 +91,38 @@ namespace ISCSIConsole
             this.btnCancel.UseVisualStyleBackColor = true;
             this.btnCancel.UseVisualStyleBackColor = true;
             this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
             this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
             // 
             // 
+            // MbRadioButton
+            // 
+            this.MbRadioButton.AutoSize = true;
+            this.MbRadioButton.Checked = true;
+            this.MbRadioButton.Location = new System.Drawing.Point(148, 16);
+            this.MbRadioButton.Name = "MbRadioButton";
+            this.MbRadioButton.Size = new System.Drawing.Size(35, 16);
+            this.MbRadioButton.TabIndex = 8;
+            this.MbRadioButton.TabStop = true;
+            this.MbRadioButton.Text = "MB";
+            this.MbRadioButton.UseVisualStyleBackColor = true;
+            // 
+            // GbRadioButton
+            // 
+            this.GbRadioButton.AutoSize = true;
+            this.GbRadioButton.Location = new System.Drawing.Point(189, 16);
+            this.GbRadioButton.Name = "GbRadioButton";
+            this.GbRadioButton.Size = new System.Drawing.Size(35, 16);
+            this.GbRadioButton.TabIndex = 9;
+            this.GbRadioButton.Text = "GB";
+            this.GbRadioButton.UseVisualStyleBackColor = true;
+            // 
             // CreateRAMDiskForm
             // CreateRAMDiskForm
             // 
             // 
             this.AcceptButton = this.btnOK;
             this.AcceptButton = this.btnOK;
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
             this.CancelButton = this.btnCancel;
             this.CancelButton = this.btnCancel;
             this.ClientSize = new System.Drawing.Size(384, 111);
             this.ClientSize = new System.Drawing.Size(384, 111);
+            this.Controls.Add(this.GbRadioButton);
+            this.Controls.Add(this.MbRadioButton);
             this.Controls.Add(this.btnCancel);
             this.Controls.Add(this.btnCancel);
             this.Controls.Add(this.btnOK);
             this.Controls.Add(this.btnOK);
-            this.Controls.Add(this.label1);
             this.Controls.Add(this.lblSize);
             this.Controls.Add(this.lblSize);
             this.Controls.Add(this.numericDiskSize);
             this.Controls.Add(this.numericDiskSize);
             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
@@ -129,8 +144,9 @@ namespace ISCSIConsole
 
 
         private System.Windows.Forms.NumericUpDown numericDiskSize;
         private System.Windows.Forms.NumericUpDown numericDiskSize;
         private System.Windows.Forms.Label lblSize;
         private System.Windows.Forms.Label lblSize;
-        private System.Windows.Forms.Label label1;
         private System.Windows.Forms.Button btnOK;
         private System.Windows.Forms.Button btnOK;
         private System.Windows.Forms.Button btnCancel;
         private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.RadioButton MbRadioButton;
+        private System.Windows.Forms.RadioButton GbRadioButton;
     }
     }
 }
 }

+ 35 - 16
ISCSIConsole/CreateRAMDiskForm.cs

@@ -1,18 +1,13 @@
+using DiskAccessLibrary;
 using System;
 using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.IO;
-using System.Text;
-using System.Threading;
 using System.Windows.Forms;
 using System.Windows.Forms;
-using DiskAccessLibrary;
+using DiskAccessLibrary.Mod;
 
 
 namespace ISCSIConsole
 namespace ISCSIConsole
 {
 {
     public partial class CreateRAMDiskForm : Form
     public partial class CreateRAMDiskForm : Form
     {
     {
-        private RAMDisk m_ramDisk;
+        private Disk m_ramDisk;
 
 
         public CreateRAMDiskForm()
         public CreateRAMDiskForm()
         {
         {
@@ -27,23 +22,47 @@ namespace ISCSIConsole
 
 
         private void btnOK_Click(object sender, EventArgs e)
         private void btnOK_Click(object sender, EventArgs e)
         {
         {
-            int size = (int)numericDiskSize.Value * 1024 * 1024;
-            RAMDisk disk;
-            try
+            if (MbRadioButton.Checked)
+            {
+                var size = (int)numericDiskSize.Value * 1024 * 1024;
+                RAMDisk disk;
+                try
+                {
+                    disk = new RAMDisk(size);
+                }
+                catch (OutOfMemoryException)
+                {
+                    MessageBox.Show("Not enough memory available", "Error");
+                    return;
+                }
+                m_ramDisk = disk;
+            }
+            else if (GbRadioButton.Checked)
             {
             {
-                disk = new RAMDisk(size);
+                var size = (int)numericDiskSize.Value;
+                UnmanagedLargeRamDisk disk = new UnmanagedLargeRamDisk(size); ;
+                try
+                {
+                    disk.Allocate();
+                }
+                catch (OutOfMemoryException)
+                {
+                    disk.Free();
+                    MessageBox.Show("Not enough memory available", "Error");
+                    return;
+                }
+                m_ramDisk = disk;
             }
             }
-            catch (OutOfMemoryException)
+            else
             {
             {
-                MessageBox.Show("Not enough memory available", "Error");
+                MessageBox.Show("What chosen?");
                 return;
                 return;
             }
             }
-            m_ramDisk = disk;
             this.DialogResult = DialogResult.OK;
             this.DialogResult = DialogResult.OK;
             this.Close();
             this.Close();
         }
         }
 
 
-        public RAMDisk RAMDisk
+        public Disk RAMDisk
         {
         {
             get
             get
             {
             {

+ 9 - 0
ISCSIConsole/Helpers/LockUtils.cs

@@ -8,6 +8,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
 using DiskAccessLibrary;
 using DiskAccessLibrary;
+using DiskAccessLibrary.Mod;
 
 
 namespace ISCSIConsole
 namespace ISCSIConsole
 {
 {
@@ -31,6 +32,14 @@ namespace ISCSIConsole
             {
             {
                 ((RAMDisk)disk).Free();
                 ((RAMDisk)disk).Free();
             }
             }
+            else if (disk is LargeRamDisk)
+            {
+                ((LargeRamDisk)disk).Free();
+            }
+            else if (disk is UnmanagedLargeRamDisk)
+            {
+                ((UnmanagedLargeRamDisk)disk).Free();
+            }
 #if Win32
 #if Win32
             else if (disk is PhysicalDisk)
             else if (disk is PhysicalDisk)
             {
             {