1

我们的嵌入式系统程序员为我们的移动硬件开发了一个虚拟串行端口驱动程序的外壳,我一直在填写使其工作的方法。该驱动程序确实按预期工作,它模拟了一个用于喷出 NMEA 字符串(GPS 数据)的 USB 设备的 COM 端口。

我简称 WM6,但操作系统是 WM6.1,如果它有什么不同的话。

我遇到的问题是驱动程序仅在 WM6 上启动设备时不加载。该驱动程序是为 CE5 和 WM6 开发的,但在 CE5 上,驱动程序“确实”在启动时加载,这将我指向 WM6 配置问题。在这一点上可能值得注意的是,驱动程序将使用 ActivateDevice() 方法加载到 WM6 和 CE5 中,这是我迄今为止一直在使用的 WM6,一个用于启动驱动程序的小型测试应用程序,因此我至少可以测试驱动程序正在开发 WM6。

注册表中已经填充了启动驱动程序所需的密钥。所以驱动程序应该在启动时加载,没有任何问题。HKEY_LOCAL_MACHINE\Drivers\BuiltIn 包含一个子键 A36D_GPS_COM,并且包含在该键中。

设备数组索引:0

设备类型:0

DLL:A36D.dll

标志:0

友好名称:A36D GPS COM 端口

指数:8

订购:3

前缀:COM

优先级:0

优先级:256

据我所知,我已经调查过这个问题通常有两个常见的答案。这些想法是嵌入式程序员给我的,但我自己研究了如何去做。

1) 当驱动程序尝试加载时,COM 端口已经在使用中,即使在加载设备后该 COM 端口最终是空闲的。我已将注册表中的 Index 值从 1 更改为 20 并重新启动设备,驱动程序未加载到指定的 COM 端口。因此,为了更彻底地尝试和测试,我将另一个设备从 COM9 移到了 COM8,并将我的驱动程序移到了 COM9(使用上述注册表设置)。其他设备驱动程序在 COM8 上启动时非常愉快地加载,但我的设备驱动程序无法在 COM9 上启动。我什至尝试过调整其他设置,但它仍然没有在启动时加载。

2)CE5和WM6之间另一个可能的问题和区别是安全性。所以使用 MSDN 文章http://msdn.microsoft.com/en-us/library/bb737570.aspx我从事过签名和 XML 配置方面的工作。使用特权密钥(未过期),在 Visual Studio 中对 A36D.dll 进行签名,并且创建的安装 CAB 文件也使用相同的密钥进行签名。创建一个 _setup.xml 文件并将其附加到 cab 文件,以便将签名密钥添加到证书存储区。CAB 文件使用相同的密钥再次签名,以确保它仍然有效。此外,_setup.xml 被打包到它自己的 .CPF 文件中。CAB 和 CPF 文件都将密钥添加到证书存储“HKEY_LOCAL_MACHINE\Comm\Security\SystemCertificates”,所以知道这是有效的。为谨慎起见,我已将其安装到 Privileged、Unprivileged、ROOT 和 SPC 证书存储区。但是当移动设备启动时,设备驱动程序仍然没有加载到 device.exe 中。

除了在驱动程序上调用 ActivateDevice() 的启动应用程序的解决方法之外,我对如何让该驱动程序在启动时加载感到困惑。

我觉得它在 CE5 中有效但在 WM6 中无效,这很奇怪,我只是不知道其他任何可能导致问题的东西。

有没有人有任何进一步的建议可以尝试。

所有帮助表示赞赏。

4

2 回答 2

1

我更熟悉 Windows CE,但这里有几件事:

  • 是否在 DllMain 函数中添加了调试打印以查看它是否被调用?
  • 您是否检查了依赖关系中断。会不会是你有一个在 CE 5 下可用的 Dll,而在 WM6 下却没有?
于 2010-08-29T04:41:12.680 回答
0

这是一个答案,但不是“正确”的答案。这只是解决加载问题的方法。我在一个多星期前就知道了,但不想用它作为解决方案。所以这希望只是一个临时修复。

以下代码用于手动加载驱动程序,它使用 C++ 调用用 C# 编写,我习惯于 C#,这就是为什么我做了一个 C# 项目而不是 C++ 项目。那些使用 C++ 的人无疑会在 C++ 应用程序中创建它。

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);
            }
        }
    }
}

现在为了让它工作,它需要在启动时运行,所以我添加了所需的注册表项。

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

"32 00" 是为了确保它在 shell32.exe 之后加载

现在设备启动,驱动在device.exe中激活。

至于签名/注册问题,这仍在调查中。

于 2010-09-01T15:32:15.233 回答