Implementing DPAPI in Compact Framework

Posted: 13th May 2011 by thegrayzone in Development
Tags:

I have used the Windows Data Protection API in a number of Windows applications for machine encrypting values. I was trying to implement CryptProtectData and CryptUnprotectData for use on a Windows Mobile device.

I tried using the wrapper class that I use for standard Windows development with the following DllImports:

[DllImport("crypt32.dll", EntryPoint = "CryptProtectData", CharSet = CharSet.Auto)]
public static extern bool Encrypt ( .... )

[DllImport("crypt32.dll", EntryPoint = "CryptUnprotectData", CharSet = CharSet.Auto)]
public static extern bool Decrypt( .... )

However, when I tried to use this I received the error:

Can’t find an Entry Point ‘CryptProtectData’ in a PInvoke DLL ‘crypt32.dll’.

It took me a while to figure out what was happening. The issue was that in Compact Framework the methods are from coredll.dll, not Crypt32.dll as it is in Desktop Windows. So the signature (including parameters) now becomes:

[DllImport("coredll.dll", EntryPoint = "CryptProtectData", CharSet = CharSet.Auto)]
public static extern bool Encrypt(
  ref DataBlob dataIn,
  String description,
  ref DataBlob optionalEntropy,
  IntPtr reserved,
  ref CryptProtectPromptStruct promptStruct,
  int flags,
  out DataBlob dataOut);

[DllImport("coredll.dll", EntryPoint = "CryptUnprotectData", CharSet = CharSet.Auto)]
public static extern bool Decrypt(
  ref DataBlob dataIn,
  String description,
  ref DataBlob optionalEntropy,
  IntPtr reserved,
  ref CryptProtectPromptStruct promptStruct,
  int flags,
  out DataBlob dataOut);

This is obvious when you fully read the MSDN articles I’ve linked too but I was in a hurry and presumed that it would be the same dll!

I also use the following two structures for passing to the above methods:

[StructLayout(LayoutKind.Sequential)]
internal struct CryptProtectPromptStruct
{
	internal Int32 Size;
	internal Int32 Flags;
	internal IntPtr Window;

	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
	internal String Message;
}

internal struct DataBlob
{
	internal Int32 Size;
	internal IntPtr Data;
}

Without the StructLayoutAttribute and MarshalAsAttribute on the CryptProtectPromptStruct you will receive the following error:

“NotSupportedException” at System.Runtime.InteropServices.Marshal.SizeOfInternal()

This is because (thanks to this article for the info) the struct must be a Blittable type, meaning that the struct must be represented identically in both managed and unmanaged memory.

Changing app.config for Build Configurations

Posted: 5th May 2011 by thegrayzone in Development
Tags:

I’m currently working on an application where config data (connection strings etc) is stored machine encrypted, using the Windows Data Protection API, in app.config.

The Problem

In the standard app.config file all strings are encrypted for my development machine. I also wanted to store them encrypted for the deployment machine and automatically publish these values when building a release version of the application.

The Solution

The solution was to alter the csproj/vbproj file, adding an ItemGroup with a condition to deploy a different app.config depending on the build configuration.

First I added another app.config file within a ‘Release’ folder. I then edited the csproj file.
To do this you can either:

  1. Use a text editor (Notepad, Notepad++, Wordpad etc).
  2. In Visual Studio, right click -> Unload Project. Right click -> Edit.

Within the csproj file you will find the following XML within the main Project node:

<ItemGroup>
  <None Include="App.config" />
</ItemGroup>

Remove this tag and replace it with the following:

<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
  <None Include="App.config" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
  <None Include="Release\App.config" />
</ItemGroup>

This tells MSBuild to use App.config when using Debug configuration, or Release\App.config when using Release configuration.

Unit Testing Asynchronous Operations

Posted: 11th April 2011 by thegrayzone in Development
Tags:
The Problem

