Regex - Validate IP

by Luke 2. November 2011 21:39

I was just doing some validation for a WOL application I'm making and needed to verify the IP was correct, here's my approach. I'm wondering if it could be any shorter / more efficient?

 

([0-2]?[0-9]{1,2}\.){3}([0-2]?[0-9]{1,2})

Tags: ,

.NET Development

C#.NET Scripting Support In Your Applications

by Luke 1. November 2010 23:11

Hi all,

This is a technical blog post today that I hope will be fairly useful to everyone out there. I have wondered how to actually include scripting abilities within my applications and today I decided to figure it out. The process is actually pretty simple. You need to include two namespaces which are System.CodeDom.Compiler and System.Reflection to do this (the first compiles your 'script' while the second lets you use the result) and then you can do whatever you want from there. Here's one I made earlier...

private void btnRun_Click(object sender, EventArgs e)
  {
    CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("C#");
    CompilerParameters codeParams = new CompilerParameters();
    CompilerResults codeResults = null;
    codeParams.GenerateExecutable = false;
    codeParams.GenerateInMemory = true;
    codeParams.IncludeDebugInformation = false;
    codeParams.ReferencedAssemblies.Add("System.dll");
    codeParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
    codeResults = codeProvider.CompileAssemblyFromSource(
                        codeParams,
                        new string[] { txtSourceInput.Text }
                        );

    CompilerErrorCollection codeErrors = cResults.Errors;

    Type[] resultTypes = cResults.CompiledAssembly.GetTypes();
    object o = codeResults.CompiledAssembly.CreateInstance(
                  resultTypes[0].FullName
                  );
    MethodInfo[] m = resultTypes[0].GetMethods();
    m[0].Invoke(o, null);
}

