Exchange ActiveSync Building Blocks – GAL Search

Index for the series:
Exchange ActiveSync Building Blocks – Intro

Background reading (not a pre-requisite):
[EAS Building Blocks] – Encode & Decode
[MS-ASCMD] Searching the Global Address List
[MS-ASWBXML] Code Page 16: GAL

Any luck with your own WBXML testing yet? While I hope the encoder/decoder was understandable in it’s own right I thought I’d just show another example of what becomes very easy to implement once you’ve got that dll-file in place sorting out the XML for you.

I’ve tested a couple of Exchange ActiveSync clients during the past couple of years, and while some of them are quite usable in their implementation I sometimes wonder why some clients just aren’t getting GAL search done in a user-friendly way. Why do I have to go into some strange sub-menu of the mail view to look up someone I work with? And then have to copy-paste the phone number or email address instead of just getting a context menu letting me choose and get a shortcut to the corresponding app? Oh, well, better off just doing your own search I guess Smile

Thing is it’s quite easy really with the tools we have by now.

Throwing up a quick UI based on the same super-fancy layout we’ve done a couple of times now:
image

I searched the GAL for a first name, but it’ll also work with last name or alias. It doesn’t want to go along with me searching for things like phone number; not sure why. Exchange tells me the request was invalid… I’ll admit I haven’t researched the cause of it so I don’t know if it’s supposed to work either.

You can only see some of the returned properties in the screenshot, but you should be able to see the following properties if you test it yourself:
DisplayName, Phone, Office, Title, Company, Alias, FirstName, LastName, HomePhone, MobilePhone, EmailAddress, Picture, Status & Data. (If your EAS level supports it, and the properties are defined in the user object in Active Directory.)

It’s really just a matter of defining the XML as a string behind the scenes:

<?xml version="1.0" encoding="utf-8"?>
<Search xmlns="Search:">
	<Store>
		<Name>GAL</Name>
		<Query>andreas</Query>
	<Options>
		<Range>0-1</Range>
	</Options>
	</Store>
</Search>

Putting this into the context of a C# method it looks like this:

private void btnSearch_Click(object sender, EventArgs e)
{
    string strUsername = txtUsername.Text;
    string strPassword = txtPassword.Text;
    string strDomain = txtDomain.Text;
    string strServerAddress = txtServerAddress.Text;
    string strQuery = txtQuery.Text;

    string strEncCredentials = null;

    strEncCredentials = getEncCredentials(strUsername, strPassword, strDomain);

    string strQueryXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Search xmlns=\"Search:\"><Store><Name>GAL</Name><Query>" + strQuery + "</Query><Options><Range>0-1</Range></Options></Store></Search>";
            
    StringReader sourceXml = new StringReader(strQueryXml);

    XDocument sourceWbxml = XDocument.Load(sourceXml);

    WBXMLWriter wbxmlWriter = new WBXMLWriter(new WBXML.ASCodePageProvider());
    WBXMLConverter wbxmlConverter = new WBXMLConverter(new ASCodePageProvider(), wbxmlWriter, null);

    IList<byte> bDestWbxml = wbxmlConverter.Parse(sourceWbxml);

    string strDeviceId = "IMEI1234";
    string strDeviceType = "FakeDevice";
    string strUserAgent = "MobilityDojo.net";
    string strASVersion = "14.1";

    string uri = strServerAddress + "/Microsoft-Server-ActiveSync" + "?Cmd=Search" + "&User=" + strUsername + "&DeviceId=" + strDeviceId + "&DeviceType=" + strDeviceType;
    HttpWebRequest webRequestWbxml = (HttpWebRequest)WebRequest.Create(uri);
    webRequestWbxml.ContentType = "application/vnd.ms-sync.wbxml";

    webRequestWbxml.Method = "POST";
    webRequestWbxml.Headers.Add("Authorization", "Basic " + strEncCredentials);
    webRequestWbxml.Headers.Add("MS-ASProtocolVersion", strASVersion);
    webRequestWbxml.UserAgent = strUserAgent;

    webRequestWbxml.ContentLength = bDestWbxml.Count;
    try
    {
        byte[] bBuffer = new byte[bDestWbxml.Count];
        bDestWbxml.CopyTo(bBuffer, 0);

        Stream sw = webRequestWbxml.GetRequestStream();
        sw.Write(bBuffer, 0, bBuffer.Length);
        sw.Close();

        txtOutput.Text += "Response: " + "\r\n\r\n";
        WebResponse webResponseWbxml = webRequestWbxml.GetResponse();
        if (webResponseWbxml == null)
        {
        }

        System.Text.UTF8Encoding utf8Encoding = new System.Text.UTF8Encoding();
        StreamReader srResponse = new StreamReader(webResponseWbxml.GetResponseStream());

        string responseBody = srResponse.ReadToEnd().Trim();
        Byte[] byteResp = utf8Encoding.GetBytes(responseBody);

        XElement destXml = wbxmlConverter.Parse(byteResp);

        txtOutput.Text += destXml.ToString();
    }

    catch (WebException)
    {
    }
}

Not much more to it I suppose 🙂 It would obviously be cooler if I had implemented this in a dynamic web page, or really jazzy widget for a mobile device of your choosing, but the UI part is taking the backseat. I hope it inspires someone else to do as user-friendly GAL lookups as possible Smile

Downloads:
C# Source – GALSearch.cs
C# Source – EAS_BB_Part-09_01.zip

4 thoughts on “Exchange ActiveSync Building Blocks – GAL Search”

  1. Hi Andreas,

    Thanks for these detailed articles. It makes the EAS protocol more clear for us.

    We are doing research to create an Exchange client in Silverlight. Do you think Active Sync is the right protocol for that purpose?

    We would like to sync e-mail, contacts, appointments and tasks. Like Outlook Web App but then in our own Silverlight app.

    We did research on EWS, Power Shell and EAS.

    Thanks. Hans

  2. It’s dependent on your specific scenario really. PowerShell is great for a lot of things like configuration and server admin tasks, but less suited for mail/contacts/etc. PowerShell is also more suitable for use over the LAN than the Internet.

    EWS is on par with EAS for most mail-related things. Most parts of Outlook Web App is done in EWS “behind the scenes” so that would give you an idea of what is possible. There are some things EAS is more suited for though, and of course you are affected in different ways when it comes to policies.

    I would probably end up with a mix of EWS and EAS if I could solve the authentication part in a smooth way.

  3. I am developing active sync client and wondering How we can we read mails and attachment using was protocol implementation?

Leave a Reply

Your email address will not be published. Required fields are marked *

*