I’m currently working on an application that uses the MapPoint 2010 API to generate routing data. Some of the operations can be quite long-running (often < 20s but some can run up to a couple of mins). Due to this I use a BackgroundWorker in my main class to process each route’s data.
I ran into some problems unit testing this since it is an asynchronous process but I found a solution, not necessarily the cleanest but it works.

The Solution

In the end the solution was quite simple. I had to figure a way of making the thread wait until the “CalculationComplete” event is raised. To do this I used the ManualResetEvent class. I can then use the ManualResetEvent.WaitOne() method to tell the current thread to wait until it receives notification. Notification is then sent using the ManualResetEvent.Set() event, called from the completed event of the asynchronous method being tested.

For this example I will use a class called “CalculateData” which has a “CalculationComplete” event and a method called “StartCalculationAsync”.

[TestMethod]
public void Test_Calculation()
{
  // Instantiate class to test
  CalculateData calcData = new CalculateData();

  // Instantiate ManualResetEvent, setting to unsignalled
  ManualResetEvent eventCompletion = new ManualResetEvent(false);

  // Variable to store return args
  CustomEventArgs eventArgs = null;

  // Use an anonymous function to set value of eventArgs and signal to ManualResetEvent to continue
  calcData.CalculationComplete += (sender, e) =>
  {
    eventArgs = e;

    // Call set method to signal thread to continue
    eventCompletion.Set();
  };

  // Call async method to be tested
  calcData.StartCalculationAsync(arg1, arg2);

  // Signal thread to wait here until signal received
  eventCompletion.WaitOne();

  // Assert statement will be reached once completion event raised.
  Assert.IsFalse(eventArgs.boolProperty);
}

Setting up MantisBT on IIS 7 w/ SQL Server

Posted: 24th March 2011 by thegrayzone in Development
Tags:

I recently decided to give a new Bug Tracking system a try and after some reading decided to go with Mantis as it is web based, Open Source, lightweight and easy to use.

I decided to host it locally with IIS 7 on my Windows 7 development machine, using Microsoft SQL Server 2008 R2 Express as the database. I chose MSSQL as the database as I already had it installed on my machine.

The steps that are required to get Mantis running on Windows are fairly straightforward and consist of:

  1. Install PHP on IIS.
  2. Setup Mantis.
  3. Track bugs!

However I found a lot of articles on the internet with people having issues setting up Mantis on Windows so I thought I would put down how I did it to try and help anyone else with similar issues.

Install PHP on IIS

This was a lot easier than I thought it would be, go through the following steps and you’ll be good to go:

  1. The initial steps are to enable FastCGI in IIS and configure IIS to process PHP requests. These are pretty simple and detailed in this article on php.net.
  2. Next you need to download PHP for Windows. I downloaded the zip file of PHP 5.3.6 “VC9 x86 Non Thread Safe” version from http://windows.php.net/download/.
  3. After downloading the zip file, unzip it to a location on your local computer, I used C:\PHP.
  4. Most documentation I found stated that I would need php_mssql.dll in order for PHP to use MSSQL. It turns out that PHP 5.3 doesn’t support this anymore. Fortunately there is a Microsoft PHP driver for MSSQL, available for download here.
  5. Extract the dlls from the above executable, I unzipped them to an MSSQL folder within my PHP install folder (C:\PHP\MSSQL). Copy php_sqlsrv_53_nts_vc9.dll from the extracted files and paste it into the php “ext” folder (C:\PHP\EXT).
  6. The final step is now to enable the above dll for PHP to be able to use it. You can do this by either adding into the following your php.ini file or using the “Enable or disable an extension” option in PHP Manager for IIS 7:

    [PHP_SQLSRV_53_NTS_VC9]
    extension=php_sqlsrv_53_nts_vc9.dll
    

Now that PHP is installed, setup in IIS and the relevant drivers installed the next step is to setup Mantis.

Setup Mantis

