【问题标题】:Safely remove a USB drive using the Win32 API?使用 Win32 API 安全删除 USB 驱动器?
【发布时间】:2010-09-10 06:46:58
【问题描述】:

如何使用 Win32 API 移除 USB 驱动器?我在嵌入式系统上做了很多工作,其中一个我必须将我的程序复制到 U 盘上并将其插入目标硬件。

由于我主要在控制台上工作,我不喜欢每天使用鼠标点击小任务栏图标一百次。

我很想写一个小程序来做这件事,这样我就可以把它放到我的 makefile 中,但是我还没有找到任何做同样事情的 API 调用。

有什么想法吗?

【问题讨论】:

标签: c windows winapi usb


【解决方案1】:

您可以使用 CM_Request_Device_Eject() 函数以及其他一些可能性。 请参阅以下项目和文章:

DevEject:直截了当。 http://www.withopf.com/tools/deveject/

一篇有用的 CodeProject 文章: http://www.codeproject.com/KB/system/RemoveDriveByLetter.aspx

【讨论】:

  • 完美.. 你甚至链接到一个实用程序来完成这项工作。非常感谢。
【解决方案2】:

看起来Sync 允许您指定 -e 来弹出可移动驱动器。虽然不是 win32 API,但您可能只需要从您的 makefile 中调用 sync -e [drive_letter]

【讨论】:

  • 但是如何知道USB驱动器添加了哪个驱动器号?我还想删除基于卷的 USB 驱动器,例如不允许 USB 卷超过 5GG 等。
【解决方案3】:

这是一个关于可移动存储媒体的technet article。寻找DismountNtmsMedia

【讨论】:

    【解决方案4】:

    这是 Delphi 中的一个解决方案,我已对其进行了修改并投入到一项服务中,以供在一个非常大的企业中使用。转至:link text

    查找“scapi (Setup & Config Manager API)”并下载它。将有一个名为 USBView 的演示程序可以帮助您上路。如果您有 Delphi,这还包括一个 TUSBDeviceTree 组件,您可以使用它来收集有关 USB 设备的信息。

    问候

    【讨论】:

      【解决方案5】:
      #include<SetupAPI.h>
      #include <windows.h>  
      #include<initguid.h>
      #include <newdev.h>
      #include <Cfgmgr32.h>
      
      #pragma comment(lib, "Cfgmgr32.lib")
      #pragma comment(lib, "Setupapi.lib")
      #pragma comment(lib, "Newdev.lib")
      
      int RemoveDevice(const GUID *guid, const wchar_t *hwID) {
          HDEVINFO m_hDevInfo;
          SP_DEVICE_INTERFACE_DATA         spdid;
          SP_DEVINFO_DATA                  spdd;
          DWORD                            dwSize;
          BYTE Buf[1024];
          PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd =
              (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf;
      
          printf("try to remove device::%ws\n", hwID);
      
          m_hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT| DIGCF_DEVICEINTERFACE);
          if (m_hDevInfo == INVALID_HANDLE_VALUE)
          {
              printf("GetClassDevs Failed!\n");
              return 0;
          }
          spdid.cbSize = sizeof(spdid);
          for (int i = 0; SetupDiEnumDeviceInterfaces(m_hDevInfo, NULL, guid, i, &spdid); i++) {
              dwSize = 0;
              SetupDiGetDeviceInterfaceDetail(m_hDevInfo,
                  &spdid, NULL, 0, &dwSize, NULL);
              if (dwSize != 0 && dwSize <= sizeof(Buf)) {
                  pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes!
      
                  ZeroMemory((PVOID)&spdd, sizeof(spdd));
                  spdd.cbSize = sizeof(spdd);
      
                  long res =
                      SetupDiGetDeviceInterfaceDetail(m_hDevInfo, &
                          spdid, pspdidd,
                          dwSize, &dwSize,
                          &spdd);
                  if (res) {
                      OLECHAR* guidString;
                      OLECHAR* guidString2;
                      StringFromCLSID(&spdd.ClassGuid, &guidString);
                      StringFromCLSID(&spdid.InterfaceClassGuid, &guidString2);
                      printf("%d, %ws, %ws, %ws\n", spdd.DevInst, pspdidd->DevicePath, guidString, guidString2);
                      CoTaskMemFree(guidString);
                      CoTaskMemFree(guidString2);
                      if (!memcmp(pspdidd->DevicePath, hwID, 2 * lstrlenW(hwID))) {
                          DEVINST DevInstParent = 0;
                          res = CM_Get_Parent(&DevInstParent, spdd.DevInst, 0);
                          for (long tries = 0; tries < 10; tries++) {
                              // sometimes we need some tries...
                              WCHAR VetoNameW[MAX_PATH];
                              PNP_VETO_TYPE VetoType = PNP_VetoTypeUnknown;
                              VetoNameW[0] = 0;
      
                              res = CM_Request_Device_EjectW(DevInstParent,
                                  &VetoType, VetoNameW, MAX_PATH, 0);
                              if ((res == CR_SUCCESS &&
                                  VetoType == PNP_VetoTypeUnknown)) {
                                  printf("remove %ws success!\n", pspdidd->DevicePath);
                                  SetupDiDestroyDeviceInfoList(m_hDevInfo);
                                  return 1;
                              }
                              Sleep(500); // required to give the next tries a chance!
                          }
                          break;
                      }
                  }
              }
          }
          printf("Remove Device Failed!\n");
          SetupDiDestroyDeviceInfoList(m_hDevInfo);
          return 0;
      }
      
      int main(){
          GUID GUID_DEVINTERFACE_USB_HUB;
          CLSIDFromString(L"F18A0E88-C30C-11D0-8815-00A0C906BED8", &GUID_DEVINTERFACE_USB_HUB);
      
          RemoveDevice(&GUID_DEVINTERFACE_USB_HUB, L"\\\\?\\usb#root_hub30");
          return 0;
      }
      

      参考:

      How to Prepare a USB Drive for Safe Removal

      GUID_DEVINTERFACE

      【讨论】:

        猜你喜欢
        • 2017-03-10
        • 1970-01-01
        • 2011-03-18
        • 1970-01-01
        • 2012-08-07
        • 1970-01-01
        • 1970-01-01
        • 2015-11-07
        • 1970-01-01
        相关资源
        最近更新 更多