views:

75

answers:

2

Hi,

Our embedded systems programmer has developed the shell of a virtual serial port driver for our mobile hardware, and I have been filling in the methods to get it to work. The driver does work as expected, it simulates a COM port for a USB device that is spewing out NMEA strings (GPS data).

I type WM6 for short, but the OS is WM6.1 if it makes any difference.

The problem I am having is that the driver does not load at start up of the device on WM6 only. The driver was developed for both CE5 and WM6, but on CE5 the driver "does" load at boot, which is pointing me to a WM6 configuration issue. It maybe worth noting at this point that the driver will load in WM6 and CE5 using ActivateDevice() method, this is what I have been using so far for WM6, a small test app to launch the driver so I can at least test the driver is working on WM6.

The registry is already populated with the required keys for the startup of the driver. So the driver should load at startup without any issues. HKEY_LOCAL_MACHINE\Drivers\BuiltIn contains a sub key A36D_GPS_COM, and in that key is contained.

DeviceArrayIndex: 0

DeviceType: 0

Dll: A36D.dll

Flags: 0

Friendly Name: A36D GPS COM Port

Index: 8

Order: 3

Prefix: COM

Priority: 0

Priority: 256

From what I can tell there are generally 2 common answers to this issue which I have already investigated. These ideas were given to me by the embedded programmer but I researched how to do them myself.

1) The COM port is already in use when the driver tries to load, even if that COM port is eventually free once the device is loaded. I have changed the Index value in the registry from between 1 to 20 and rebooted the device, and the driver does not load onto a specified COM port. So to try and test this more thoroughly, I have moved another device to from COM9 to COM8 and moved my driver to COM9 (using the above registry settings). The other device driver loads at startup on COM8 quite happily but my device driver will not boot up on COM9. I have even tried tweaking the other settings but still it doesn't load the at boot.

2) Another possible issues and difference between CE5 and WM6 is security. So using the MSDN article http://msdn.microsoft.com/en-us/library/bb737570.aspx I have worked on signing and XML provisioning. Using a privileged key (not expired), The A36D.dll is signed in visual studio and the created installation CAB file is also signed with the same key. A _setup.xml file is created and appended to the cab file so that the signed key is added to the certificate store. The CAB file is signed again with the same key to ensure it is still valid. In addition the _setup.xml is packaged into its own .CPF file. Both the CAB and CPF files do add the key to the certificate stores "HKEY_LOCAL_MACHINE\Comm\Security\SystemCertificates" so know this is working. As a matter of caution I have installed it to the Privileged, Unprivileged, ROOT and SPC certificate stores. But the device driver still does not load into device.exe when the mobile device boots.

Other than a workaround of a start-up application that calls ActivateDevice() on the driver, I am stumped on how to get this driver to load at start-up.

I find it very odd it works in CE5 but not in WM6, I just don't know of anything else that could be causing issues.

Does anyone have any further suggestions that can be tried.

All help appreciated.

+1  A: 

I am more familiar with Windows CE, but here are a couple of things:

  • Did you add a debug print in the DllMain function to see whether it is called?
  • Did you check for a dependency break. Could it be that somehow you have a Dll available under CE 5 that is not there under WM6?
Shaihi
Hi Shaihi,I have looked at DllMain and there is no debug print, I have added one in and will test it on Tuesday morning when I have access to the WM6 device again. I know for a fact no other debug prints are written at startup, so maybe putting in an instant debug may shred light on the issue to if the dll is even loaded.As to a dependency break, i do not know how to do this on a mobile OS. But in thinking about it the driver can be activated manually with ActiviateDevice, so surely all the needed dependencies are already installed, aren't they?Thank you for the suggestions.
JonWillis
I missed the part that it loads under WM with ActivateDevice. This rules out dependency. Did you try to change the `order` filed in the registry? maybe the driver tries to load before some functionality it needs is ready.
Shaihi
Hi Shaihi, No problem, all help is appreciated.I did consider order and actually tried to make it load sooner rather than later incase of a COM port in use rather than dependency issue of other files not yet loaded, when I next get in ill set it to 255 and see if that helps.It maybe worth mentioning that someone has pointed out out the possible issue of signing. Whilst I have signed it with our cert, they have recommended to drop back down to the new (Jan 2010) SDK certificates and use cabsigner.exe instead of signtool.exe, and see if it loads. Could you see this been an possible issue? Thx
JonWillis
I did not regard the signage since I don't work with WM (that was the opening in my answer (: ). Can't you try and load it on a device that is "open"/"unlocked"/"does need signage"?
Shaihi
My apologies ;) The requirement for signing of DLLs are far as I know is built into the OS and is not something that can be disabled. Just spent the last 30 minutes looking and disabling certificates is for server/exchange/wifi only not for drivers. RapiConfig.exe is the tool to use for WM6 and I will investigate it but do not think it would help.As to the device, the driver is for a specific piece or hardware for this device so it cannot be tested on a different WM6 device unfortunately, but it was a good suggestion.
JonWillis
To update.The print dubug in DllMain is not displayed in WM6.1, but is in CE5. For those reading this in he future, I have tried it without and with signing of the DLLs and cab files yet it seemed to make no difference.
JonWillis
A: 

This is an answer, but not the 'right' one. It is merely a work around the loading issue. I figured this out over a week ago but did not want to use it as the solution. So this is hopefully just a temp fix.

The following code is used to load the driver manually, Its written in C# using C++ calls, I am used to C# which is why I did a C# project not a C++ one. Those who use C++ will undoubtedly create this in a C++ app.

public class LoadDriver
{
    [DllImport("coredll.dll", SetLastError = true)]
    public extern static IntPtr ActivateDevice(string lpszDevKey, int dwClientInfo);
    [DllImport("coredll.dll", SetLastError = true)]
    public static extern void SignalStarted( uint dw);

    public static void Main(string[] args)
    {
        Cursor.Current = Cursors.Default;
        IntPtr handle = ActivateDevice("Drivers\\BuiltIn\\A36D_GPS_COM", 0);
        if(handle != IntPtr.Zero)
        {
            Console.Write("Success");
        }

        if (args.Length > 0)
        {
            try
            {
                SignalStarted(uint.Parse(args[0]));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

Now in order for this to work it needs to be run at startup, so i added in the required registry keys.

"HKEY_LOCAL_MACHINE/init"
Launch62 = A36D_loaddriver.exe
Depend62 = "32 00"

"32 00" is to ensure it loads after the shell32.exe

Now the the startup of the device, the driver is activated in device.exe.

As to the signing/registry issue, this is still being looked into.

JonWillis