Setting up Mantis was also pretty straightforward, the only possibly tricky part is setting the Database connection options.

  1. First download the zip file of the latest release of Mantis Bug Tracker from http://www.mantisbt.org/download.php, currently 1.2.4.
  2. Unzip this to any location. Copy the contents of the mantisbt-1.2.4 folder to C:\Inetpub\wwwroot\mantis\ (or change if the location of your root directory is different).
  3. Before setting up the configuration file for Mantis you need to create a DB and a User. My database was called “mantisBT” and I created a user called “mantisdbuser”.
  4. Next you need to setup the configuration file for Mantis. To do this rename the file “config_inc.php.sample” to “config_inc.php”, then change the “Database Configuration” section. For the following my computername is “COMPUTERNAME” and MSSQL instance name is “EXPRESS”.

    # --- Database Configuration ---
    $g_hostname      = 'Driver={SQL Server};SERVER=COMPUTERNAME\EXPRESS;DATABASE=mantisBT;UID=mantisdbuser;PWD=mantisPassword;';
    $g_db_username   = 'mantisdbuser';
    $g_db_password   = 'mantisPassword';
    $g_database_name = 'mantisBT';
    $g_db_type       = 'odbc_mssql';
    
  5. The final step is to run the installation scripts to create all of the required Database tables. This will be at: http://localhost/mantis/admin/install.php. You will see a “pre-installation check” screen which will warn you of any problems that need looked at before you install the Database.

You should now be good to go, navigate to http://localhost/mantis/ and login using the default username and password (administrator, root).

Debugging a Memory Leak in Silverlight 4

Posted: 10th November 2010 by thegrayzone in Development
Tags:
The Problem

I was having a bit of trouble with a memory leak somewhere in my Silverlight 4 application. There was nothing obvious in my code that was causing it, I was cleaning up and disposing of objects as I went. I then discovered the very handy WinDbg tool that comes as part of the Debugging tools for Windows download. Using this it becomes a lot easier to find, and fix, your memory leak.

The Solution

First you need to download and install the Debugging tools for Windows, after this is done go through the following procedure to find and fix the memory leak.

  1. Run your application in IE and get it to a stage where you think the memory leak is occuring. If you are running the application from Visual Studio you need to start without debugging (Ctrl+F5), or WinDbg won’t be able to attach because the VS debugger is already attached.
  2. Next you need to find the Process ID (PID) of the IE process running the Silverlight application. Since multiple IE instances will be running I’ve found the easiest way to do this is to use the Process Explorer tool. The PID you want is the child process, not the parent. See screenshot below with PID 4128 highlighted:
    Screenshot of Process Explorer

    Screenshot of Process Explorer

  3. Now that you have the appropriate PID, open up WinDbg and select File -> Attach to a Process (or press F6). This will show you a list of all processes, select the appropriate process and hit the OK button.
  4. Before you can see any stats for the Silverlight app you need to load the sos.dll for Silverlight, to do this use the command “.load C:\\Program Files\\Microsoft Silverlight\\4.0.50917\\sos.dll” (changing file path as appropriate). This now enables you to view all debug information for the application.
  5. There are a few different commands that you can use from here to assist you in hunting down the memory leak:

    1. “!dumpheap -stat” shows a listing of all objects that are in memory, how many instances there are of each and the total space that they take up. From here you can easily see if there is a particular object that is not being cleared.
      WinDbg Dump Stats

      Screenshots Dump Stats

    2. “!dumpheap –stat –type TYPENAME” will show the same above status but for the specified type.
    3. “!dumpheap –type TYPENAME” will show a listing of all memory addresses for the specified type. You can then use the memory address with the “!gcroot ADDRESS” command. This shows what is holding the reference to the object, helping you hunt down what is holding a reference and preventing the object being cleared.

In my case the memory leak issue was actually caused by an issue with the ContextMenu from the Silverlight Toolkit not unsubscribing from the MouseMove event and so not being garbage collected.

Problem

By default any binding for a TextBox is not updated until the field loses focus. This didn’t suit my needs for an application I’m currently working on because I wanted the Binding source to be updated whenever something is entered into the TextBox. With WPF this is done easily by setting the UpdateSourceTrigger property to PropertyChanged in the Binding definition, unfortunately this is not available for Silverlight.

