Windows CE GPSID, its C# wrapper, and device emulator interaction issues

GPSID (the GPS abstraction APIs introduced in Windows Mobile 5) has a few known issues (aka bugs).  This is rather complicated due to versioning issues and also because of a C# wrapper library for the API’s that work around the bug, which may or may not exist on certain platforms. 

The base issue is that when GPSID shipped to our OEMs in Windows Mobile 5, it returned longitude and latitude in a very bad format.  (Raw from the NMEA stream and not in reasonable degrees).  It was possible to compute a reasonable representation of lat/long from what GPSID returned, but it was not reasonable to have every ISV in the world do this.  So before our OEMs shipped any devices (it takes a few months for them to get ready) we released a fix to GPSID so it returned reasonable values and it was put on all actual PocketPC + SmartPhone devices.  This should have been the end of the story.  Unfortunately there are other factors here.

Another MS developer created a C# wrapper library for GPSID that just P/Invoked the GPSID API’s.  He dealt with the bad values that GPSID was returning pre-fix and converted them to be reasonable for the app.  Unfortunately, the C# APIs were not fixed to remove this workaround when GPSID was fixed.  So currently they are doing a conversion of the correct lat/long values, which means they’re returning bogus data now.

Further complicating this is that while the GPSID fix made it to PocketPC + SmartPhone ROMs, it did not make it to the device emulator.  So that means on the emulator the C# piece actually does work correctly because it’s still fixing valid data, but using the C APIs will give invalid results.

GPSID with C APIs:
    STATUS: Will not work (GPSID bug not fixed)
    WORKAROUND: Call GetDegreesFromAngular() (see below) on lat + long values.
  PocketPC/SmartPhone (real device)
    STATUS: Will work (GPSID bug was fixed)
    WORKAROUND: Not needed

