Windows Mobile and Handango Dynamic Registration

Did you every investigate how you could commercialize your Windows Mobile application? Of course there are a lot of different app stores on the internet, very soon Microsoft will open up it’s own Marketplace for Windows Mobile applications. But I think the largest app store for Windows Mobile applications is Handango.

This article is about how to enable a licensing system in your Windows Mobile application that’s compatible with Handango. Handango supports a few registration methods for licenses like: Static, Pool, Dynamic and HTTP Post.

- Static: One registration code unlocks all copies of the software.

- Pool: A pool of unique registration codes given one by one to the customers.

- Dynamic: Handango will create the registration codes based on a RPN string and the customers Device User ID.

- HTTP Post: Handango will communicate with one of your servers through XML to provide license keys.

In my opinion the first one isn’t really safe at all. It of course depends but, I don’t want just one license key. The pool is an option, but if you’ve got a best-selling application it will give you a lot of work.

The Dynamic option sounds interesting but what is a RPN string? More on that later.

The HTTP Post is a very interesting option, but it requires you to develop a service to generate license keys.

Let’s investigate the Dynamic Registration method for licenses for Handango

The Dynamic Registration method uses the customers Device User ID as input. But what is this Device User ID? It’s basically the Owner name of the Windows Mobile device. This is something that’s provided by the customers, so your application should be able to handle different owner names for the application and the device. Though pre filling the registration form in your application with the device owner is probably a good thing. You can get the Device Owner by using this code.

string ownerName = Microsoft.WindowsMobile.Status.SystemState.OwnerName

So that’s the simple part, but what about the RPN string? RPN stands for Reverse Polish Notation. RPN strings are expressions that can be easily parsed. It’s a postfix notation of a normal formula. The following expressions are exactly the same but the RPN one can be easily parsed.

Standard: 2 * 3
RPN: 2 3 *

Besides the ability for you to specify almost any arithmetic / logical / bitwise operators, there are a few parameters you have to put in somewhere in your RPN string. First of all it’s important to know that the owners name will be used in combination with the RPN string. Basically each character will be used with the RPN string. To be more exact, if the owner’s name exceeds 10 characters the first 5 and the last 5 characters of the owner will be used.

The parameters are:

- i: the indexer over the characters, starting with 0.

- key: the result of the RPN evaluation with the previous character, for the first character use 0.

- c: the ASCII value of the character.

An example RPN string can be like this: i 0 == 111 * key + c 2 * +

Handango has a very nice test-site, you can test your RPN string and an owner name to see what the RPN string evaluation will result in.

Let’s build a RPN Evaluator

Alright we now kind of know what RPN stands for, and how it’s used by Handango to generate license keys. I expect the Registration Form in your application to consist of two fields, an owner field and the license key field. I would check the validness of the license key by generating the license key myself by using the same RPN string. After the generation of the license key based on the owners name, it would be easy to compare those licenses.

Let’s first write the code to generate the correct RPN string for each character (first 5 and last 5).

public int SolveRpnFor(string baseRpn, string owner)
{
    if (owner.Length > 10)
        owner = owner.Substring(0, 5) + owner.Substring(owner.Length - 5);
    char[] ownerChars = owner.ToCharArray();
    double key = 0;
    for (int i = 0; i < ownerChars.Length; i++)
    {
        string rpnForChar =
            baseRpn.Replace("i", string.Format("{0}", i))
                .Replace("c", string.Format("{0}", (int) ownerChars[i]))
                .Replace("key", string.Format("{0}", key));
        key = SolveRpn(rpnForChar);
    }
    return (int) Math.Round(key);
}

This code first of all makes sure the owner isn’t longer than 10 characters, if it is the code will pickup the first and last 5 characters. Next we walk through each character, and replace the “i” with the index, the “c” with the ASCII value of the character, and the “key” with the RPN result from the previous character or with 0 if we are create a RPN string for the first character. These are just standard string replacements, but what about the real RPN Evaluation? That’s where we are now.

public double SolveRpn(string rpn)
{
    if (string.IsNullOrEmpty(rpn)) return 0;
    var tokens = new Stack<string>
        (rpn.Split(' ', '\t'));
    if (tokens.Count == 0) return 0;
    double evalResult = EvalRpn(tokens);
    if (tokens.Count != 0) throw new Exception();
    return evalResult;
}

First we convert the elements in the RPN string (divided by either a space or tab) to a stack containing the elements. If the amount of tokens is 0, we return 0. If the amount of tokens isn’t 0 we try to evaluate the stack of elements. If after the evaluation there are still elements in the stack, something definitely has gone wrong, so throw an exception. This exception might happen when the RPN string isn’t a valid RPN string.

We know like any formula a RPN string contains both values and operators. Let’s define the operators and write the function calls for them. We need a class to represent the operator and the function as well.

private class Operator
{
    public string Sign { get; set; }
    public Func<double, double, double> Function { get; set; }
}

