Tuesday, January 30, 2007

Installing a CE MAPI filter

We all know how this is done, right? We start by installing the CE MAPI filter DLL on the device (must be signed for WM5 devices), we register it and we restart the messaging application. Hum... How do we restart the messaging application? My approach (and I have to say it is not only my approach because I see it a lot) is to soft-reset the device. Not bad for a Pocket PC 2003, but a nuisance for a WM5 device - it just takes too long to reboot. Needless to say, this approach is a nightmare for developers trying to debug a CE MAPI filter DLL: you have to restart the device twice for each deployment (registering and unregistering the DLL).

There is a better way, though: the messaging application can be closed with a simple WM_CLOSE message sent to the right window. To find that window, use the FindWindow API with the "Inbox.MainWnd" class name. Once you close the messaging application, you can register and unregister the DLL without resetting the device. Nice.

Wednesday, January 24, 2007

Read-only SDF files

Ever tried opening a read-only SDF file? The OLE DB provider will refuse to open it, reporting error number 25039 (SSCE_M_FILEACCESSDENIED): "Access to the database file not allowed". The workaround for this is to provide a writeable path for the temporary files directory on the connection string (or connection properties). Thanks for this piece of info, Laxmi!

Friday, January 19, 2007

Reading the GPS port on the HTC P3300

So how do you read a COM port? After a few years of practice I got the impression that using WaitCommEvent on a thread was an assured way of catching all the characters sent by the serial port. As a matter of fact I have used the same code over and over again with the same reliable results, whether I was reading a real serial port or an emulated one over a Bluetooth connection.

Recently I had to tackle the built-in GPS serial port of the HTC P3300 and got a big surprise: my code wouldn't work! In fact, no characters were being buffered by the thread code meaning that the consuming application was receiving no data... After a close examination of what was going on in the thread code, I realised that no events were being generated by the serial port, namely the EV_RXCHAR that is used to signal that the serial port has characters to deliver. Interestingly, if you use the ReadFile API with a reasonable set ot timeouts you will be able to read data.

It is baffling to se how unreliably hardware support for common stuff like serial ports can be implemented. I'm still trying to figure out why HTC implemented it this way...

Friday, January 12, 2007


It's nice when you see your (modest) offline help publicly recognized. Thanks for this, Maurizio!

Time to update eVC4?

I'm getting a few weird 0x80000002 exceptions in my eVC4-generated code. After looking around, it looks like this *may* be a compiler issue. Microsoft has provided an update to address this. I wil try it out and post back the results.

Well, this was *my* error, not eVC4's... Shame on me.

Friday, January 05, 2007

RAPI Data Throttling

One of the significant changes of Windows Mobile 5 devices over the previous generation was the noticeable speedup of RAPI communications. My iPAQ 2210 just crawls when compared to the either the JasJar or the K-Jam (with a slower CPU). This means that it is much easier for me to test my remote database access code on the WM5 devices, but I still keep my pledge to support older devices like my pre-historic iPAQ 3850 with the Pocket PC 2002 OS. And this means slower RAPI connections.

The connection speed can be so slow to the point where loading a very large table from the iPAQ 2210 (on a CF card) to the new Console may take several minutes. In the case of the huge table I discussed before, this means a 15 minute load time. If you think like I do, this is unnacceptable. So how can we speed up the communication between the device and the desktop? Easy: ZIP it!

In my particular case this was quite easy. All of my remote database access products use the same device DLL that communicates with the desktop via RAPI, TCP/IP or even the serial port. Data is packaged in messages of varying sizes and, depending on their semantics, they are either dispatched immediately or grouped together in a 64 KB buffer and sent when it fills up. This seems to be the optimal size for RAPI connections (according to one slide deck from MEDC 2005). So what happens if you compress this buffer before sending it? In my case the data transfer time was cut to a third. Now the behemoth table downloads to the desktop in under 5 minutes.

Finally, the ZIP library I'm using was found in CodeProject. This code allows me to compress and uncompress to a memory buffer, making it perfect for my own purposes.

Tuesday, January 02, 2007