The Solution

A workaround that I found for this was to add a KeyUp event to the required TextBox and update the binding in code behind.

The Code

For example if you had the following TextBox declared in your XAML file:

<TextBox Text="{Binding Path=ClientName, Mode=TwoWay}" Name="tbName"/>

You could add the following to your code behind file:

using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

public MyUserControl()
{
  InitializeComponent();

  tbName.KeyDown += new KeyEventHandler(tbName_KeyUp);
}

private void tbName_KeyUp(object sender, KeyEventArgs e)
{
  BindingExpression binding = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
  binding.UpdateSource();
}

Since the above is not dependent on any particular TextBox or ViewModel it could be changed to a custom TextBox control that auto-updates on KeyUp, for example:

using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

public class AutoUpdateTextBox : TextBox
{
  protected override void OnKeyUp(KeyEventArgs e)
  {
    BindingExpression binding = this.GetBindingExpression(TextBox.TextProperty);
    binding.UpdateSource();
    base.OnKeyUp(e);
  }
}

This would then be used in XAML like a standard TextBox:

<my:AutoUpdateTextBox Text="{Binding Path=ClientName, Mode=TwoWay}"/>
Key Points
  1. Firstly we use the FrameworkElement.GetBindingExpression(), passing in the TextBox.TextProperty DependencyProperty to get the BindingExpression object, which contains information about the textboxes Binding.
  2. We then call the UpdateSource() method to update the Binding’s source property.

Binding to WebContext.Current in XAML

Posted: 6th October 2010 by thegrayzone in Development
Tags: ,

When using the RIA Services Business Application template in VS 2010 I noticed that the WebContext.Current object is added to the applications ResourceDictionary:

private void Application_Startup(object sender, StartupEventArgs e)
{
  this.Resources.Add("WebContext", WebContext.Current);
  ...
}

As this is now stored as a resource you can easily bind to it, using the StaticResource extension. I’ve used it with a simple Value Converter to show/hide options depending on whether the user is Authorised, e.g.:

<UserControl
  ...
  xmlns:converters="clr-namespace:theGrayZone.Converters;assembly=theGrayZone.Common">

<UserControl.Resources>
  <converters:BoolToVisibilityConverter x:Key="BoolVisibilityConverter"/>
</UserControl.Resources>

  <HyperlinkButton NavigateUri="/Search" TargetName="ContentFrame" Content="Search" Visibility="{Binding Path=User.IsAuthenticated, Source={StaticResource WebContext}, Converter={StaticResource BoolVisibilityConverter}}"/>

using the following as my converter:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace theGrayZone.Converters
{
  public class BoolToVisibilityConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return (bool)value ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }
}

I’ve been using WCF RIA-Services to pass data retrieved via Stored Procedure/EF 4 to a Silverlight 4 application. The system is based on an existing system and a lot of the legwork is already done in Stored Procedures so I was required to re-use them.

To start with, I imported my stored procedures to my Entity Framework model, added a Function Import and created a Complex Type for each stored procedure, as per this MSDN Article.

I had 4 issues that I had to solve when using this approach.

  1. Get Output parameter from Stored Procedure
  2. Add properties to Complex Types.
  3. Add methods to Complex Types to be available on client side.
  4. Store nested Complex Types within other Complex Types.
Defining Key for Entity

Before returning any complex types from RIA-Services you must define a Key for each. This is normally taken from the database but when using Stored Procedures you have to manually add them. If you don’t you’ll get the following error:

The entity ‘Employee’ in DomainService ‘MyDomainService’ does not have a key defined. Entities exposed by DomainService operations must have at least one public property marked with the KeyAttribute

Fortunately they are easy to add using DataAnnotations. Create a new partial class for the element that you want to add the key to and insert something similar to:

using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(EmployeeMetadata))]
public partial class Employee
{
  internal sealed class EmployeeMetadata
  {
    public EmployeeMetadata() { }