GPSID with C# APIs:
    STATUS: Will work (GPSID bug not fixed, C# work around for issue in place)
    WORKAROUND: Not needed
  PocketPC/SmartPhone (real device)
    STATUS: Will not work (C# API working around a bug that no longer exists)
    WORKAROUND: Remove the C# code (it was shipped as source) that does the unneeded conversion.

We’re very likely to get the C# wrapper fixed in a future release.  Fixing GPSID on the emulator is under investigation.  You can tell if underlying GPSID is fixed simply by making sure that the lat/long values it returns are what they’re supposed to be for whatever the GPS driver is telling it.

As promised above, the conversion function you need ONLY on emulator and using C API lat/long (note I haven’t tested this as I’m describing below but it should work)

DOUBLE GetDegreesFromAngular(DOUBLE dbl) {
        dbl /= 100;

 int    i    = (int) dbl;
 DOUBLE frac = (dbl – (double)i) * (100.0 / 60.0);

 return ((double)i + frac);

I apologize for all the problems this caused.  The fault here is totally mine, and not the C# developer.  Thanks to Christopher E Piggott of Rochester Institute of Technology and Trapulo “of Italy” (sorry I don’t know your real name) for bringing all the C# + emulator issues to my attention and testing out some theories I had.

[Author: John Spaith]

Comments (27)

  1. wz2b says:

    Good post.

    What would  happen if I went  to my Axim, grabbed GPSID.dll, and copied it to the device emulator?

  2. cenet says:

    For copying GPSID.dll to device emulator, I believe that would work.  There’s one way to find out :).  You’ll need to get the original GPSID out of the device emulator "ROM" for your new one.  I’ve never used device emulator so I’m not sure how you’d go about doing that; in the worst case you’d just need to find any gpsid.dll instance in the device registry and replace with say "mygpsid.dll" and reboot (make sure your device emulator flushes registry between reboots, don’t know if it would or no).


  3. Jon Person says:

    Hi John,

       Great job on the intermediate driver!  Being able to share the GPS device is a common request from my customers and I’m glad to be able to help them thanks to you.  I have some C# code for configuring the Intermediate Driver from managed code, which I’d be happy to pass along for anyone interested.

       I’m also interested in trying to hook the intermediate driver up to our "GPS.NET" product’s GPS device emulator namespace.  The idea is to have our virtual GPS device classes feed raw NMEA-0183 data into the Intermediate Driver as a way to use the PDA when no GPS signal is present, or for developers who wish to write test cases against varying models of virtual GPS devices.  Is it possible to control the feed of raw NMEA data into the driver?

    Thanks very much,

    Jon Person

  4. cenet says:

    Jon — sorry for the delay in responding, our blog software doesn’t notify us of new posts.

    For your question, there are a few ways you can solve this.  One is to create the NMEA file itself and have GPSID itself read from the file directly (rather than a COM port).  This is doc’d in MSDN and I believe has been good enough for most folks, it’s called the "file driver" or something along those lines in main GPSID documentation.

    It’s also possible to hook into another driver to get absolute control over what GPSID gets (the file driver reads like 80 bytes at a time always and you can’t change the data file without stopping + starting GPSID by comparison).  This is harder though.  What you’d need to do is to create a device driver that is a virtual serial driver, then have GPSID consume the data from "COM4:" or whatever.  I have a services.exe white paper on MSDN that explains how to write a network service, this is kind of similiar even though you’d need to be in device.exe instead.  The "GPS.Net" makes me think though that this is a C# app you have today, which isn’t something device.exe can run, so you’d need the device driver from scratch (based on my naive reading).

    John Spaith

  5. Chris Richards says:

    Hi John,

    I cannot find the gpsid.dll in the WIndows directory on my device, an Orange M600. Do you know what needs to be done to get this dll working on my device? I guess Orange have removed it from the ROM, but is it possible to install again?


  6. cenet says:

    Chris, a few possibilities here

    1) GPSID is for Windows Mobile 5.0 only.  Is this a PPC2003 or earlier?

    2) Your file explorer may be lying to you.  Many of them hide system files, which GPSID is.  If you can see windowscoredll.dll, then you can see system files.

    3) If this is a wM5 and Orange removed it from ROM, it’s theoretically possible to put it back but in practice it would be quite hard.  And it’s not something you could distribute to other Orange users, as ultimately our partners own their platforms and decide which MS components they take or don’t take.

    John Spaith

  7. Chris Richards says:


    1) Yes this is a WM5 device with AKU 2 (Build 14847.2.0.0)

    2) I have selected the Show All Files option in File Explorer and can see coredll.dll

    3) Could you point me in the right direction to put the driver back? This is for my personal use so I’m not interested in distributing to other users.

    Thanks in advance.


  8. Ken Adam says:

    I have been developing for the MIO A201 (GPS/PDA) and for the MIO A701 (GPS/PDA/Phone), using C.

    Curiously, the GPS ID on the A701 (later model) returns the Lat/Long in the raw format, whereas the 201 provides the expected values.

    This seems inconsistent with what you reported – could it be that the 701 has an older GPSAPI loaded?

    Would I be able to replace it with the one from the 201?


  9. cenet says:

    To answer Chris’s question about getting the GPSID driver back on — wow, I really don’t know if it’s possible to do (cleanly).  You’d also need GPS registry settings.  I would recommend going to the newsgroups on this one.  The way that OEMs actually decide which binaries to put onto images isn’t something I’m all that familiar with.

  10. Christopher Piggott says:

    I think you should try to just plunk the .DLL on and see what happens, then tell us 🙂

  11. Miguel Santos says:

    Answering Ken Adam. I have the same problem with Mio A701, I have open a incident with MIO, but still no answer. I think might be a problem with Ephemeris tool they install on the device… John is aware of this problem to. Does anybody knows if the problem also happens with Eten G500?

  12. Mike says:

    Hi John,

    could you be a bit more specific on the "bogus values"? What do you mean with "You can tell if underlying GPSID is fixed simply by making sure that the lat/long values it returns are what they’re supposed to be for whatever the GPS driver is telling it."?

    Could you give some margin  of error? How muchg do the bogus values differ from the error-free values? Degrees? minutes? seconds? Could you give an example?

    Thanks, Mike

  13. cenet says:

    Mike – please see documentation about the exact format returned.  The legit values (fixed GPSID) for say Redmond WA, USA will be like 47.44, -122… whereas the bogus values (broken) I think was like 4700…, -12700.


  14. gpsguru says:

    I would like to write some data to my GPS device via the GPSID and also watch for some specific NMEA commands that are not normal GPS related data.

    Can anyone point me to some examples of using the ReadFile and WriteFile in a C# application so I can read raw NMEA and also write commands to the hardware?


  15. cenet says:

    GPSGuru – first I should warn you that if you want to Write to a GPS device, your application needs to be trusted (at least on smart-phone, this isn’t the case on PocketPC SKU’s).  GPSID sits on top of the GPS driver and because I can have multiple applications running at the same time I’m afraid that one of them may send some funky NMEA command that will mess up the state for the other apps on the device.

    As far as the sample code, I would probably point you to a CE Newsgroup (, but the dot-net compact framework group is probably better).  Because we have to moderate the comments on this blog (%90 would be really gross spam otherwise), that introduces a turnaround delay that makes having good conversations in the blog comments very difficult.

    John Spaith

  16. CAM says:

    Regarding your cowboy decision to deliver altered data, to suite your own personal preferences…

    Do you not understand Standards?

    Do you not understand Boundaries?

  17. cenet says:

    There’s a very big difference between altering data and changing its format.  The data as returned from NMEA streams directly is not in a format that any application developer wants to use.  Rather than make everyone of them do this math formula themselves, I perform do this re-formatting at my layer.  You can deterministically get back to the raw NMEA stream data from my lat/long data if you wanted to.  Though this bug has not won me any friends, everyone else who has given me feedback has indicated they wanted the data in the format I’m currently returning it in.

    The point of this post and descriptions of problems folks were seeing was not because of the reformat, but because of miscommunication on my part with some of the internal MS teams doing very early development work on GPSID where I wasn’t doing the reformatting.


  18. Nick Miles says:

    The fix code for A701 and Emulators in C doesn’t work as it removes any minus values!  You need to comment out the line:

    dbl = fabs(dbl);

    Shocking bug really, and then he gets the fix wrong!

  19. cenet says:

    You’re correct Nick, I have removed the offending line from the code.  Thank you.


  20. wz2b says:

    I’m noting some undesirable GPSID behavior with the CellLink BTG7000 bluetooth receiver.  This behavior is in both the emulator and actual PDA (Axim x51v, WM5).

    The problem is most likely due to the peculiarities of this receiver; nonetheless, it’s my feeling that the API ought to handle whatever the hardware throws at it in a robust manner.  However, I am not at the point yet where I can certainly say that it is or is not..

    Here is a clip of what is coming out of the receiver causing the failure scenario:





    Note that the position is marked as invalid ("V" in the RMC).  Also note that lat and lng are reported as zero.  The date is reported as August 22, "99".  This really means 1999, but GPSID assumes it’s 2099.  (Can’t really fault GPSID for that though).

    Here is the bad news: despite the fact that the RMC message is marked "V", dwValidFlags is returned as 0x1FDF.  This means that GPSID thinks that the position and time are both valid.  Most GPS receivers I have encountered would not send a $GPRMC with any lattitude or longitude if the position was invalid.  Most of them would send something like:


    I suspect that the problem is that GPSID is ignoring the "V" and instead determining the validity of the fix based on its ability to parse the fields.  Can anybody with access to source confirm this?

    The result is that you wind up with a gps position struct that shows a valid lat of 0.000, and a valid lng of 0.0000, and a date somewhere in 2099.  dwValidFlags is ix1FDF (in this case).  This freaks out the C# wrapper with a divide-by-zero exception in ParseDegreesMinutesSeconds().

    There are many psosible workaround scenarios.  In my case, I have modified the GpsPosition class to report everything as invalid if Time.Year >= 2099.  This isn’t a great solution, though, because some other receiver may send a different date.  Really what has to happen is that the "V" flag needs to be properly interpreted by GPSID.

    One other note: in my case, I am using this in purely a polled mode.  I am not setting up a message loop to receive asynchronous position updates, because I have a separate timer that processes the data anyway.

    It’s possible I’m misinterpreting something that’s going on here.  If anybody is interested in experimenting with this I would be happy to share the code fragment that causes the problem.  It would be fairly easy to set the GPSID up to loopback mode (driven by a file) and replicate what I am seeing.  I’m willing to work with somebody if you’d like to do this; just email me.


  21. cenet says:

    Chris – first I don’t feel so bad ignoring this comment so far since we have talked offline.  Here’s the response:

    Yes, unforunately your hypothesis here is absolutely correct.  The fact GPSID was ignoring the V flag is a known bug in the WM5 and even the initial releases of WM6.  I’ve fixed this already but it will only be in WM6 AKU 0.4 (AKU is WM name for a service pack though they’re not as massive or infrequent as Vista SP’s).  After the fix we won’t mark the lat/long as valid if we see the warning field flipped no matter whether there’s data in the lat/long or no.

    I’m afraid for the time being you’re going to have to hack around with with some check against val’s == 0.

    My apologies you had to run into this and please don’t hesitate to bring other GPSID or WM issues in general to my attention.

  22. Mike says:

    I have a problem with GPSID and COM4 on WM5 phone with built in GPS.

    I have been using the C# example to receive data from the GPSID for a year or so now.

    When my progam is running, all is fine. Then a user starts up TomTom (or another variant) which accesses Com4 (the virtual port). All is fine.

    However – when a user then stops TomTom, my C# program using the GPSID stops receiving data from the GPS. The GPS is built into the phone hardware (HTC3300 and Mio A701 exibit this behaviour).

    Starting TomTom again makes the GPS feed to my C# program from the GPSID driver resume.

    Why does COM4 operations seem to make the GPSID feed to a C# routine falter?

  23. gpsguru says:

    Hi – I have been using the WM5 sample kit with C# for a year or so now.

    The GPSID works fine for me on a HTC p3300 and Mio A701 via the GPSID driver (with a fix to sort out the Degrees thing).

    If I start my app, then start tomtom, tomtom works fine on com4: and my GPSID c# program continues to work.

    However, if I then stop tomtom on com4: (the virtual port), my C# program stops receiving GPS data. Closing the virtual port seems to halt the GPSID driver on "proper" GPSID C# programs.

    If I start tomtom again, my C# program also starts receiving data.

    Is this a "feature" of the virtual port – the GPSID seems to think that even though the C# GPSID program started first and is still running, when the last user of the virtual port closes, the GPSID driver shutsdown.

    I now have some bemused users on my tail. Can anyone shed some light on this behaviour?


  24. cenet says:

    First my apologies for long delay here.  For followups, one of newsgroups on is probably best way to go.

    For this issue, I’m wondering is it just the TomTom GPS device or if it’s the ohers as well you see this?  It’s definitely not a design feature of GPSID to close up the underlying driver in this case — we keep a global GPSApplication ref count and virtual port and the GPSAPI both add that, and add/deref independantly of each other.  So… I’m wondering maybe if the app is sending some sort of weird string to the underlying GPS driver that it’s not liking?  

    When an app using virtual comm port closes & there’s another app using API, we don’t even signal to underlying GPS driver anything (the ref count is purely internal) so I’m really not clear what could be up here.


  25. piknew says:

    Has someone encountered the problem as described below:

    I am using GPS IntermediateDrive to parse raw gps nmea data.

    1. CreateFile (with multiplexed gps port)
    2. sequential ReadFile

    3. CloseHandle

    The problem appears when

    1. Execute my application – OK
  26. Execute "third party" application – OK (both apps are reading gps data without any problems)

  27. Close "third party" application – NOT OK, it seems that this operation powers down gps hardware (why? according to MSDN there should be reference counting performed, but it seems it is not), my application has still handle to port opened, but is not able to read anything – ReadFile blocks infinitely…

  28. Solution is to execute  "third party" application once again, my application gets the data from port again (because now gps hardware is turned on)…

    So, could someone explain why such a situation happens? And how to prevent it… Or even a workaround – unfortunetely SetCommTimeouts has no effect in this particular case.

    FS-PocketLoox n560 with built-in gps hardware.

    thanks and regards, Marcin

  • gpsguru says:

    Thanks John.

    It is not specifically a TomTom issue as many GPS apps do it. Anyhow, I simply repopen the GPSID port when I detect lack of activity on it for 30 seconds and that does the trick.

    I have another problem however with Windows Mobile 6:

    I tried to run my software (C#, .NETCF2, WM5 SDK GPS Sample derivative) and it gets no GPS Data, The issue is this line:

    int result = GPSGetPosition(gpsHandle, ptr, 500000, 0);

    In Gps.CS

    Result = 87

    I tried the WM6 SDK sample and that has the same issue and the same result code.

    I am using a HTC P3300 upgraded using their WM6 kit (this exact piece of hardware worked fine using WM5 and my kit).

    TomTom is currently working fine accessing com port 4 which I believe is (and remains) the virtual port.

    Any thoughts?

  • cenet says:

    The error 87 thing is something we’re investigating, as discussed in newsgroup microsoft.public.pocketpc.developer, "WM5 to WM6 GPSID Problem on HTC P3300".  We’re in the process now of getting hardware.  (As a heads up I’m on vacation starting tomorrow so you may not hear from me personally, but there’s a new engineer coming on GPSID anyway.)