Thursday, February 02, 2006

Walter, the IE Program Manager, just announced on the IEBlog that the Windows RSS Platform is going to be available on the Windows XP as well as Vista. It will be installed as a part of IE7 package. This is indeed a great news and shows Microsoft's commitment to the “RSS anywhere” paradigm and would like to remind that they should not forget the Windows CE world. I am a strong believer that RSS has a great potential that is going to grow beyond Weblogs and news feed applications.

RSS
2/2/2006 6:35:14 PM (GMT Standard Time, UTC+00:00)  #    Comments [38]  | 
 Thursday, January 26, 2006

In my previous post I showed you the class diagram and the usage for the Licensing classes that are available as a part of SDF v2.

Today I'll explain a few other steps that you will be required to do in order to have licensing enabled in your application.

Attentive readers had probably noticed from looking at the class diagram that I have provided implementation of a concrete class PublicKeyLicenseProvider that inherits from the abstract LicenseProvider. The internal implementation of the PublicKeyLicenseProvider class is based on the asymmetric encryption such as RSACryptoServiceProvider. This was made possible by the fact that Microsoft has provided the implementation of the System.Security.Cryptography namespace to the CF v2.

Little bit of the background information on the asymmetric encryption. Asymmetric Encryption is a form of encryption where keys come in pairs. What one encrypts, only the other can decrypt. Asymmetric Encryption is also known as Public Key Cryptography, since users typically create a matching key pair, and make one public while keeping the other secret.

This fact has brought me to the idea of possibility to implement an almost fool proof system for licensing of components and applications in the CF v2. Even considering an "openness" of the .NET assemblies through the tools like Reflector, as long as your private key will stay unknown to a possible hacker, they will have a little chance to break the encryption.

And now after you have digested this information, you should be able to understand the other steps that are required:

1. You will have to generate a pair of the Public and Private keys. I have created a class LicenseKeyGenerator to help you with this task. Here's the CreateKeyPair method that you can use on either Windows CE or a desktop to generate these keys:

public static void CreateKeyPair( string path, int keySize )

{

      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider( keySize );

      // Open the file stream for writing of the public key

      FileStream keyWriter = new FileStream(Path.Combine(path, "Pub.key"), FileMode.Create);

      // Get the key from provider

      byte[] key1 = rsa.ExportCspBlob(false);

      //Write it to the file

      keyWriter.Write(key1, 0, key1.Length);

      keyWriter.Close();

 

      // Open the file stream for writing of the private key

      keyWriter = new FileStream(Path.Combine(path, "Priv.key"), FileMode.Create);

      // Get the key from provider

      byte[] key2 = rsa.ExportCspBlob(true);

      //Write it to the file

      keyWriter.Write(key2, 0, key2.Length);

      keyWriter.Close();

}

2. Add the generated public key file Pub.key to the root (this is very important) of your project and set its Build Action to the Embedded Resource.

3. Add the LicenseProviderAttribute to your component as I had already shown to you in the previouse post.

4. Generate the license file based on the user data. The license is a simple XML file in the following format:

<licenseKey version="1.0">

    <product version="1.0.3.2489">NewControlproduct>

    <customerInfo>

        <Name>John DoeName>

        <Email>john.doe@mail.comEmail>

    customerInfo>

    <key>f4/WgB2JhgR9bQibFa6rbGDugM+4wqbyM/ES+6W17gxx+x//G9at5he3yT0wZGwk2okSAzqrRJoNfsakEDMlFg==key>

licenseKey>

 

The value of the key tag is the public key that we have generated in the previouse step. Here is the method Generate from the LicenseKeyGenerator class:

public void Generate(string publicKeyFile, string licenseFile)

{

      //Open public key file

      FileStream fs = new FileStream(licenseFile, FileMode.Open);

      BinaryReader keyReader = new BinaryReader(fs);

      // Create encryptor

      RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();

      rsaProvider.ImportCspBlob(keyReader.ReadBytes((int)keyReader.BaseStream.Length));

 

      // sign and save.

      this.Sign(rsaProvider);

      this.Save(licenseFile);

}

And you will use it like so:

private void cmdGenerate_Click(object sender, EventArgs e)

{

       // Create new license key.

       LicenseKeyGenerator licenseKey = new LicenseKeyGenerator();

       licenseKey.ProductName = txtProduct.Text;

       licenseKey.ProductVersion = txtVersion.Text;

       licenseKey.CustomerName = txtCustName.Text;

       licenseKey.CustomerEmail = txtCustEmail.Text;

 

       licenseKey.Generate((Application.ExecutablePath) + @"\Keys\Priv.Key", "MyCompany.NewControl.lic");

}

You can download the full version for the LicenseKeyGenerator class and a sample project from here:

GenLicense.zip (23.81 KB)

After you are done with these steps, the result is simple and effective - you've got a licensing system in place that would be rather hard to brake and easy to use.

1/26/2006 1:52:45 PM (GMT Standard Time, UTC+00:00)  #     | 
 Wednesday, January 25, 2006