private readonly List<Operator> operators =
    new List<Operator>
        {
            new Operator {Sign = "+", Function = (argX, argY) => argX + argY},
            new Operator {Sign = "-", Function = (argX, argY) => argX - argY},
            new Operator {Sign = "*", Function = (argX, argY) => argX*argY},
            new Operator {Sign = "/", Function = (argX, argY) => argX/argY},
            new Operator {Sign = "^", Function = Math.Pow},
            new Operator {Sign = "%", Function = (argX, argY) => argX%argY},
            new Operator {Sign = "<<", Function = (argX, argY) => (int) argX << (int) argY},
            new Operator {Sign = ">>", Function = (argX, argY) => (int) argX >> (int) argY},
            new Operator {Sign = "==", Function = (argX, argY) => (argX == argY) ? 1 : 0},
            new Operator {Sign = "<", Function = (argX, argY) => (argX < argY) ? 1 : 0},
            new Operator {Sign = "<=", Function = (argX, argY) => (argX <= argY) ? 1 : 0},
            new Operator {Sign = ">", Function = (argX, argY) => (argX > argY) ? 1 : 0},
            new Operator {Sign = ">=", Function = (argX, argY) => (argX >= argY) ? 1 : 0}
        };

Each Operator has a sign and an expression on how to calculate the result, basically each operation has two input values and one result. That makes it easy. As you can see there are a lot of operations in this list but the list isn’t complete. You can of course add other operators if you require them.

Alright we now have a stack setup and the operations, let’s walk through the stack and evaluate that RPN string.

private double EvalRpn(Stack<string> tokens)
{
    string token = tokens.Pop();

    Operator operatorFound = operators.Where(o => o.Sign == token).FirstOrDefault();

    double x;
    if (operatorFound != null)
    {
        double y = EvalRpn(tokens);
        x = EvalRpn(tokens);
        x = operatorFound.Function(x, y);
    }
    else
    {
        x = double.Parse(token);
    }
    return x;
}

I think the recursive mind in this code makes it very clean, but also difficult to understand. Let’s walk through the code.

- Pop the first token from the stack.

- Find out if this token is an operator and save the operator in a variable.

- If it isn’t an operator just parse it as a double and return it.

- If it is an operator evaluate the next things in the stack for y and x. (this is where the recursion comes in)

- Execute the operator on both x and y and return the result of it.

This code can evaluate RPN strings like: i 0 == 111 * key + c 2 * +

But make sure you always test your RPN strings and compare with the Handango test site result. It’s also very important you keep your RPN strings secret, because it enables people to generate license keys. I suggest to change the RPN string every time you have a new release. I am not guaranteeing this code is working correctly in all situations, and probably this code can be enhanced, but it’s a first start for you to create production ready code. To be complete you can use the full RpnService class.

public class RpnService
{
    private readonly List<Operator> operators =
        new List<Operator>
            {
                new Operator {Sign = "+", Function = (argX, argY) => argX + argY},
                new Operator {Sign = "-", Function = (argX, argY) => argX - argY},
                new Operator {Sign = "*", Function = (argX, argY) => argX*argY},
                new Operator {Sign = "/", Function = (argX, argY) => argX/argY},
                new Operator {Sign = "^", Function = Math.Pow},
                new Operator {Sign = "%", Function = (argX, argY) => argX%argY},
                new Operator {Sign = "<<", Function = (argX, argY) => (int) argX << (int) argY},
                new Operator {Sign = ">>", Function = (argX, argY) => (int) argX >> (int) argY},
                new Operator {Sign = "==", Function = (argX, argY) => (argX == argY) ? 1 : 0},
                new Operator {Sign = "<", Function = (argX, argY) => (argX < argY) ? 1 : 0},
                new Operator {Sign = "<=", Function = (argX, argY) => (argX <= argY) ? 1 : 0},
                new Operator {Sign = ">", Function = (argX, argY) => (argX > argY) ? 1 : 0},
                new Operator {Sign = ">=", Function = (argX, argY) => (argX >= argY) ? 1 : 0}
            };

    public int SolveRpnFor(string baseRpn, string owner)
    {
        if (owner.Length > 10)
            owner = owner.Substring(0, 5) + owner.Substring(owner.Length - 5);
        char[] ownerChars = owner.ToCharArray();
        double key = 0;
        for (int i = 0; i < ownerChars.Length; i++)
        {
            string rpnForChar =
                baseRpn.Replace("i", string.Format("{0}", i))
                    .Replace("c", string.Format("{0}", (int) ownerChars[i]))
                    .Replace("key", string.Format("{0}", key));
            key = SolveRpn(rpnForChar);
        }
        return (int) Math.Round(key);
    }

    public double SolveRpn(string rpn)
    {
        if (string.IsNullOrEmpty(rpn)) return 0;
        var tokens = new Stack<string>
            (rpn.Split(' ', '\t'));
        if (tokens.Count == 0) return 0;
        double evalResult = EvalRpn(tokens);
        if (tokens.Count != 0) throw new Exception();
        return evalResult;
    }

    private double EvalRpn(Stack<string> tokens)
    {
        string token = tokens.Pop();

        Operator operatorFound = operators.Where(o => o.Sign == token).FirstOrDefault();

        double x;
        if (operatorFound != null)
        {
            double y = EvalRpn(tokens);
            x = EvalRpn(tokens);
            x = operatorFound.Function(x, y);
        }
        else
        {
            x = double.Parse(token);
        }
        return x;
    }
		
    #region Nested type: Operator

    private class Operator
    {
        public string Sign { get; set; }
        public Func<double, double, double> Function { get; set; }
    }

    #endregion
}