    [Key]
    public int EmployeeClassID { get; set; }
  }
}
Get Output parameter from Stored Procedure

The first problem that I had to figure out was how to retrieve an output parameter from a stored procedure. Take the following stored procedure:

CREATE PROCEDURE SelectWeeklyHours
  @EmployeeID INT
, @TotalHours INT OUTPUT
AS

SELECT
  @TotalHours = SUM(Hours)
FROM
  Hours
WHERE
  EmployeeID = @EmployeeID

To get the value of @TotalHours in my DomainService I use the following code:

using System.Data.Objects;

private int GetTotalHours(int employeeID)
{
  // Declare ObjectParameter object to store output param
  ObjectParameter total = new ObjectParameter("TotalHours", typeof(int));

  // Call stored procedure, passing in ObjectParameter
  this.ObjectContext.SelectWeeklyHours(employeeID, total);

  // ObjectParameter will have output param value
  return Convert.ToInt32(total.Value);
}
Add property to Complex Types.

The second issue that I had to solve was that I wanted to add a new property to a complex type. At first I tried adding this to the Complex Type using the Model Browser, with the thought that I would add the appropriate value after the Stored Procedure has been called. However this throws the following exception at run time:

The data reader is incompatible with the specified ‘MyModel.Employee’. A member of the type, ‘Manager’, does not have a corresponding column in the data reader with the same name.

The easiest way to do this is create a new partial class and add the required property and decorate it with the DataMemberAttribute to specify that the property is part of the data contract and is to be serialized. For example, using the above Employee example you wanted to add an extra property, Manager, to the class you would do:

using System.Runtime.Serialization;

public partial class Employee
{
  [DataMember]
  public string Manager { get; set; }
}
Add methods to Complex Types to be available on client side

I also had a requirement where I wanted to add a couple of methods to the server side generated class for the complex type and have that available on client side. This is done by naming your class using the shared notation. E.g. if you had a complex type named Employee you would add a new class file and name it Employee.shared.cs, this file will now be copied to the client side and you will be able to access any methods there.

public partial class Employee
{
  public override ToString()
  {
    return EmployeeID.ToString();
  }

  public string FullName
  {
    return string.Format("{0} {1}", Forename, Surname);
  }
}

You will now be able to access Employee.FullName or Employee.ToString() from the client application.

Store nested Complex Types within other Complex Types

The last requirement that I had to fill was the ability to store a complex type returned from one stored procedure within the complex type of another stored procedure. At first I tried to add this into the complex type definition in the Model Browser, however this throws an error the same was as trying to add a scalar value did.

The solution to this again involves using a partial class to include the property, but rather than use the DataMemberAttribute, like above, you need to use the IncludeAttribute and AssociationAttribute. The AssociationAttribute represents the relationship between the two complex types and the IncludeAttribute specifies that the relationship should be included when the code is generated on the client. This can be used to add single complex types or collections of complex types:

using System.ServiceModel.DomainServices.Server;
using System.ComponentModel.DataAnnotations;

public partial class Employee
{
  [Include]
  [Association("Employee_Address", "EmployeeID", "EmployeeID")]
  public IEnumerable<Address> Addresses { get; set; }

  [Include]
  [Association("Employee_Position", "PositionID", "PositionID")]
  public Position Position { get; set; }
}

The AssociationAttribute takes the name of the relationship and the two key fields, if either of these key are wrong you will get an error similar to:

Association named ‘Employee_Address’ defined on entity type ‘myProject.Model.Employee’ is invalid: ThisKey property named ‘EmployeesID’ cannot be found.

Change Opacity of Border on MouseOver

Posted: 8th September 2010 by thegrayzone in Development
Tags: ,
The Problem

Recently I was looking for a way of changing the opacity of a Border control when the user mouse’s over it, and re-setting the opacity when the mouse leaves. I originally wanted to do it using VisualStateManagers but since there is no ControlTemplate this won’t work.

The Solution

The solution that I came up with (not necessarily the best but it works!) was to create a new class that inherits from the Behavior<T> class. I then define the opacity changes in this and it work’s a treat!

