<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Red Stars &#187; Technology</title>
	<atom:link href="http://blog.red-stars.net/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.red-stars.net</link>
	<description>Programming, food, and rambling</description>
	<lastBuildDate>Sat, 08 May 2010 16:19:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP string concatenation speed</title>
		<link>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/#comments</comments>
		<pubDate>Sat, 08 May 2010 16:18:39 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=224</guid>
		<description><![CDATA[Something I have always wondered is the speed difference between concatenation strings with in-string variables verses the . operator. I've always assumed . would be much faster, and today I found out. $amount = 0x1FFFF; $start = microtime(true); while ($amount--) $throwAway = "this is a test at the $amount point!"; //$throwAway = "this is a [...]]]></description>
			<content:encoded><![CDATA[<p>Something I have always wondered is the speed difference between concatenation strings with in-string variables verses the . operator. I've always assumed . would be much faster, and today I found out.</p>
<pre class="brush:php">$amount = 0x1FFFF;
$start = microtime(true);

while ($amount--)
	$throwAway = "this is a test at the $amount point!"; //$throwAway = "this is a test at the ". $amount ." point!";

	echo "Time: ". (microtime(true) - $start);</pre>
<p>Exactly as expected, leaving it up to in-string parsing of variables ended up with a bench mark time of 0.1574 and manually concatenating in the variable was 0.1384, which is not a huge difference, but I wanted to see how this would scale when doing multiple concatenations. The string was changed to $throwAway = "this is ". $amount ." a test ". $amount ." at the ". $amount ." point!"; and it's respective in-string.</p>
<p>What I found is that it actually scales to <em>in-string</em> far better! In-string averaged to 0.3235 and manual to 0.3597. After some research it turns out this is because it does a single large concatenation while manually doing it could perform the operation 3 separate times.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/php-string-concatenation-speed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Array Performance</title>
		<link>http://blog.red-stars.net/uncategorized/php-array-performance/</link>
		<comments>http://blog.red-stars.net/uncategorized/php-array-performance/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 13:42:02 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=204</guid>
		<description><![CDATA[Index Checking The functional difference between array_key_exists($key, $array) and isset($array[$key]) is that isset returns false when the key exists but contains null. Functionality aside, there is a demonstrable performance difference. $dataSet = array(); $size = 0x1FFFF; $i = $size; while ($i--) $dataSet[$i] = $i+1; $start = microtime(true); $i = $size; while ($i--) array_key_exists($i, $dataSet); //isset($dataSet[$i]); [...]]]></description>
			<content:encoded><![CDATA[<span id="Index_Checking"><h3>Index Checking</h3></span>
<p>The functional difference between array_key_exists($key, $array) and isset($array[$key]) is that isset returns false when the key exists but contains null. Functionality aside, there is a demonstrable performance difference.</p>
<pre class="brush:php">$dataSet = array();
$size = 0x1FFFF;

$i = $size;
while ($i--)
	$dataSet[$i] = $i+1;

$start = microtime(true);

$i = $size;
while ($i--)
	array_key_exists($i, $dataSet); //isset($dataSet[$i]);

echo "Time: ". (microtime(true) - $start);</pre>
<p>Sure enough, after averaging a few benchmarks together the outcome was clear.</p>
<dl>
<dt>isset</dt>
<dd>0.0248870849609</dd>
<dt>array_key_exists</dt>
<dd>0.604112148285</dd>
</dl>
<p>When performance is important target isset() when applicable. It's even possible to use a fall through to increase performance, here's an example from my Options class: if (!isset($this->_options[$resolvedName]) &#038;& !array_key_exists($resolvedName, $this->_options))</p>
<span id="Append_Performance"><h3>Append Performance</h3></span>
<p>In the following test case there was no performance difference between usage of append or directly addressing an index.</p>
<pre class="brush:php">$dataSet = array();
$size = 0x1FFFF;
$i = $size;

$start = microtime(true);

while ($i--)
	$dataSet[] = $i+1; //$dataSet[$i] = $i+1;

echo "Time: ". (microtime(true) - $start);</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/uncategorized/php-array-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remodeling PHP&#8217;s compact()/extract() into an OO Pattern</title>
		<link>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 16:38:47 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=185</guid>
		<description><![CDATA[A common usage, at least for extract(), has been to allow an associative array to be passed to a function for use as named optional parameters, however, there is a lot wrong with dumping an array into the symbol table and then checking if what you want exists or not. I have designed a pattern [...]]]></description>
			<content:encoded><![CDATA[<p>A common usage, at least for extract(), has been to allow an associative array to be passed to a function for use as named optional parameters, however, there is <em>a lot</em> wrong with dumping an array into the symbol table and then checking if what you want exists or not.</p>
<p>I have designed a pattern that allows an object to accept and address public level optional named arguments without the problems that could be associated with the compact()/extract() pattern. This pattern does require at least PHP 5.3 (uses late static binding) and overloads __get/__set preventing the child class from doing so.</p>
<p><span id="more-185"></span></p>
<span id="Usage"><h2>Usage</h2></span>
<p>Possible optional keys are defined as class constants, if one is addressed or set that is undefined an exception will be thrown. Instead of using extract(), the inherited SetOptionalProperties($array) method should be called to set the values. The value's can be addressed by it's constants name like it's a property, like $instance->ConstantName. Default values can be given by overloading the protected static $_defaultOptions member. The example shows this in with more detail:</p>
<span id="Example"><h3>Example</h3></span>
<pre class="brush:php">class MyClass extends Options {
	public $Property;

	const MyOption = "MyOption";
	const AnotherOption = "AnotherOption";

	protected static $_defaultOptions = array(self::AnotherOption = "default value!");

	public function __construct($property, $options = array()) {
		$this->Property = $property;
		$this->SetOptionalProperties($options); // this allows Options to access the optional values.
	}
}

$instance = new MyClass("property's value", array(MyClass::MyOption = "my option value!"));
echo "MyOption: '{$instance->MyOption}', AnotherOption: '{$instance->AnotherOption}', Property: '{$instance->Property}'";</pre>
<span id="Output:"><h4>Output:</h4></span>
<pre>MyOption: 'my option value!', AnotherOption: 'default value!', Property: 'property's value'</pre>
<span id="Class"><h3>Class</h3></span>
<pre class="brush:php">abstract class Options {
	/// The array which stores the optional values
	private $_options = array();

	/// This array should be overloaded by child classes if default values are going to be used.
	protected static $_defaultOptions = array();

	/// Use Options::$AllowUndefinedProperties = true; to prevent exceptions from being thrown when an undefined
	/// property is set or fetched.
	public static $AllowUndefinedProperties = false;

	public function &#038;__get($name) {
		$resolvedName = $this->ResolveOptionName($name);

		// Do we have a value? Use the isset/array_key_exists fall through to speed up access to existing non-null entries.
		if (!isset($this->_options[$resolvedName]) &#038;& !array_key_exists($resolvedName, $this->_options)) {
			// Do we have a default value?
			if (array_key_exists($resolvedName, static::$_defaultOptions))
				$this->_options[$resolvedName] = static::$_defaultOptions[$resolvedName];
			else
				$this->_options[$resolvedName] = null;
		}

		return $this->_options[$resolvedName];
	}

	public function __set($name, $value) {
		$resolvedName = $this->ResolveOptionName($name);

		return $this->_options[$resolvedName] = $value;
	}

	public function __isset($name) {
		$resolvedName = $this->ResolveOptionName($name);

		return isset($this->_options[$resolvedName]);
	}

	public function __unset($name) {
		$resolvedName = $this->ResolveOptionName($name);

		unset($this->_options[$resolvedName]);
	}

	/**
	 * Set the optional properties for the class.
	 * @param $options A [ClassConstant] = Value indexed array of optional properties.
	 */
	protected function SetOptionalProperties(array $options) {
		$this->_options = $options;
	}

	/// Resolve any aliases name to the proper name.
	private function ResolveOptionName($name) {
		$constant = "static::". $name;

		if (defined($constant))
			return constant($constant);
		else if (!self::$AllowUndefinedProperties)
			throw new Exception("Undefined property or option '$name' being set in ". get_called_class());

	}
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/remodeling-phps-compactextract-into-an-oo-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Queryable Food Nutrition Database</title>
		<link>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:42:06 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=175</guid>
		<description><![CDATA[The USDA releases data for food nutritional information. I've taken this data and loaded it into my local database, and created a front end to allow it to be queryable. Database Schema Sample Queries Top 150 protein containing foods SELECT Foods.Description, concat( NutrientValue, Units ) AS Value FROM Foods JOIN NutrientDefinitions ON ( NutrientName = [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ars.usda.gov/Services/docs.htm?docid=17478">The USDA</a> releases data for food nutritional information. I've taken this data and loaded it into my local database, and created <a href="http://fooddb.red-stars.net">a front end to allow it to be queryable.</a></p>
<span id="Database_Schema"><h2>Database Schema</h2></span>
<p><img src="http://red-stars.net/pictures/fooddb.png" alt="database schema" /></p>
<p><span id="more-175"></span></p>
<span id="Sample_Queries"><h2>Sample Queries</h2></span>
<span id="Top_150_protein_containing_foods"><h3>Top 150 protein containing foods</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM Foods<br />
JOIN NutrientDefinitions ON ( NutrientName = 'Protein' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
ORDER BY NutrientValue DESC<br />
LIMIT 150</code></p>
<span id="Top_100_protein_containing_legumes"><h3>Top 100 protein containing legumes</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM FoodGroups<br />
JOIN Foods<br />
USING ( CategoryID )<br />
JOIN NutrientDefinitions ON ( NutrientName = 'Protein' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
WHERE FoodGroups.Description like '%LEGUME%'<br />
ORDER BY NutrientValue DESC<br />
LIMIT 100</code></p>
<span id="Top_150_iron_containing_foods"><h3>Top 150 iron containing foods</h3></span>
<p><code>SELECT Foods.Description, concat( NutrientValue, Units ) AS Value<br />
FROM Foods<br />
JOIN NutrientDefinitions ON ( NutrientName like '%Iron%' )<br />
JOIN NutrientData<br />
USING ( NutrientID, FoodID )<br />
ORDER BY NutrientValue DESC<br />
LIMIT 150</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/queryable-food-nutrition-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Message Hasher</title>
		<link>http://blog.red-stars.net/technology/software/message-hasher/</link>
		<comments>http://blog.red-stars.net/technology/software/message-hasher/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 01:09:09 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=168</guid>
		<description><![CDATA[A small web-based message hasher, good for generating hashes of small amounts of text. No binary support yet, but it's planned via file uploads! #hasherform { display: inline-block; width: 400px; } #hasherform .wide { width: 100%; } #hasherform form * { margin-top: 8px; } #hasherform textarea { height: 10em; } Short Message Hasher Algorithm md2 [...]]]></description>
			<content:encoded><![CDATA[<p>A small web-based message hasher, good for generating hashes of small amounts of text. No binary support yet, but it's planned via file uploads!</p>
<p><span id="more-168"></span><br />
<style type="text/css">
	#hasherform {
		display: inline-block;
		width: 400px;
	}
	#hasherform .wide {
		width: 100%;
	}
	#hasherform form * {
		margin-top: 8px;
	}
	#hasherform textarea {
		height: 10em;
	}
</style>
<fieldset id="hasherform">
<legend>Short Message Hasher</legend>
<form method="get" target="/index.php">
		<label for="algorithm">Algorithm</label></p>
<select name="algorithm" class="wide" id="algorithm">
<option value="md2">md2</option>
<option value="md4">md4</option>
<option value="md5">md5</option>
<option value="sha1">sha1</option>
<option value="sha256">sha256</option>
<option value="sha384">sha384</option>
<option value="sha512">sha512</option>
<option value="ripemd128">ripemd128</option>
<option value="ripemd160">ripemd160</option>
<option value="ripemd256">ripemd256</option>
<option value="ripemd320">ripemd320</option>
<option value="whirlpool">whirlpool</option>
<option value="tiger128,3">tiger128,3</option>
<option value="tiger160,3">tiger160,3</option>
<option value="tiger192,3">tiger192,3</option>
<option value="tiger128,4">tiger128,4</option>
<option value="tiger160,4">tiger160,4</option>
<option value="tiger192,4">tiger192,4</option>
<option value="snefru">snefru</option>
<option value="gost">gost</option>
<option value="adler32">adler32</option>
<option value="crc32">crc32</option>
<option value="crc32b">crc32b</option>
<option value="haval128,3">haval128,3</option>
<option value="haval160,3">haval160,3</option>
<option value="haval192,3">haval192,3</option>
<option value="haval224,3">haval224,3</option>
<option value="haval256,3">haval256,3</option>
<option value="haval128,4">haval128,4</option>
<option value="haval160,4">haval160,4</option>
<option value="haval192,4">haval192,4</option>
<option value="haval224,4">haval224,4</option>
<option value="haval256,4">haval256,4</option>
<option value="haval128,5">haval128,5</option>
<option value="haval160,5">haval160,5</option>
<option value="haval192,5">haval192,5</option>
<option value="haval224,5">haval224,5</option>
<option value="haval256,5">haval256,5</option>
</select>
<p>
		<label for="message">Message</label><br />
		<textarea name="data" class="wide" id="message"></textarea></p>
<input type="checkbox" name="raw" id="rawcheckbox" /><label for="rawcheckbox">Return as raw data</label></p>
<input type="submit" value="Hash!" />
	</form>
</fieldset>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/message-hasher/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GraphicsPath Front &#8211; Vector drawing software</title>
		<link>http://blog.red-stars.net/technology/program/graphicspath-front-vector-drawing-software/</link>
		<comments>http://blog.red-stars.net/technology/program/graphicspath-front-vector-drawing-software/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 02:12:49 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Program]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=154</guid>
		<description><![CDATA[GraphicsPath Front is vector drawing software based upon the GraphicsPath .net class. Download (source and binaries) &#8212; Execute \bin\debug\GraphicsPathFront.exe or compile from source. Some of the notable features include: Save/load vectorized graphics, or save in numerous rasterized formats. Configurable and snap-to'able grid. Live preview of what's being drawn, including rendering in real-time. The ability to [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://red-stars.net/pictures/graphicspathfront.png" alt="screenshot" /></p>
<p>GraphicsPath Front is vector drawing software based upon the GraphicsPath .net class.</p>
<p><a href="http://red-stars.net/programs/GraphicsPathFront.zip">Download</a> (source and binaries) &mdash; Execute <code>\bin\debug\GraphicsPathFront.exe</code> or compile from source.</p>
<p>Some of the notable features include:</p>
<ul>
<li>Save/load vectorized graphics, or save in numerous rasterized formats.</li>
<li>Configurable and snap-to'able grid.</li>
<li>Live preview of what's being drawn, including rendering in real-time.</li>
<li>The ability to render as mouse input. (Need to see the videos to understand!)
<ul>
<li><a href="http://red-stars.net/pictures/renderingfont.avi">Rendering an elaborate font as mouse input to Microsoft Paint.</a></li>
<li><a href="http://red-stars.net/pictures/renderingcard.avi">Rendering a vectorized playing card as mouse input to Microsoft Paint.</a></li>
</li>
</ul>
</ul>
<p>There are several limitations in this program due to the limits of the underlying GraphicsPath class. Though the code is in place to do so, nodes can not be directly edited once created, for example. Nor can different paths be drawn using different pens.</p>
<p><span id="more-154"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#DrawingGrid_class">DrawingGrid class</a>
	</li>
	<li>
		<a href="#DrawingTools_class">DrawingTools class</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<p>Below are some samples of the code from the project. Note that some of the limitations of the code highlighting plugin are apparent in generics being passed as generic types, and with XML comments.</p>
<span id="DrawingGrid_class"><h3>DrawingGrid class</h3></span>
<p>The class which manages the drawing of and mouse handling for the grid.</p>
<pre class="brush:csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace CrayonAutomaton {
    ///
<summary>
    /// Create a GraphicsPath based grid in memory.
    /// </summary>

    class DrawingGrid {
        ///
<summary>An event that is triggered when ever the grid is regenerated and needs to be redisplayed.</summary>

        public event Action GridUpdated;

        ///
<summary>Gets or Sets the total area of the grid.</summary>

        public Size GridSize {
            get { return _gridSize; }
            set {
                _gridSize = value;
                makeGrid();
            }
        }
        ///
<summary>Gets or Sets the size of each grid cell.</summary>

        public Size CellSize {
            get { return _cellSize; }
            set {
                _cellSize = value;
                makeGrid();
            }
        }
        ///
<summary>Gets or Sets the color of the drawn grid.</summary>

        public Color GridColor {
            get { return _gridColor; }
            set {
                _gridColor = value;
                makeGrid();
            }
        }
        ///
<summary>Gets the grid vector</summary>

        public GraphicsPath Grid { get { return path; } }
        ///
<summary>Gets or Sets if 'GridPositionFromPoint()' snaps passed Point to the grid.</summary>

        public bool SnapPointsToGrid { get; set; }
        ///
<summary>Gets or Sets if grid is drawn when asked to</summary>

        public bool Visible {
            get { return _visible; }
            set {
                _visible = value;
                if (GridUpdated != null)
                    GridUpdated();
            }
        }

        private Size _gridSize;
        private Size _cellSize;
        private Color _gridColor;
        private bool _visible;
        private bool noRendering = false;
        private GraphicsPath path = new GraphicsPath();

        public DrawingGrid(Size gridSize) : this(gridSize, new Size(20, 20), Color.LightGray, true) { }
        public DrawingGrid(Size gridSize, Size cellSize) : this(gridSize, cellSize, Color.LightGray, true) { }
        public DrawingGrid(Size gridSize, Size cellSize, Color gridColor) : this(gridSize, cellSize, gridColor, true) { }
        ///
<summary>Creates an instance of a class for drawing a grid on an image</summary>

        ///
<param name="gridSize">Total area of grid to draw</param>
        ///
<param name="cellSize">Size of each cell to draw</param>
        ///
<param name="gridColor">Color to draw the grid</param>
        ///
<param name="snapPointsToGrid">Determins if 'GridPositionFromPoint()' snaps passed Point to the grid.</param>
        public DrawingGrid(Size gridSize, Size cellSize, Color gridColor, bool snapPointsToGrid) {
            BeginUpdate();
            GridSize = gridSize;
            CellSize = cellSize;
            GridColor = gridColor;
            SnapPointsToGrid = snapPointsToGrid;
            Visible = true;
            EndUpdate();
        }

        ///
<summary>'Snaps' the passed point to grid, returns as-is if snapping to grid is disabled.</summary>

        public Point GridPositionFromPoint(Point point) {
            if (!SnapPointsToGrid)
                return point;
            Point gridPoint = new Point();
            gridPoint.X = (int)Math.Floor((decimal)(point.X / CellSize.Width)) * CellSize.Width;
            gridPoint.Y = (int)Math.Floor((decimal)(point.Y / CellSize.Height)) * CellSize.Height;
            if (point.X % CellSize.Width > CellSize.Width / 2)
                gridPoint.X += CellSize.Width;
            if (point.Y % CellSize.Height > CellSize.Height / 2)
                gridPoint.Y += CellSize.Height;
            return gridPoint;
        }
        ///
<summary>Draws grid to Graphic 'g' if Visible, regenerates grid if 'size' is different</summary>

        public void DrawToGraphic(Graphics g, Size size) {
            if (Visible) {
                if (size != GridSize)
                    GridSize = size;
                g.DrawPath(new Pen(GridColor), Grid);
            }
        }
        ///
<summary>Draws grid to Graphic 'g' if Visible</summary>

        public void DrawToGraphic(Graphics g) {
            if (Visible)
                g.DrawPath(new Pen(GridColor), Grid);
        }
        ///
<summary>Prevents (costly) regeneration of grid during property changes.</summary>

        public void BeginUpdate() { noRendering = true; }
        ///
<summary>Allows grid to be regenerated by property changes again, also regenerates grid.</summary>

        public void EndUpdate() {
            noRendering = false;
            makeGrid();
        }

        ///
<summary>(Re)render the grid to the 'path' variable.</summary>

        private void makeGrid() {
            /* Do not render if durring an 'update' */
            if (noRendering)
                return;

            int cellX = CellSize.Width;
            int cellY = CellSize.Height;

            /* Clear old grid */
            path.Reset();

            /* Add vertical lines (columes) */
            do {
                path.StartFigure();
                path.AddLine(cellX, 0, cellX, GridSize.Height);
            } while ((cellX += CellSize.Width) < GridSize.Width);

            /* Add horizontal lines (rows) */
            do {
                path.StartFigure();
                path.AddLine(0, cellY, GridSize.Width, cellY);
            } while ((cellY += CellSize.Height) < GridSize.Height);

            /* Call all grid updated events */
            if (GridUpdated != null)
                GridUpdated();
        }
    }
}</pre>
<span id="DrawingTools_class"><h3>DrawingTools class</h3></span>
<p>A collection of drawing tools and an abstract class and event driven drawing tool system.</p>
<pre class="brush:csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace CrayonAutomaton {
    ///
<summary>A collection of DrawingTool</summary>

    class DrawingTools {
        ///
<summary>Event for when an update is required.</summary>

        public event Action PreviewUpdate;

        ///
<summary>Gets or Sets the currently in-use drawing tool.</summary>

        public DrawingTool Tool { get; set; }
        ///
<summary>A collection of DrawingTools</summary>

        public List<DrawingTool> Tools { get; set; }
        ///
<summary>Functions which are called on the mouse input before the mouse data is used.</summary>

        public IEnumerable<Func<Point, Point>> MouseInputFilters {
            get { return _mouseInputFilters; }
            set {
                performToAllTools(delegate(DrawingTool tool) { tool.MouseInputFilters = value; });
                _mouseInputFilters = value;
            }
        }
        public GraphicsPath Path {
            get { return _path; }
            set {
                performToAllTools(delegate(DrawingTool tool) { tool.Path = value; });
                _path = value;
            }
        }

        private GraphicsPath _path;
        private IEnumerable<Func<Point, Point>> _mouseInputFilters;

        public DrawingTools(GraphicsPath path, Func<Point, Point> mouseInputFilter/*, Control hookToSurface*/)
            : this(path, new[] { mouseInputFilter }) { }
        ///
<summary>Instances a usable collection of DrawingTool's</summary>

        ///
<param name="path">Path for the tools to draw to</param>
        public DrawingTools(GraphicsPath path, IEnumerable<Func<Point, Point>> mouseInputFilters/*, Control hookToSurface*/) {
            /* Instance all locally coded drawing tools */
            Tools = new List<DrawingTool>(new DrawingTool[] {
                new NullDrawingTool(),
                new LineDrawingTool(),
                new RectangleDrawingTool(),
                new EllipseDrawingTool(),
                new FreeDrawDrawingTool(),
                new TextDrawingTool()
            });

            /* Set-up all required members */
            performToAllTools(delegate(DrawingTool tool) { tool.ParentCollection = this; });
            Path = path;
            MouseInputFilters = mouseInputFilters;

            SetTool("");
        }

        public void Preview() {
            if (PreviewUpdate != null)
                PreviewUpdate();
        }
        public void HookToolsToSurface(Control surface) {

        }

        public bool SetTool(DrawingTool tool) { return SetTool(tool.Name); }
        ///
<summary>Changes the in-use tool based upon 'name'</summary>

        /// <returns>Returns 'true' if a tool is found and set, 'false' otherwise.</returns>
        public bool SetTool(string name) {
            foreach (DrawingTool curTool in Tools)
                if (curTool.Name == name) {
                    Tool = curTool;
                    return true;
                }
            return false;
        }

        private void performToAllTools(Action<DrawingTool> delegateFunction) {
            foreach (DrawingTool curTool in Tools)
                delegateFunction(curTool);
        }
    }

    abstract class DrawingTool : IEquatable<DrawingTool> {
        ///
<summary>Get the tools name</summary>

        public string Name { get { return _name; } }
        ///
<summary>A value indicating if the mouse is presently inside the drawing area</summary>

        public bool IsMouseInside { get; set; }
        public GraphicsPath Path { get; set; }
        public IEnumerable<Func<Point, Point>> MouseInputFilters { get; set; }
        public MouseButtons MouseButtonState { get; set; }
        public DrawingTools ParentCollection { get; set; }

        private string _name;

        protected Point mouseDownLocation;

        ///
<summary>Abstract class for drawing tools</summary>

        ///
<param name="name">Name of the drawing tool, must be unique</param>
        protected DrawingTool(string name) {
            _name = name;
            IsMouseInside = false;
        }

        ///
<summary>Call to pass the mouse down event to the in-use tool.</summary>

        public void MouseDown(Point point) {
            point = filterMouseInput(point);
            mouseDownLocation = point;
            mouseDown(point);
        }
        ///
<summary>Call to pass the mouse move event to the in-use tool.</summary>

        public void MouseMove(Point point) {
            point = filterMouseInput(point);
            mouseMove(point);
        }
        ///
<summary>Call to pass the mouse up event to the in-use tool.</summary>

        public void MouseUp(Point point) {
            point = filterMouseInput(point);
            mouseUp(point);
        }
        public void MouseLeave() {
            IsMouseInside = false;
            mouseLeave();
        }
        public void MouseEnter() {
            IsMouseInside = true;
            mouseEnter();
        }
        public void Render(Point currentMouseLocation) { Render(Path, currentMouseLocation); }
        public void Render(GraphicsPath path, Point currentMouseLocation) {
            render(path, filterMouseInput(currentMouseLocation));
        }

        protected virtual void mouseMove(Point point) {}
        protected virtual void mouseUp(Point point) { }

        ///
<summary>This function should be override if it's possible to render with mouseDownLocation and the currentMouseLocation.
        /// If this function is not overloaded, drawing is still possible, but preview rendering is not.</summary>

        protected virtual void render(GraphicsPath path, Point currentMouseLocation) { }
        ///
<summary>Override if mouse down detection is needed</summary>

        protected virtual void mouseDown(Point point) { }
        ///
<summary>Override if mouse enter detection is needed</summary>

        protected virtual void mouseEnter() { }
        ///
<summary>Override if mouse up detection is needed</summary>

        protected virtual void mouseLeave() { }

        ///
<summary>Returns passed point as processed by the list of provided filters in MouseFilterList</summary>

        protected Point filterMouseInput(Point point) {
            foreach (Func<Point, Point> curFilter in MouseInputFilters)
                point = curFilter(point);
            return point;
        }
        ///
<summary>Reorders the passed points so that point1 is to the upper left of point2</summary>

        /// <returns>Returns the distance between refactored point1 and point2</returns>
        protected Size orderPoints(ref Point point1, ref Point point2) {
            point1.X = Math.Min(point1.X, point2.X);
            point1.Y = Math.Min(point1.Y, point2.Y);
            point2.X = Math.Max(point1.X, point2.X);
            point2.Y = Math.Max(point1.Y, point2.Y);
            return new Size(point2.X - point1.X, point2.Y - point1.Y);
        }
        ///
<summary>Returns a rectangle from where MouseDown and mouseUpPoint occured</summary>

        protected Rectangle mouseDragRectangle(Point mouseUpPoint) {
            return new Rectangle(mouseDownLocation, orderPoints(ref mouseDownLocation, ref mouseUpPoint));
        }

        public override string ToString() { return Name; }
        public bool Equals(DrawingTool obj) { return obj.GetHashCode() == GetHashCode(); }
        public override int GetHashCode() { return Name.GetHashCode(); }
    }

    ///
<summary>A base level null drawing tool for default tool selection</summary>

    class NullDrawingTool : DrawingTool {
        public NullDrawingTool()
            : base(string.Empty) { }
    }

    ///
<summary>A DrawingTool for drawing single lines</summary>

    class LineDrawingTool : DrawingTool {
        public LineDrawingTool()
            : base("Line") { }

        protected override void render(GraphicsPath path, Point currentMouseLocation) {
            path.AddLine(mouseDownLocation, currentMouseLocation);
        }

        protected override void mouseUp(Point point) {
            Render(point);
        }
    }

    ///
<summary>A DrawingTool for drawing single rectangles</summary>

    class RectangleDrawingTool : DrawingTool {
        public RectangleDrawingTool()
            : base("Rectangle") { }

        protected override void render(GraphicsPath path, Point currentMouseLocation) {
            path.AddRectangle(mouseDragRectangle(currentMouseLocation));
        }

        protected override void mouseUp(Point point) {
            Render(point);
        }
    }

    ///
<summary>A DrawingTool for drawing single ellipses</summary>

    class EllipseDrawingTool : DrawingTool {
        public EllipseDrawingTool()
            : base("Ellipse") { }

        protected override void render(GraphicsPath path, Point currentMouseLocation) {
            path.AddEllipse(mouseDragRectangle(currentMouseLocation));
        }

        protected override void mouseUp(Point point) {
            Render(point);
        }
    }

    ///
<summary>A DrawingTool for 'free hand' drawing</summary>

    class FreeDrawDrawingTool : DrawingTool {
        Point lastPoint;

        public FreeDrawDrawingTool()
            : base("Free Draw") { }
        protected override void mouseDown(Point point) {
            lastPoint = point;
        }
        protected override void mouseMove(Point point) {
            if (MouseButtonState == MouseButtons.Left) {
                drawLine(point);
                lastPoint = point;
            }
        }
        protected override void mouseUp(Point point) {
            drawLine(point);
        }

        private void drawLine(Point point) {
            Path.AddLine(lastPoint, point);
        }
    }

    class TextDrawingTool : DrawingTool {
        public TextDrawingTool()
            : base("Text") { }

        enterTextDialog textDialog;

        protected override void mouseUp(Point point) {
            textDialog = new enterTextDialog(ParentCollection.Preview);
            if (textDialog.ShowDialog() == DialogResult.OK)
                render(Path, point);
        }

        void textDialog_PreviewUpdateEvent() {
        }

        protected override void render(GraphicsPath path, Point currentMouseLocation) {
            path.AddString(textDialog.EnteredText,
                textDialog.SelectedFont.FontFamily,
                (int)textDialog.SelectedFont.Style,
                textDialog.SelectedFont.Size,
                mouseDownLocation,
                StringFormat.GenericDefault);
        }
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/program/graphicspath-front-vector-drawing-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://red-stars.net/pictures/renderingfont.avi" length="1108164" type="video/x-msvideo" />
<enclosure url="http://red-stars.net/pictures/renderingcard.avi" length="216944" type="video/x-msvideo" />
		</item>
		<item>
		<title>Boggle.exe</title>
		<link>http://blog.red-stars.net/technology/program/boggle-exe/</link>
		<comments>http://blog.red-stars.net/technology/program/boggle-exe/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 01:54:28 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Program]]></category>

		<guid isPermaLink="false">http://blog.red-stars.net/?p=150</guid>
		<description><![CDATA[Boggle.exe is a computerized version of the Hasbro dice game. It's intended to be played by multiple people infront of the computer using pens and paper, no internet play is supported as it's ridiculously easy to cheat. The main neat feature of Boggle.exe over it's physical counterpart is a board solver. Once the game is [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://red-stars.net/pictures/boggle.png" alt="screenshot" /></p>
<p><em>Boggle.exe</em> is a computerized version of the Hasbro dice game. It's intended to be played by multiple people infront of the computer using pens and paper, no internet play is supported as it's ridiculously easy to cheat. The main neat feature of Boggle.exe over it's physical counterpart is a board solver. Once the game is over, all of the valid words inside of the board are shown and can be highlighted (see picture).</p>
<p><a href="http://red-stars.net/programs/Boggle.zip">Download</a> (source and executable) &mdash; Extract to it's own directory and run <code>\bin\debug\Boggle.exe</code>. words.txt must be in the same directory as the executable.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/program/boggle-exe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Windows 7 from and to the same hard drive</title>
		<link>http://blog.red-stars.net/technology/software/installing-windows-7-from-and-to-the-same-hard-drive/</link>
		<comments>http://blog.red-stars.net/technology/software/installing-windows-7-from-and-to-the-same-hard-drive/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 01:25:42 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=105</guid>
		<description><![CDATA[The reason why is pretty simple, DVDs are not remotely as fast as any other media, and in 2009, it's starting to show. Flash drives are larger, faster, and more versatile than DVDs, and they're costing less and less. But what about an older system that can not boot from USB storage? Well, there is [...]]]></description>
			<content:encoded><![CDATA[<p>The reason why is pretty simple, DVDs are not remotely as fast as any other media, and in 2009, it's starting to show. Flash drives are larger, faster, and more versatile than DVDs, and they're costing less and less. But what about an older system that can not boot from USB storage? Well, there is an option, and that's to use the destination drive as the source. Install the drive into a separate computer (via a usb dongle is fine) and follow these steps. Note that these directions work if you're trying to make a bootable USB flash drive, too.</p>
<p><span id="more-105"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#Making_partitions_and_setting_the_drive_as_active">Making partitions and setting the drive as active</a>
	</li>
	<li>
		<a href="#Installing_the_boot_loader">Installing the boot loader</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<p>First on a different system you should remove all existing partitions and create new ones (optional), then set the partition as active, give it a boot loader, then give it the installation files.</p>
<span id="Making_partitions_and_setting_the_drive_as_active"><h3>Making partitions and setting the drive as active</h3></span>
<p>First execute <code>diskpart.exe</code> from inside of a console. You'll need to determine which drive is the hard drive you intend to do this to. Type in <code>list disk</code>. From now on, the drive number will be referred to as <em>n</em>.</p>
<p><code>select disk <em>n</em><br />
clean<br />
create partition primary<br />
select partition 1<br />
active<br />
format fs=NTFS quick<br />
assign<br />
exit</code></p>
<p><code>clean</code> will remove all existing partitions, then the partition is made and selected, <code>active</code> will mark is at an active partition which signals a bootloader to use this partition, the partition is then formatted, and mounted. Determine the drive letter assigned to the partition, this will be referred to as <em>m</em>.</p>
<span id="Installing_the_boot_loader"><h3>Installing the boot loader</h3></span>
<p>Using the <code>bootsect.exe</code> executable found in the <code>\boot\</code> directory of your Vista or Windows 7 DVD, install <b>Windows Boot Manager</b> (BOOTMGR) onto the drive using <code>bootsect.exe /nt60 <em>m:</em></code> . I can confirm that using a 32 bit executable to make a 64 bit installer does work, and vice versa.</p>
<p>That's it! You're all done! Boot from the drive and the installer will run.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/installing-windows-7-from-and-to-the-same-hard-drive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replacing an Inspiron 1525 LCD video</title>
		<link>http://blog.red-stars.net/technology/computer-repair/replacing-an-inspiron-1525-lcd-video/</link>
		<comments>http://blog.red-stars.net/technology/computer-repair/replacing-an-inspiron-1525-lcd-video/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 16:46:27 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Computer Repair]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=101</guid>
		<description><![CDATA[Simple step by step guide to replacing the LCD on a Dell Inspiron 1525 laptop. Check out the source code that went into making this video! It uses AviSynth scripting to speed up small sections. video = DirectShowSource("MVI_0480.AVI") fps = 20 speedfactor = 4 return video.Trim(0,2300) ++ \ video.Trim(2300,3250).AssumeFPS(fps*speedfactor).ChangeFPS(fps) ++ \ video.Trim(3251,5999) ++ \ video.Trim(6000, [...]]]></description>
			<content:encoded><![CDATA[<p>Simple step by step guide to replacing the LCD on a Dell Inspiron 1525 laptop.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/56e3fSk_XdM&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/56e3fSk_XdM&#038;hl=en&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><span id="more-101"></span></p>
<p>Check out the source code that went into making this video! It uses AviSynth scripting to speed up small sections.<br />
<code>video = DirectShowSource("MVI_0480.AVI")</p>
<p>fps = 20<br />
speedfactor = 4</p>
<p>return video.Trim(0,2300) ++ \<br />
	video.Trim(2300,3250).AssumeFPS(fps*speedfactor).ChangeFPS(fps) ++ \<br />
	video.Trim(3251,5999) ++ \<br />
	video.Trim(6000, 6300).AssumeFPS(fps*speedfactor).ChangeFPS(fps) ++ \<br />
	video.Trim(6301,9599) ++ \<br />
	video.Trim(9600, 11300).AssumeFPS(fps*speedfactor).ChangeFPS(fps) ++ \<br />
	video.Trim(11301,0)</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/computer-repair/replacing-an-inspiron-1525-lcd-video/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hacking Windows XP PowerToy Calculator to run in Vista/Windows 7</title>
		<link>http://blog.red-stars.net/technology/software/hacking-windows-xp-powertoy-calculator-to-run-in-vista/</link>
		<comments>http://blog.red-stars.net/technology/software/hacking-windows-xp-powertoy-calculator-to-run-in-vista/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 19:29:05 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=74</guid>
		<description><![CDATA[How far would you go to use your favorite calculator? If the answer isn't a 75mb trace log, than you fail.]]></description>
			<content:encoded><![CDATA[<p>This was more of a project than I was originally expecting, Microsoft prevents the Windows XP Powertoy Calculator from running in Vista or Windows 7 in 2 separate places, but in the end, it runs perfectly in Vista, all the limitations are false.</p>
<p>Don't feel like doing this yourself? <a href="http://red-stars.net/random/PowerCalc.exe">No need!</a> <img src='http://blog.red-stars.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-74"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#Part_1:_The_Installer">Part 1: The Installer</a>
	</li>
	<li>
		<a href="#Part_2:_Oh..._no...">Part 2: Oh... no...</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<span id="Part_1:_The_Installer"><h3>Part 1: The Installer</h3></span>
<p><img src="http://red-stars.net/pictures/powercalc/01-cant_install.png" /><br />
When running <code>PowerCalcPowertoySetup.exe</code>, it complained that I'm not on Windows XP. Fair enough, but is that really important?</p>
<p>The exe installer dumped the MSI file at <code>C:\Windows\Downloaded Installations\Calculator Powertoy for Windows XP.msi</code> which I ran <a href="http://dennisbareis.com/msidiff.htm">MsiDiff</a> on to dump the MSI script. This gave me <code>Calculator Powertoy for Windows XP.msi.MmDumpTxt</code> which I searched for the above error in.</p>
<pre class="brush:plain"><$Row
	Condition="VersionNT = 501"
	Description="The powertoys require Windows XP or a service pack. They will not function on a version of Windows earlier or later than Windows XP."
></pre>
<p>Perfect. 501 is the Windows XP kernel version. Lets change that to the Vista kernal version in the MSI...<br />
<img src="http://red-stars.net/pictures/powercalc/02-hex.png" /></p>
<p><img src="http://red-stars.net/pictures/powercalc/03-installer.png" /><br />
Sweet! It worked!</p>
<span id="Part_2:_Oh..._no..."><h3>Part 2: Oh... no...</h3></span>
<p>Running <code>PowerCalc.exe</code> causes it to exit before ever giving us a GUI. Lets do a trace in <a href="http://www.ollydbg.de/">OllyDbg</a> and see what we can figure out.</p>
<pre class="brush:plain">01018405	Main	JE SHORT PowerCal.0101840C
0101840C	Main	TEST BYTE PTR SS:[EBP-30],1
01018410	Main	JE SHORT PowerCal.01018423
01018412	Main	MOVZX ECX,WORD PTR SS:[EBP-2C]	ECX=0000000A
01018416	Main	JMP SHORT PowerCal.01018426
01018426	Main	PUSH ECX	Arg4 = 0000000A
01018427	Main	PUSH EAX	Arg3 = 001E1F33
01018428	Main	PUSH EBX	Arg2 = 00000000
01018429	Main	PUSH PowerCal.01000000	Arg1 = 01000000
0101842E	Main	CALL PowerCal.01001FD3	EAX=00000000, ECX=D73F2C3E, EDX=7F68081A
01018433	Main	MOV ESI,EAX
01018435	Main	MOV DWORD PTR SS:[EBP-7C],ESI
01018438	Main	CMP DWORD PTR SS:[EBP-60],EBX
0101843B	Main	JNZ SHORT PowerCal.01018444
0101843D	Main	PUSH ESI	status = 0
0101843E	Main	CALL DWORD PTR DS:[<&#038;msvcrt.exit>]	ECX=0006FE28, EDX=00000000, EBP=0006FE84, ESI=00000001, EDI=00831BF0
    Process terminated, exit code 0</pre>
<p>The bottom of the trace-over  isn't telling us much. Lets check out some of these offsets in <a href="http://www.hex-rays.com/idapro/">IDA Pro</a> and see what we can come up with.</p>
<p><img src="http://red-stars.net/pictures/powercalc/04-ida_lower.png" /><br />
All the stuff around <code>0101843B</code> seems to exit the program, and none of these other offsets get us anywhere... lets run a trace-into and see what we get.</p>
<p>Aside from a 75mb text file, we get: (search from the bottom up for our programs address space! There's a lot of external code in there!).</p>
<pre class="brush:plain">010180E3	Main	RETN
01001FD1	Main	LEAVE	EBP=0006FEE4
01001FD2	Main	RETN
01001FDF	Main	TEST EAX,EAX
01001FE1	Main	JE PowerCal.010020A0
010020A0	Main	XOR EAX,EAX
010020A2	Main	POP ESI
010020A3	Main	LEAVE	EBP=0006FF88
010020A4	Main	RETN 10
01018433	Main	MOV ESI,EAX
01018435	Main	MOV DWORD PTR SS:[EBP-7C],ESI
01018438	Main	CMP DWORD PTR SS:[EBP-60],EBX
0101843B	Main	JNZ SHORT PowerCal.01018444
0101843D	Main	PUSH ESI	status = 0
0101843E	Main	CALL DWORD PTR DS:[<&#038;msvcrt.exit>]
exit	Main	MOV EDI,EDI</pre>
<p>Now we're talking! It looks like a function returns and then the program exits. Lets check out the call to that function.<br />
<img src="http://red-stars.net/pictures/powercalc/05-function_call.png" /></p>
<p>One path goes to the exit, the other... doesn't! Lets check out <code>sub_1001F60</code> to see what it does...<br />
<br /><img src="http://red-stars.net/pictures/powercalc/06-evil_version_check.png" /><br />
It's our evil Windows Version Checking function!</p>
<p>In OllyDbg lets goto the <code>jz loc_10020A0</code> after the function call, right click, and goto "nop" and press run. This causes the program to <em>always</em> follow the non-exiting code path.<br />
<img src="http://red-stars.net/pictures/powercalc/07-noping.png" /></p>
<p><img src="http://red-stars.net/pictures/powercalc/08-success.png" /><br />
Success!</p>
<p><img src="http://red-stars.net/pictures/powercalc/09-hex.png" /><br />
Lets hex edit that into the executable so it's like this all the time.</p>
<p>We can now use our calculator!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/hacking-windows-xp-powertoy-calculator-to-run-in-vista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Process Monitor and other tools to fix a broken installation.</title>
		<link>http://blog.red-stars.net/technology/software/using-process-monitor-and-other-tools-to-fix-a-broken-installation/</link>
		<comments>http://blog.red-stars.net/technology/software/using-process-monitor-and-other-tools-to-fix-a-broken-installation/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 16:30:27 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=67</guid>
		<description><![CDATA[Sometimes things break, sometimes the only way to fix them breaks, sometimes you need to use kernel hooks to fix your favorite toy.]]></description>
			<content:encoded><![CDATA[<p>Today the stars were aligned and my VMWare installation decided to stop working. It's time for an upgrade, anyways.</p>
<p><img src="http://red-stars.net/pictures/vmwarefix/01-cannot_install.png" /><br />
Oh, that makes sense. So lets uninstall the old version.</p>
<p><img src="http://red-stars.net/pictures/vmwarefix/02-cannot_uninstall.png" /><br />
Can't install the new, can't uninstall the old. Time for some hackery!</p>
<p><span id="more-67"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<p>First lets find out the name of the culprit installer with <a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx">Process Explorer</a>'s find tool, then in <a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx">Process Monitor</a> lets setup a filter to this executable.<br />
<img src="http://red-stars.net/pictures/vmwarefix/03-01-setup_filter.png" /><br />Re-running the installer lets us see what it's accessing. Using that we can find out what makes it think it's installed so we can trick it into thinking it's doing a fresh install. Once the error screen comes up, unattach the event monitor in Process Monitor (control+e).</p>
<p><img src="http://red-stars.net/pictures/vmwarefix/03-finding_traces.png" /><br />
This looks interesting. It's the registry key used by Window's Add/Remove Programs.</p>
<p><img src="http://red-stars.net/pictures/vmwarefix/04-renaming_installer_class.png" /><br />
Lets rename it to prevent the installer from seeing it then re-run the installer. Hmm... Semi-success. The installer now gives us the same error, but in a different place, so lets re-Process Monitor the installer.<br />
<img src="http://red-stars.net/pictures/vmwarefix/05-finding_more_traces.png" /><br />
Well! This looks very interesting! Lets rename this one as well...<br />
<img src="http://red-stars.net/pictures/vmwarefix/06-renaming.png" /></p>
<p>Hey! It's installing!</p>
<p>Finally, time to get back to work.<br />
<img src="http://red-stars.net/pictures/vmwarefix/07-dll_error.png" /><br />
Crap!</p>
<p>A DLL did not get replaced during the installation and a version mis-match is causing problems (why put the version number in the filename and not update it?). After a harddrive-wide search, I found sigc-2.0.dll in <code>C:\Program Files\VMware\VMware Workstation</code>. Good news is the installer has all of the installation files out in the open, so no need to dump cabs or hack the msi. I replaced copy in the Program Files directory with the one from the installer's directory and...<br />
<img src="http://red-stars.net/pictures/vmwarefix/08-working.png" /><br />
Success!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/using-process-monitor-and-other-tools-to-fix-a-broken-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Google Page Rank Finder in Javascript</title>
		<link>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/</link>
		<comments>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 14:06:28 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=63</guid>
		<description><![CDATA[The google.search.WebSearch API quickly explained, also quickly complained about. It's fast, powerful, and well done, but Google gypped us on functionality.]]></description>
			<content:encoded><![CDATA[<p>An interesting technology are Google Page Rank Finders. What they do is discover which result and page number a website is in Google's search results for a given term.</p>
<p>I thought an interesting implementation would be a completely client side one written in Javascript using Google's search API. To spoil the ending, after creating this I discovered the API only allows 8 results per page and 8 pages, making this useless if the site is beyond the 64th result, but the API is interesting and powerful regardless.</p>
<p>The finished version can be found at <a href="http://pagerank.red-stars.net/">pagerank.red-stars.net</a> with the complete <a href="http://pagerank.red-stars.net/pagerank.js">Javascript</a>.</p>
<p><span id="more-63"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#google.search.WebSearch_object">google.search.WebSearch() object</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<span id="google.search.WebSearch_object"><h3>google.search.WebSearch() object</h3></span>
<p>The WebSearch() object is relatively simple, once instanced, all it needs is a call back to be setup before it can be used.</p>
<pre class="brush:javascript">var webSearch = new google.search.WebSearch();
webSearch.setSearchCompleteCallback(this, searchComplete, null);
webSearch.execute("cookies");</pre>
<p>The function searchComplete() will be called when the search for "cookies" completes. It's important that our instance of WebSearch named webSearch is inside of a scope which is viewable from searchComplete() because the callback is argumentless.
<pre class="brush:javascript">function searchComplete() {
	// Make sure that there are results.
	if (webSearch.results &#038;& webSearch.results.length > 0) {
		var results = webSearch.results;
		// Go through every result.
		for (var resultIndex = 0; resultIndex < results.length; resultIndex++) {
			var result = results[resultIndex];
			// Show a messagebox with the results information.
			alert(result.html.innerHTML);
		}
	}
}</pre>
<p>We used the .html property from the result which gives us a Google-looking result. Now what if we wanted more than just the first page?</p>
<pre class="brush:javascript">var currentPageIndex = 0;
function searchComplete() {
	// Make sure that there are results.
	if (webSearch.results &#038;& webSearch.results.length > 0) {
		currentPageIndex++;
		var results = webSearch.results;
		// Go through every result.
		for (var resultIndex = 0; resultIndex < results.length; resultIndex++) {
			var result = results[resultIndex];
			// Show a messagebox with the results information.
			alert(result.html.innerHTML);
		}

		// Check if another page exists, if so, perform the request.
		if (currentPageIndex < webSearch.cursor.pages.length)
			webSearch.gotoPage(currentPageIndex);
	}
}</pre>
<p>The <code>cursor</code> object contains an array called pages who's length is used to determine the number of pages available. This will go through all available search results. When <code>gotoPage</code> is called, our call back function is once again executed when the search is finished.</p>
<p>A complete reference to the WebSearch and associate classes <a href="http://code.google.com/apis/ajaxsearch/documentation/reference.html">is available on code.google.com</a>. The API is decent and flexible, if not limited in functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/web/creating-a-google-page-rank-finder-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>System.Drawing.Drawing2D.PathPointType defined.</title>
		<link>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/</link>
		<comments>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 19:07:57 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=50</guid>
		<description><![CDATA[Microsoft's under-documented class getting it's rightful treatment.]]></description>
			<content:encoded><![CDATA[<p>I had a project which involved raw access to the data stored inside of a System.Drawing.Drawing2D.GraphicsPath and found that the <a title="MSDN Document" href="http://msdn.microsoft.com/en-us/library/3ch9cxht.aspxhttp://">MSDN Document</a> for PathPointType was rather lacking, but it's not too complex.</p>
<p><span id="more-50"></span></p>
<p>Inside of GraphicsPath is a byte array called PathTypes that contains PathPointType and a PointF array called PathPoints (the same data is also stored in GraphicsPath.PathData.Points and GraphicsPath.PathData.Types). They relate to each other by index, so PathTypes[n] is the PathPointTypes for PathPoints[n].</p>
<p>The reason PathTypes is stored as bytes and not PathPointType is because multiple values will be contained per byte. To separate the two, you must use a bitwise AND operation of your value against the bit mask PathPointType.PathTypeMask. The resulting value is either Start, Line or Bezier (Bezier3 is equal to Bezier).</p>
<p>You can NOT modify these collections directly. Instead, you must make a new instance of GraphicsPaths and pass modified collections to them via the (PointF[], byte[]) constructor.</p>
<table style="width: 100%; border: 1px solid black;">
<caption>PathPointType values</caption>
<thead>
<tr>
<td><strong>PathPointType</strong></td>
<td><strong>Value</strong>
<td><strong>Description</strong></td>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>Start</td>
<td style="text-align: right;">0</td>
<td>Start of graphics path. Move cursor then put pen down.</td>
</tr>
<tr>
<td>Line</td>
<td style="text-align: right;">1</td>
<td>Move pen to given location.</td>
</tr>
<tr>
<td>Bezier</td>
<td style="text-align: right;">3</td>
<td>Draw curve.</td>
</tr>
<tr>
<td>Bezier3</td>
<td style="text-align: right;">3</td>
<td><em>Equal to Bezier.</em></td>
</tr>
<tr>
<td>PathTypeMask</td>
<td style="text-align: right;">7</td>
<td>Mask for extracting types from PathTypes.</td>
</tr>
<tr>
<td>DashMode</td>
<td style="text-align: right;">16</td>
<td>Draw in dashes, not solid lines.</td>
</tr>
<tr>
<td>PathMarker</td>
<td style="text-align: right;">32</td>
<td>Lift pen, move pen to new location, then if the pen was down before, place back down.</td>
</tr>
<tr>
<td>CloseSubpath</td>
<td style="text-align: right;">128</td>
<td>Move mouse to point from the last Start (closing the path) then lift pen.</td>
</tr>
</tbody>
</table>
<p>Below is code which parses the PathTypes and PathPoints and causes actions in a class which renders the GraphicsPath as mouse output where the mouse is down when the pen should be down, and the mouse moves to the location the pen should be, etc. Please note this code renders Bezier curves as lines.</p>
<pre class="brush:csharp">int index=0;
PointF firstPoint = new PointF(); // Used to store the starting position so closed paths can reposition here.
// Loop through all path data
foreach (PointF point in Path.PathPoints) {
	byte curType = Path.PathTypes[index];
				// Extract the item type by the bit mask
	byte itemType = (byte)(curType &#038; (byte)PathPointType.PathTypeMask);

	// Draw the different object types
	if (itemType == (byte)PathPointType.Start) {
		firstPoint = point;
		input.MousePos(point);
		input.LeftButtonDown();
	} else if ((itemType == (byte)PathPointType.Line) || (itemType == (byte)PathPointType.Bezier) || (itemType == (byte)PathPointType.Bezier3))
		input.MousePos(point);

	// Handle all additional flags
	if (isType(curType, PathPointType.PathMarker)) {
		bool wasMouseDown = false;
		if (input.IsMouseDown) {
			wasMouseDown = true;
			input.LeftButtonUp();
		}
		input.MousePos(point);
		if (wasMouseDown)
			input.LeftButtonDown();
	}

	if (isType(curType, PathPointType.CloseSubpath)) {
		input.MousePos(firstPoint);
		input.LeftButtonUp();
	}
	index++;
}
input.LeftButtonUp();</pre>
<pre class="brush:csharp">private bool isType(byte type, PathPointType isType) {
	return (type &amp; (byte)isType) != 0;
 }</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/programming/csharp/system-drawing-drawing2d-pathpointtype-defined/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automated Local Backup of a Remote MySQL Database</title>
		<link>http://blog.red-stars.net/technology/software/automated-local-backup-of-a-remote-mysql-database/</link>
		<comments>http://blog.red-stars.net/technology/software/automated-local-backup-of-a-remote-mysql-database/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 20:15:39 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://red-stars.net/wordpress/?p=33</guid>
		<description><![CDATA[Scared your $10.00/year web host is going to blow up or disappear some evening? Me too! So I wrote this script.]]></description>
			<content:encoded><![CDATA[<p>I always like to take backing up into my own hands, and a database is potentially the most important thing on your server next to only the code driving it all, which in nature typically has a local copy anyways.</p>
<p><span id="more-33"></span><div class='toc wptoc'>
<h2>Contents</h2>
<ol class='toc-odd level-1'>
	<li>
		<a href="#Step_1:_mysqldump_and_the_remote_script">Step 1: mysqldump and the remote script</a>
	</li>
	<li>
		<a href="#Step_2:_wget_rar_and_the_local_script">Step 2: wget, rar and the local script</a>
	</li>
	<li>
		<a href="#Step_3:_Scheduling">Step 3: Scheduling</a>
	</li>
</ol>
</ol>
</ol>
</div>
<div class='wptoc-end'>&nbsp;</div></p>
<p>The local machine is a Windows Vista workstation and the remote is a webserver running LAMP.</p>
<p>The security of the locally backup database file is only as secure as the machine it-self. If you're not sure what this means, do <em>not</em> backup sensitive data using this method.</p>
<span id="Step_1:_mysqldump_and_the_remote_script"><h3>Step 1: mysqldump and the remote script</h3></span>
<p><code>mysqldump</code> is a program which can dump the contents of a MySQL database. It should be used with a MySQL user which has read access to all of the databases on your server that you wish to backup.</p>
<p><code>mysqldump</code> will be executed by PHP on the remote server and the output will be passed back over standard http.</p>
<pre class="brush:php">
</pre>
<p>Update the variables in the above script and save as <code>index.php</code>. Upload this file to it's own directory on your server, for example <code>/www/sqlbackup/</code>.</p>
<p><code>/www/sqlbackup/</code> should be configured as a password protected directory to prevent access by anyone to it.</p>
<span id="Step_2:_wget_rar_and_the_local_script"><h3>Step 2: wget, rar and the local script</h3></span>
<p><a href="http://users.ugent.be/~bpuype/wget/" target="_blank">Download wget</a> into your <code>%windir</code>. This is a command line utility that can be used to download remote files and pages from http and ftp servers.</p>
<p>Optionally, <a href="http://www.rarlabs.com/" target="_blank">install WinRAR</a> to add compression.</p>
<pre class="brush:text">wget --http-user=... --http-password=... --output-document=C:\Users\Joe\Documents\Scripts\sqlbackup\backup.txt http://www.yourserver.com/sqlbackup/
"C:\program files\winrar\rar.exe" u -dw -y -p... backup.rar backup.txt</pre>
<p>The first line uses <code>wget</code> to download the output from our remote script to <code>backup.txt</code>. The user, password, remote, and local locations all need to be changed to suite your configuration. This should be saved into <code>script.bat</code> in it's own directory on your local workstation, example <code>C:\Users\Joe\Documents\Scripts\sqlbackup\</code>.</p>
<p>The second line compresses the downloaded file into <code>backup.rar</code> and sets the password of the rar to whatever follows the -p argument. Note that the rar password ads very minimal security due to the script, which contains the password, being in the same directory. This line is optional and can be omitted.</p>
<p>Run <code>backup.bat</code> to make sure that everything is working fine.</p>
<span id="Step_3:_Scheduling"><h3>Step 3: Scheduling</h3></span>
<p>In a command window, enter <code>at 13:00 /EVERY:M,T,W,Th,F,S,Su C:\Users\Joe\Documents\Scripts\sqlbackup\backup.bat</code></p>
<p>This will cause the above local script to execute everyday at 1:00PM everyday of the week.</p>
<p>There's nothing else to it! Keep in mind, once again, that this will make any of the dumped MySQL contents as insecure as your computer is!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.red-stars.net/technology/software/automated-local-backup-of-a-remote-mysql-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
