C++ 如何在没有Windows分配驱动器号的情况下创建分区?

C++ 如何在没有Windows分配驱动器号的情况下创建分区?,c++,winapi,windows-7,C++,Winapi,Windows 7,我正在尝试通过Windows API初始化和分区连接的虚拟硬盘。我已经成功地使用了它,但是每当我应用所需的驱动器布局时,窗口就会自动为分区分配驱动器号,并弹出一个恼人的“是否格式化?”对话框 我的目的是稍后在程序中处理这个分区的格式化和挂载,但我不确定如何停止这种行为。我尝试将RecognizedPartition设置为FALSE,但似乎没有效果 相关代码: Layout.PartitionStyle = PARTITION_STYLE_MBR; Layout.PartitionCount =

我正在尝试通过Windows API初始化和分区连接的虚拟硬盘。我已经成功地使用了它,但是每当我应用所需的驱动器布局时,窗口就会自动为分区分配驱动器号,并弹出一个恼人的“是否格式化?”对话框

我的目的是稍后在程序中处理这个分区的格式化和挂载,但我不确定如何停止这种行为。我尝试将
RecognizedPartition
设置为FALSE,但似乎没有效果

相关代码:

Layout.PartitionStyle = PARTITION_STYLE_MBR;
Layout.PartitionCount = 4;
Layout.Mbr.Signature = MY_DISK_MBR_SIGNATURE;
Layout.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
Layout.PartitionEntry[0].PartitionNumber = 1;
Layout.PartitionEntry[0].StartingOffset.QuadPart = MY_DISK_OFFSET;
Layout.PartitionEntry[0].PartitionLength.QuadPart =
   (Geom.DiskSize.QuadPart - MY_DISK_OFFSET);
Layout.PartitionEntry[0].Mbr.PartitionType = PARTITION_IFS;
Layout.PartitionEntry[0].Mbr.BootIndicator = FALSE;
Layout.PartitionEntry[0].Mbr.RecognizedPartition = FALSE;
Layout.PartitionEntry[0].Mbr.HiddenSectors =
   (MY_DISK_OFFSET / Geom.Geometry.BytesPerSector);

for (int i = 0; i < 4; i++)
{
    Layout.PartitionEntry[i].RewritePartition = TRUE;
}

if (!DeviceIoControl(hDisk, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
                     Layout, dwLayoutSz, NULL, 0, &dwReturn, NULL))
{
    // Handle error
}
DeviceIoControl(hDisk, IOCTL_DISK_UPDATE_PROPERTIES,
                NULL, 0, NULL, 0, &dwReturn, NULL);
Layout.PartitionStyle=PARTITION\u STYLE\u MBR;
Layout.PartitionCount=4;
Layout.Mbr.Signature=我的磁盘\u Mbr\u签名;
Layout.PartitionEntry[0]。PartitionStyle=PARTITION\u STYLE\u MBR;
Layout.PartitionEntry[0]。PartitionNumber=1;
Layout.PartitionEntry[0]。StartingOffset.QuadPart=MY\u DISK\u OFFSET;
Layout.PartitionEntry[0]。PartitionLength.QuadPart=
(Geom.DiskSize.QuadPart-我的磁盘偏移量);
Layout.PartitionEntry[0].Mbr.PartitionType=PARTITION\u if;
Layout.PartitionEntry[0]。Mbr.BootIndicator=FALSE;
Layout.PartitionEntry[0]。Mbr.RecognizedPartition=FALSE;
Layout.PartitionEntry[0].Mbr.HiddenSectors=
(MY_DISK_OFFSET/Geom.Geometry.BytesPerSector);
对于(int i=0;i<4;i++)
{
Layout.PartitionEntry[i].RewritePartition=TRUE;
}
如果(!DeviceIoControl(hDisk、IOCTL、磁盘、设置、驱动器、布局、,
布局,dwLayoutSz,NULL,0,&dwReturn,NULL)
{
//处理错误
}
设备控制(hDisk、IOCTL\u磁盘\u更新\u属性、,
NULL,0,NULL,0,&dwReturn,NULL);

如何防止自动分配驱动器盘符?

我已经有一段时间没有使用此API了,但从内存来看,您不能。但这并不能阻止你追查真相


我不确定它是否会停止格式化提示tho,在我进行磁盘布局更新之前,分区已经正确格式化。解决此问题的唯一可靠方法是在创建和格式化卷时停止“外壳硬件检测”服务。然而,这种方法非常愚蠢,我拒绝将其写入代码

另一个“黑客”选项是启动服务,然后通过
CreateProcess()
CREATE\u NO\u window
标志在隐藏窗口中立即生成自身(或“worker”可执行文件)

由于这个软件作为一个系统服务运行,我不想让代码复杂化,因为在系统的生命周期中只会发生一次或两次,所以我不得不接受这样一个事实:在创建分区时,有时会偶尔弹出一个交互式服务检测窗口


如果有人在以编程方式创建和格式化驱动器时发现了防止格式化提示的好方法,我很乐意更改已接受的答案(并欠你一杯啤酒)。

我刚刚解决了这个问题,等待几秒钟驱动器可用,然后直接发出格式化操作。查看我的答案。

有一个有趣的解决方法:它安装一个窗口事件挂钩,检测“是否要格式化此驱动器?”提示并立即关闭它们


然后,它继续安排只装载它关心的分区,但这是正交的。

我没有尝试过,特别是因为没有磁盘可供尝试。但是,如果尝试以独占方式打开设备(
hDisk
),然后执行您的操作,会怎么样?毕竟,独占访问应该确保挂载管理器不会干涉您的事务,不是吗?(这将是
dwShareMode==0
)+1当然是这个问题。检查它-不幸的是不起作用