1

我有在 winCE 6.0 版本上运行的 ac# 应用程序。我需要在运行时卸载/重新加载 SD 卡驱动程序。我试图通过调用 FindFirstDevice,然后调用 DeactivateDevice/ActivateDeviceEX 来做到这一点。我的问题是 FindFirstDevice() 调用总是失败。我认为这是我将第二个参数编组到它的方式的问题。谁能告诉我我做错了什么?这是代码:

  [DllImport("coredll.dll", SetLastError = true)]
  public static extern int FindFirstDevice(DeviceSearchType
  searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

  public bool MountSDCardDrive(string mRegPath)
  {
     const int INVALID_HANDLE_VALUE = -1;

     int handle = INVALID_HANDLE_VALUE;
     DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName;

     DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION();
     di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION));

     string searchParamString = "*";
     IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);
     Marshal.StructureToPtr(searchParamString, searchParam, false);

     handle = FindFirstDevice(searchType, searchParam, ref di);
     if (handle == INVALID_HANDLE_VALUE)
     {
        // Failure - print error
        int hFindFirstDeviceError = Marshal.GetLastWin32Error();

        using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append)))
        {
           String iua = "DevDriverInterface: error from FindFirstDevice: " + hFindFirstDeviceError.ToString();
           bw.WriteLine(iua);
        }
        return false;
     }

... (rest of code)

如果我将行更改Marshal.StructureToPtr(searchParamString, searchParam, false);searchParam = Marshal.StringToBSTR(searchParamString);“我最终得到错误 1168 (ERROR_NOT_FOUND) 而不是 18(没有更多文件)。

searchParamString请注意,当我开始工作时,我的意图是使用“SDH1”。我目前正在使用searchParamString“*”来查看返回的内容并排除特定的字符串值。

感谢您提供的任何帮助 - Lynn

4

1 回答 1

1

FindFirstDevice 必须与 FindNextDevice 一起使用(它使用 FindFirstDevice 返回的句柄作为其第一个参数,如果找到另一个设备则返回 TRUE),因为您必须迭代所有设备以找到好的设备......并且为了这您必须比较结构中的 szLegacyName 值。

消除:

IntPtr searchParam = Marshal.AllocHGlobal(searchParamString.Length);

并且仅使用:

IntPtr searchParam = Marshal.StringToBSTR(searchParamString);

由于该方法已经提供分配必要的内存(请记住在 finally 块中使用 Marshal.FreeBSTR() 以释放该内存空间)。

您的结构应如下所示:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct DEVMGR_DEVICE_INFORMATION 
{ 
    public UInt32 dwSize; 
    public IntPtr hDevice; 
    public IntPtr hParentDevice; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] 
    public String szLegacyName; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szDeviceKey; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szDeviceName; 

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public String szBusName; 
} 
于 2013-01-18T15:12:28.430 回答