The beta of the SDF v2.0 is available for download. We have worked really hard toward this release. Of course it fully supports the VS 2005 and CF v2. The SDF v2 also includes a lot of new functionality. Among those I would like to present to you the Licensing classes that I have developed. In the next few posts I will try to describe its design and show you how to actually use it.

The design of the Licensing functionality is based on the existing classes from the System.ComponentModel on the desktop like the Lisense, LicenseProvider, etc... Here is the class diagram representing the class structure of the Licensing library in the SDF v2:

So how would you use this library? The same way it is described in the MSDN documentation. Add the LicenseProviderAttibute to your component and use the LicenseManager to validate the license:

[LicenseProvider(typeof(PublicKeyLicenseProvider))]

public partial class NewControl : UserControl

{

     public NewControl()

   {

         InitializeComponent();

         

         if (!LicenseManager.IsValid(typeof(NewControl)))

         {

              MessageBox.Show("NewControl has invalid license");

         }

   }

 }

 

In the next post I'll explain to you which additonal steps are required to use the Licensing classes in your CF v2 application.

1/25/2006 4:47:00 PM (GMT Standard Time, UTC+00:00)  #    Comments [46]  | 
 Tuesday, January 17, 2006

The DateTimePicker control in the .NetCF v2 doesn't implement DropDown and CloseUp events which could be really helpful whe dealing with the picker. It doesn't mean that these events or messages are not available in the native counterpart. Win CE SDK docs show the presence of the DTN_CLOSEUP and DTN_DROPDOWN notification messages. It means that they are sent by the DateTime picker to its parent. So, I pulled the NativeWindow class to whip up the DateTimePickerEntender class that suclasses the form, catches the messages and raises the events to the client:

public class DateTimePickerExtender : NativeWindow

{

        public event System.EventHandler CloseUp;

        public event System.EventHandler DropDown;

 

        private IntPtr handle;

 

        public DateTimePickerExtender(IntPtr handle)

        {

            this.handle = handle;

            // Subclass the window

            this.AssignHandle(handle);

        }

 

        protected override void WndProc(ref Message m)

        {

            // Check for notification messages

            if (m.Msg == WM_NOTIFY)

            {

                NMHDR nmhdr = new NMHDR();

                        Marshal.PtrToStructure(m.LParam, nmhdr);

                switch (nmhdr.code)

                {

                    case DTN_DROPDOWN:       

                        // Raise the event

                        if (DropDown != null)

                            DropDown(this, new EventArgs());

                        break;

                    case DTN_CLOSEUP:

                        // Raise the event

                        if (CloseUp != null)

                            CloseUp(this, new EventArgs());

                        break;

                }

            }

            base.WndProc(ref m);

        }

 

 

        #region P/Invoke declarations

 

        private const int WM_NOTIFY = 0x004E;

 

        private const int DTN_FIRST = -760;

        private const int DTN_DROPDOWN = (DTN_FIRST + 6);

        private const int DTN_CLOSEUP = (DTN_FIRST + 7);

 

        private class NMHDR

        {

            public IntPtr hwndFrom = IntPtr.Zero;

            public uint idFrom = 0;

            public int code = 0; //uint

        }

 

        #endregion

}

Drop the DateTimePicker controls on the form, create and instance of the DateTimePickerExtender and hook up into the events:

DateTimePickerExtender dtEntender;

 

public Form1()

{

     InitializeComponent();

     dtEntender = new DateTimePickerExtender(this.Handle);

     dtEntender.CloseUp += new EventHandler(dtEntender_CloseUp);

     dtEntender.DropDown += new EventHandler(dtEntender_DropDown);

}

 

void dtEntender_DropDown(object sender, EventArgs e)

{

     Console.WriteLine("DropDown event");

}

 

void dtEntender_CloseUp(object sender, EventArgs e)

{

     Console.WriteLine("CloseUp event");

}

 

1/17/2006 7:35:53 PM (GMT Standard Time, UTC+00:00)  #     | 
 Thursday, January 05, 2006

Questions about embedding Macromedia Flash in CF application pop up from time to time on the CF NG. In fact it is very easy to do with Flash ActiveX for Pocket PC and WebBrowser control.

Here are five steps to achieve that:

1. Download and install Flash ActiveX for Pocket PC on your Pocket PC.

2. Create Smart Device and CF v2 project in VS 2005 and drop WebBrowser on your form.

3. Add flash file (.SWF) of your choice to your project and set its Built Action to content and “Copy if newer”

4. Create html file and make sure that you have a full path to the .SWF file in the src tag value:

<html>

<head>

<title>Dogshow Gametitle>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

head>

 

<body bgcolor="#FFFFFF" margintop=0 topmargin=0 leftmargin=0 marginleft=0>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="580" height="360">

  <param name=movie value="dogshow.swf">

  <param name=quality value=high>

  <embed src="file://\Program Files\MMediaClient\dogshow.swf" quality=high pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="580" height="360">

  embed>

 

object>