The Code

First I created a new class that inherits from Behavior<UIElement>. All I did was add a MouseEnter and MouseLeave event and change the opacity accordingly:

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace TheGrayZone.Behaviours
{
  public class OpacityHoverBehaviour : Behavior<UIElement>
  {
    protected override void OnAttached()
    {
      base.OnAttached();

      this.AssociatedObject.MouseEnter += new MouseEventHandler(AssociatedObject_MouseEnter);
      this.AssociatedObject.MouseLeave += new MouseEventHandler(AssociatedObject_MouseLeave);
    }

    protected override void OnDetaching()
    {
      base.OnDetaching();

      this.AssociatedObject.MouseEnter -= new MouseEventHandler(AssociatedObject_MouseEnter);
      this.AssociatedObject.MouseLeave -= new MouseEventHandler(AssociatedObject_MouseLeave);
    }

    private void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)
    {
      this.AssociatedObject.Opacity = 0.6;
    }

    private void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
    {
      this.AssociatedObject.Opacity = 0.8;
    }
  }
}

Then in the UserControl containing the Border element use the following XAML. You need to include the System.Windows.Interactivity namespace and the namespace where your behaviour was declared.

<UserControl
...
  xmlns:behaviour="clr-namespace:TheGrayZone.Behaviours"
  xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">

<Border Style="{StaticResource BorderStyle}">
  <TextBlock Foreground="White" Text="Some Text"/>

  <i:Interaction.Behaviors>
    <behaviour:OpacityHoverBehaviour/>
  </i:Interaction.Behaviors>
</Border>

Finally I’ve defined the following style referenced in the above xaml.


Custom URL Protocol in Windows CE

Posted: 13th August 2010 by thegrayzone in Development
Tags: ,
The Problem

One requirement for my current application is that when the user clicks on a specific link on a web application from their Windows Mobile device, a pre-installed application will be launched on the device and a parameter from the web application will be passed to the application.

The Solution

I decided to use a custom URL Protocol (like http, mailto, ftp etc) to launch the application and pass parameters that way. This would work in the same way as ‘mailto:test@test.com’. This launches the default e-mail program and passes in the e-mail address as an argument. For this article I’ll create the protocol ‘launch’, e.g. ‘launch:my_param’.

Registry Settings

It turns out to be fairly straight forward to get this up and running. First off I found this MSDN article on registering a URL protocol. I found this very helpful but there is an extra registry entry required for Windows CE, below are all of the registry entries that need to be made.

  1. [HKEY_CLASSES_ROOT\launch]
    "URL Protocol"=""
    "(Default)"="URL:Launch Protocol"
    

    The important part here is the “URL Protocol” as this specifies that the entry is a URL Protocol.

  2. [HKEY_CLASSES_ROOT\launch\Shell]
    
    [HKEY_CLASSES_ROOT\launch\Shell\Open]
    
    [HKEY_CLASSES_ROOT\launch\Shell\Open\Command]
    @="\"\\Program Files\\MyApp\\MyApp.exe\" \"%1\""
    

    “\Program Files\MyApp\MyApp.exe” “%1″ specifies the application that is to be launched and the “%1″ part ensures that any arguments will be passed to this application.

  3. [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shell\URLProtocols\launch]
    

    This is the last registry entry that you need and is omitted from the above MSDN article.

Application

To test the URL Protocol I made a standard Device Application. Within the program.cs that is created I changed the Main method to take in a string array of arguments. I then added a string parameter to the constructor of Form1

public static void Main(string[] args)
{
  string param = string.Empty;
  if (args != null && args.Length > 0)
  {
    param = args[0];
  }

  Application.Run(new Form1(param));
}

public Form1(string parameter)
{
  InitializeComponent();
  label1.Text = string.Format("Passed in value is: {0}", parameter);
}

Now when you click on a the following link: “launch:test_param” the application will launch and display the parameter. Without any filtering the whole link will be passed in (i.e. with the “launch:” prefix).