首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Windows中以编程方式挂载驱动器?

如何在Windows中以编程方式挂载驱动器?
EN

Stack Overflow用户
提问于 2010-09-24 14:30:29
回答 2查看 8.7K关注 0票数 4

我们生产和销售一种设备,我们的用户有时会想要连接到他们的计算机大量与多个USB集线器。它是一种具有人机界面(HID)和海量存储(MSD)接口的USB复合设备。Windows自动挂载每个设备的文件系统,直到它在“Z:”处用完字母为止。

我可以遍历设备树,并使用PnP配置管理器设备安装函数组合获得HID和USBSTOR接口的设备实例标识符。使用USB存储设备路径,我还可以获得磁盘编号(即\\.\PhysicalDrive1)。

下一步是按需要挂载这些磁盘,方法是在与设备通信时循环出驱动器号,或者更好的是,将它们安装在C:驱动器上的临时目录中。我在尝试使用DefineDosDevice执行此任务时遇到了困难,并且无法在SetVolumeMountPoint上取得进展,因为设备在挂载之前没有体积规。这就产生了鸡和蛋的问题。

但愿我们的客户使用unix!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-09-24 21:17:44

Windows不挂载磁盘;它挂载卷。但是,USBSTOR类设备的卷未作为设备树中的子节点列出。因此,您必须枚举所有卷,并进行一串字符串操作和比较,以便将存储\卷节点与USBSTOR节点匹配。

所有卷GUID值都使用FindFirstVolume函数集进行枚举。前面的".\“和尾部的"\”字符可以删除,然后将结果字符串传递给QueryDosDevice。这提供了一个设备名称。

接下来,必须使用GUID_DEVINTERFACE_VOLUME与SetupDiGetClassDevs和朋友一起枚举所有卷。将每个卷的设备类型和数量与使用的USBSTOR设备进行比较。一旦匹配,您就可以从卷中获取设备名称,并将其与其他设备名称列表进行比较,以找到卷GUID。

最后,该卷GUID可以成功地与SetVolumeMountPoint一起使用。

感谢加布在对我的问题的评论中给予了非常有益的帮助。

代码段

从设备路径获取设备类型和编号:

代码语言:javascript
复制
STORAGE_DEVICE_NUMBER sdn;
HANDLE handle = CreateFile(devInterfaceDetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
DWORD len = 0;
DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof (sdn), &len, NULL);

通过迭代所有卷接口并比较上述片段中的磁盘号,查找相应USBSTOR实例的设备名称:

代码语言:javascript
复制
std::string deviceName;
HDEVINFO devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_DEVICE_INTERFACE_DATA devInterface = { 0 };
devInterface.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
for (int i = 0; SetupDiEnumDeviceInterfaces(devInfoSet, NULL, &GUID_DEVINTERFACE_VOLUME, i, &devInterface); ++i) {
    SP_DEVINFO_DATA devInfoData = { 0 };
    devInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
    DWORD len;
    SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, NULL, 0, &len, &devInfoData);
    std::vector<char> buf(len);
    SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA *) &buf[0];
    devInterfaceDetail->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
    if (SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterface, devInterfaceDetail, len, NULL, &devInfoData)) {
        if (DEVICE_NUMBER == this->getDeviceNumber(devInterfaceDetail->DevicePath)) {
            std::vector<BYTE> buf(MAX_PATH + 1);
            DWORD type, len;
            if (SetupDiGetDeviceRegistryProperty(devInfoSet, &devInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &type, &buf[0], buf.size(), &len)) {
                deviceName.assign(buf.begin(), buf.begin() + len);
                break;
            }
        }
    }
}
票数 9
EN

Stack Overflow用户

发布于 2010-09-27 00:05:10

在我看来,您必须使用IOCTL_MOUNTMGR_CREATE_POINT。不幸的是,大多数使用的IOCTL_MOUNTMGR_XXX示例都是为内核模式驱动程序编写的,但它并不是必需的。也许我的旧答案 (使用IOCTL_MOUNTMGR_QUERY_POINTS)和另一个可以帮助您做到这一点。另见http://msdn.microsoft.com/en-us/library/ff567603.aspxhttp://support.microsoft.com/kb/836662

可以是,在更好地理解了如何使用IOCTL_MOUNTMGR_CREATE_POINT之后,您将能够解决SetVolumeMountPoint方面的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3788057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档