There's a lot to note here:

 

  1. Lines 9 and 10 are adding referenced assemblies programmatically but this is the same as right clicking "References" in your project and clicking "Add Reference" as this makes the methods within those assemblies available to the dynamically compiled code (the user's script). I was testing this by popping up a messagebox so needed System.Windows.Forms.dll but you could add anything here that would work using the "Add Reference" option of a normal project.
  2. Line 11 uses an array of strings, I'm not sure why but for a standard user script you can just do what I've done and enter the whole text box as the first element.
  3. Line 15 shows the retrieval of the compile errors collection which is IMPORTANT! If you don't check this for errors then your application will likely crash due to bad end-user code. I was just doing this as testing so I haven't added anything to actually check the collection but if "codeErrors.HasErrors" is false then it's good to go.
  4. Line 17 creates the type by using the FULL NAME If you do not do this you will get the exception "Non-static method requires a target" unless you execute static methods.
  5. The remaining lines are NOT good code and you shouldn't do things this way in your live applications but this is fine as an example. I'm showing the way to get the types, create an instance, get the methods of that type and then how to invoke the first method of the instance of that type. You can easily modify this code to check for an expected type and method and provide parameters as needed.
When you come to test this you must feed it fully correct C# or the CompilerErrorCollection will have errors. So, for example, you cannot try to compile "MessageBox.Show("HI!!");" but you can compile:

 

namespace MyDynamicNamespace
{
	public class MyDynamicClass
	{
		public void MyDynamicMethod() 
		{
			MessageBox.Show("This is a test");
		}

	}

}

Tags: , , ,

.NET Development

Screenshot Code

by Luke 23. September 2010 22:55

This is very simple but I wanted to test the Syntax highlighter I just installed on the blog.

001using System;
002using System.IO;
003using System.IO.Compression;
004using System.Drawing;
005using System.Drawing.Imaging;
006using System.Collections.Generic;
007using System.Windows.Forms;
008
009    class Screenshot
010    {
011        List<Bitmap> _screenImages = new List<Bitmap>();
012        Graphics _gfx;
013
014        /// <summary>
015        /// Creates a new Screenshot object for taking, saving and compressing screenshots
016        /// </summary>
017        public Screenshot()
018        {
019        }
020
021        /// <summary>
022        /// Get a stream for the selected image
023        /// </summary>
024        /// <param name="index">zero-based index of the image</param>
025        /// <param name="compress">use compression or not</param>
026        /// <returns>Stream</returns>
027        public Stream this[int index, bool compress]
028        {
029            get
030            {
031                if (index >= 0 && index <= _screenImages.Count)
032                {
033                    MemoryStream[] ms = new MemoryStream[] { new MemoryStream(), new MemoryStream() };
034                    _screenImages[index].Save(ms[0], ImageFormat.Bmp);
035                    if (compress)
036                    {
037                        compressOutput(ms[0], ms[1]);
038                        ms[0].Close();
039                        ms[0] = null;
040                        ms[1].Seek(0, SeekOrigin.Begin);
041                        return ms[1];
042                    }
043                    else
044                    {
045                        ms[0].Seek(0, SeekOrigin.Begin);
046                        return ms[0];
047                    }
048                }
049                return null;
050            }
051        }
052        /// <summary>
053        /// Get a stream for the selected image
054        /// </summary>
055        /// <param name="index">zero-based index of the image</param>
056        /// <param name="compress">use compression or not</param>
057        /// <param name="format">type of image to return</param>
058        /// <returns>Stream</returns>
059        public Stream this[int index, bool compress, ImageFormat format]
060        {
061            get
062            {
063                if (index >= 0 && _screenImages.Count < index)
064                {
065                    MemoryStream[] ms = new MemoryStream[1];
066                    _screenImages[index].Save(ms[0], format);
067                    if (compress)
068                    {
069                        compressOutput(ms[0], ms[1]);
070                        ms[0].Close();
071                        ms[0] = null;
072                        ms[1].Seek(0, SeekOrigin.Begin);
073                        return ms[1];
074                    }
075                    else
076                    {
077                        ms[0].Seek(0, SeekOrigin.Begin);
078                        return ms[0];
079                    }
080                }
081                return null;
082            }
083        }
084
085        public int Count
086        {
087            get { return _screenImages.Count; }
088        }
089
090        /// <summary>
091        /// Capture all screens to memory
092        /// </summary>
093        public void CaptureAllScreens()
094        {
095            _screenImages.Clear();
096            foreach (Screen x in Screen.AllScreens)
097            {
098                Bitmap tmp = new Bitmap(x.Bounds.Width, x.Bounds.Height, PixelFormat.Format32bppArgb);
099                _gfx = Graphics.FromImage(tmp);
100                _gfx.CopyFromScreen(0, 0, 0, 0, x.Bounds.Size, CopyPixelOperation.SourceCopy);
101                _screenImages.Add(tmp);
102            }
103        }
104
105        /// <summary>
106        /// Capture only the primary screen
107        /// </summary>
108        public void CapturePrimary()
109        {
110            _screenImages.Clear();
111            Bitmap tmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
112            _gfx = Graphics.FromImage(tmp);
113            _gfx.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
114            _screenImages.Add(tmp);
115        }
116        /// <summary>
117        /// Capture a specific screen from the Screen collection
118        /// </summary>
119        /// <param name="screen">Screen object</param>
120        public void CapureScreen(Screen screen)
121        {
122            _screenImages.Clear();
123            Bitmap tmp = new Bitmap(screen.Bounds.Width, screen.Bounds.Height, PixelFormat.Format32bppArgb);
124            _gfx = Graphics.FromImage(tmp);
125            _gfx.CopyFromScreen(0, 0, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy);
126            _screenImages.Add(tmp);
127        }
128
129        /// <summary>
130        /// Compress the input stream to the output stream using DeflateStream
131        /// </summary>
132        /// <param name="source">source stream</param>
133        /// <param name="destination">destination stream</param>
134        void compressOutput(Stream source, Stream destination)
135        {
136            DeflateStream ds = new DeflateStream(destination, CompressionMode.Compress);
137            byte[] buffer = new byte[2048];
138            int bytesRead = 0;
139            source.Seek(0, SeekOrigin.Begin);
140            bytesRead = source.Read(buffer, 0, buffer.Length);
141            while (bytesRead > 0)
142            {
143                ds.Write(buffer, 0, bytesRead);
144                bytesRead = source.Read(buffer, 0, buffer.Length);
145            }
146            ds.Flush();
147        }
148    }
149

Tags:

.NET Development

Virtualization and VHD Files

by Luke 30. May 2010 20:34

A while ago I became very interested in virtualization and how Microsoft Virtual PC works. I quickly came up against VHD (Virtual Hard Disk) files and after learning a little about them I realised that you could use them to start learning 32-bit Assembly and build your own bootloader or operating system. All pretty obvious stuff but it all seemed so magical... so I looked for a good interface to let me edit VHD files and couldn't really find anything that was as visual as I wanted which meant it was time to start coding.

After reading the specification for VHD files (which is here) I learned that there are three types of VHD file which are Fixed, Dynamic and Differencing. The most basic of these is the fixed disk type which is just one file with a block of data representing a hard disk surrounded by a header and a footer. The dynamic disk grows by block sizes as you add data to it but never goes beyond the maximum capacity. This is how you can have a virtualized 60Gb drive taking up only 4Gb - it is because the actual space used is only what is needed rather than the full allocation as is the case with fixed virtual disks. I won't go into differencing disks in this post because I did nothing with them but they are used to represent the differences between an existing VHD and another state of that VHD. A differencing VHD file relies on having a parent which can be a fixed, dynamic or even another differencing disk.

Footer Format

All VHD disk types share a common footer format which is detailed in the VHD format specification document but here's the brief version.

Hard Disk Footer Fields Size (bytes)
Cookie 8
Features 4
File Format Version 4
Data Offset 8
Time Stamp 4
Creator Application 4
Creator Version 4
Creator Host OS 4
Original Size 8
Current Size 8
Disk Geometry 4
Disk Type 4
Checksum 4
Unique Id 16
Saved State 1
Reserved 427

Using this table you could build an object to easily read and modify these values from the VHD files footer. Doing this would then allow you to manipulate fixed disks by changing their size (Current Size) or doing other funky things. To save the footer as a fully functional FIXED DISK VHD file you save out the data block as large as needed but in multiples of a 'block' size and end with the 512 byte footer as detailed above.

When any changes are made you must re-create the Checksum which can be done like so (this is an example from my code, don't forget that your variables names are likely to be different).

 

[code:c#]public void UpdateChecksum()
        {
            uint uChecksum = 0;
            byte[] tmp = new byte[512];
            this.Checksum = 0;
            Array.Copy(_cookie, 0, tmp, 0, _cookie.Length);
            Array.Copy(_features, 0, tmp, 8, _features.Length);
            Array.Copy(_fileFormatVersion, 0, tmp, 12, _fileFormatVersion.Length);
            Array.Copy(_dataOffset, 0, tmp, 16, _dataOffset.Length);
            Array.Copy(_timeStamp, 0, tmp, 24, _timeStamp.Length);
            Array.Copy(_createApp, 0, tmp, 28, _createApp.Length);
            Array.Copy(_creatorVersion, 0, tmp, 32, _creatorVersion.Length);
            Array.Copy(_creatorHostOS, 0, tmp, 36, _creatorHostOS.Length);
            Array.Copy(_originalSize, 0, tmp, 40, _originalSize.Length);
            Array.Copy(_currentSize, 0, tmp, 48, _currentSize.Length);
            Array.Copy(_diskGeometry, 0, tmp, 56, _diskGeometry.Length);
            Array.Copy(_diskType, 0, tmp, 60, _diskType.Length);
            Array.Copy(_checksum, 0, tmp, 64, _checksum.Length);
            Array.Copy(_uniqueID, 0, tmp, 68, _uniqueID.Length);
            tmp[84] = _savedState;
            Array.Copy(_reserved, 0, tmp, 85, _reserved.Length);

            foreach (byte b in tmp)
                uChecksum += b;

            this.Checksum = ~uChecksum;
        }
    }[/code]

There are a few things here to take note of. Firstly, the checksum is calculated by simply adding up all the bytes so this is a lot of lines to do really not that much work. The second is the unary bitwise NOT operator ~ (tilde) as this performs a one's complement NOT operation on the checksum.

Finally...

If you're interested in programatically manipulating VHD files this post might help you get started and I would be interested to hear from you if you do something interesting with virtualisation. I may someday finish my VHD project and make a bootloader and if that day comes I'll post it for download on this site!

Tags: , ,

.NET Development

About the author

Luke is a computer programmer from England with a keen interest in .NET development.