body>

html>

5. Make a call to the Navigate method with the name of your html file:

webBrowser1.Navigate(new Uri(@“file://\Program Files\MMediaClient\dogshow.htm“));

 

And enjoy the show:

1/5/2006 4:56:57 PM (GMT Standard Time, UTC+00:00)  #     | 
 Tuesday, January 03, 2006

You probably know how difficult it was to create a screen snapshot in CF v1. It required usage of many API calls and custom marshaling of a few structures. Just take a look at these resources:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/scibf.asp?frame=true

http://vault.netcf.tv/VaultService/VaultWeb/Blame.aspx?repid=2&path=%24%2fSDF%2fv1.4%2fOpenNETCF.Drawing%2fGDIPlus.cs&version=5&includedversions=20

The world has become a much better place since release of the CF v2 - availability of the native handles and ability to save image from Bitmap - have reduced the required code to just a few lines and one API call:

private void Snapshot(string filename, Graphics gx, Rectangle rect)

{

     Bitmap bmp = new Bitmap(rect.Width, rect.Height);

     // Create compatible graphics

     Graphics gxComp = Graphics.FromImage(bmp);

     // Blit the image data

     BitBlt(gxComp.GetHdc(), 0, 0, rect.Width, rect.Height, gx.GetHdc(), rect.Left, rect.Top, SRCCOPY);

     bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);

     // Cleanup

     bmp.Dispose();

     gxComp.Dispose();

}

 

// P/Invoke declaration

[DllImport("coredll.dll")]

public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);

 

const int SRCCOPY = 0x00CC0020;

All you need to use it is just place the Snapshot method on your form and call it like that:

//Create a snapshot of a current view of the TextBox

Snapshot(@"\Temp\save.bmp", this.CreateGraphics(), textBox1.Bounds);

 

1/3/2006 1:44:08 PM (GMT Standard Time, UTC+00:00)  #     | 
 Wednesday, December 21, 2005
 Friday, December 09, 2005

I've got the following info from Microsoft guys that could be helpful for anybody:

The following downloads for SQL Server 2005 Mobile Edition (SQL Server Mobile) available at http://download.microsoft.com is described below. For more information please refer to the SQL Server Mobile website at http://www.microsoft.com/sql/editions/sqlmobile.

a.    Microsoft SQL Server 2005 Mobile Edition Server Tools - The package installs the SQL Server Mobile Replications Components on the machine running the IIS server. The components are required for connecting the SQL Server Mobile database on a mobile device to SQL Server 2000 SP3a database and later versions. Link to download: http://www.microsoft.com/downloads/details.aspx?familyid=6ed0fb7e-7c05-4f59-879a-8fb619e36612&displaylang=en

b.    Microsoft SQL Server 2000 Service Pack 4 Replication Components – The package installs the SQL Server 2000 SP4 replication components on the machine running the IIS server. The components are required for connecting the SQL Mobile database on a mobile device to a SQL Server 2000 SP4 database. Link to download: http://www.microsoft.com/downloads/details.aspx?familyid=a0241f9c-79b1-4011-81e3-2601aa701e02&displaylang=en

c.     Microsoft SQL Server 2000 Service Pack 3a Replication Components – The package installs the SQL Server 2000 SP3a SQL Server 2000 SP3a replication components on the machine running the IIS server. The components are required for connecting the SQL Mobile database on a mobile device to a SQL Server 2000 SP3a database.  Link to download: http://www.microsoft.com/downloads/details.aspx?familyid=a9e0cea0-6f8d-4625-af71-fc8d671f64b6&displaylang=en

d.     Microsoft SQL Server 2005 Mobile Edition Device SDK – The SDK contains the product installers files for installing SQL Server Mobile on the mobile devices, and it also contains the DLL’s and Header files required for developing SQL Mobile applications on the Desktop. Link to download: http://www.microsoft.com/downloads/details.aspx?FamilyId=5BD8ABAA-5813-4DB3-B23A-24551DE2ECC1&displaylang=en

e.     IBuySpy Delivery 2005 Developer Toolkit Sample Application– The Toolkit is a sample e-commerce storefront to demonstrate how simple it is to create scalable applications for the Microsoft® .NET® platform by using SQL Server Mobile . Link to download: http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=7A5F64B0-4E64-4A72-A2C9-994A0C55CECD .

Apart from these the following are also available – 

EULA for SQL Server Mobile Device SDK: http://download.microsoft.com/download/2/4/8/2482E95D-00FD-4374-BD15-57A8C4C34444/EULA.rtf

ReadMe file for SQL Server Mobile Device SDK: http://download.microsoft.com/download/2/4/8/2482E95D-00FD-4374-BD15-57A8C4C34444/SSMREADME.htm

Help File for the SQL Server Mobile: http://download.microsoft.com/download/2/4/8/2482E95D-00FD-4374-BD15-57A8C4C34444/ssm3chm.chm

 

12/9/2005 2:38:47 PM (GMT Standard Time, UTC+00:00)  #     |