2

我们正在尝试通过 C++ 程序使用 Windows 服务器 2008/2012 上某些现有磁盘的属性来初始化磁盘。

我们正在使用磁盘管理控制代码DeviceIoControl()中的方法和IOCTL_DISK_CREATE_DISK代码IOCTL_DISK_SET_DRIVE_LAYOUT_EX, IOCTL_DISK_SET_PARTITION_INFO_EX来使磁盘可用。

通过搜索得到以下代码片段

//To open the drive
hDevice = CreateFile( TEXT("\\\\.\\PhysicalDrive7"), 
                      GENERIC_READ | GENERIC_WRITE,       // no access to the drive 
                      FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode 
                      NULL,                               // default security attributes 
                      OPEN_EXISTING,                      // disposition 
                      0,                                  // file attributes 
                      NULL);                              // do not copy file attributes 


CREATE_DISK dsk; 
dsk.PartitionStyle = PARTITION_STYLE_MBR; //It can also be PARTITION_STYLE_GPT
dsk.Mbr.Signature = 1;

// Initialize disk
bResult = DeviceIoControl( hDevice,                 // device to be queried 
                           IOCTL_DISK_CREATE_DISK,  // operation to perform 
                           &dsk, sizeof(dsk),         
                           NULL, 0,                // no output buffer 
                           &junk,                  // # bytes returned 
                           NULL
                         ); 

LARGE_INTEGER lgPartitionSize;
lgPartitionSize.QuadPart = (1024 * 1024 * 1024);
DWORD dwDriverLayoutInfoExLen = sizeof (DRIVE_LAYOUT_INFORMATION_EX) + 3 * sizeof(PARTITION_INFORMATION_EX);
DRIVE_LAYOUT_INFORMATION_EX *pdg = (DRIVE_LAYOUT_INFORMATION_EX *)new BYTE[dwDriverLayoutInfoExLen];

SecureZeroMemory(pdg, dwDriverLayoutInfoExLen);

pdg->PartitionStyle = PARTITION_STYLE_MBR; 
pdg->PartitionCount = 1;
pdg->Mbr.Signature = 1;

pdg->PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;   
pdg->PartitionEntry[0].StartingOffset.QuadPart = 1048576;  
pdg->PartitionEntry[0].PartitionLength.QuadPart = lgPartitionSize.QuadPart * 200;   
pdg->PartitionEntry[0].PartitionNumber = 1;   
pdg->PartitionEntry[0].RewritePartition = TRUE;

pdg->PartitionEntry[0].Mbr.PartitionType = PARTITION_NTFT; // PARTITION_IFS (NTFS partition or logical drive)   
pdg->PartitionEntry[0].Mbr.BootIndicator = TRUE;
pdg->PartitionEntry[0].Mbr.RecognizedPartition = 1;   
pdg->PartitionEntry[0].Mbr.HiddenSectors = 32256 / 512;   

// Partition a disk
bResult = DeviceIoControl( hDevice,        // device to be queried 
                           IOCTL_DISK_SET_DRIVE_LAYOUT_EX,  // operation to perform 
                           pdg, sizeof DRIVE_LAYOUT_INFORMATION_EX, //output buffer
                           NULL, 0,                // no output buffer 
                           &junk,                    // # bytes returned 
                           NULL
                         ); 

bResult = DeviceIoControl(  hDevice, 
                            IOCTL_DISK_UPDATE_PROPERTIES, 
                            NULL, 0, NULL, 0, &junk, NULL);

PARTITION_INFORMATION_EX dskinfo; 
PARTITION_INFORMATION_MBR mbrinfo; 
mbrinfo.PartitionType = PARTITION_NTFT; 
mbrinfo.HiddenSectors = (32256 / 512);
mbrinfo.BootIndicator = 1;
mbrinfo.RecognizedPartition = 1;

dskinfo.PartitionStyle = PARTITION_STYLE_MBR; 
dskinfo.StartingOffset.QuadPart = 1048576;//0; 
dskinfo.PartitionLength.QuadPart = lgPartitionSize.QuadPart * 200; 
dskinfo.PartitionNumber = 1; 
dskinfo.RewritePartition = TRUE; 
dskinfo.Mbr = mbrinfo;


bResult = DeviceIoControl( hDevice,        // device to be queried 
                           IOCTL_DISK_SET_PARTITION_INFO_EX,  // operation to perform 
                           &dskinfo, sizeof(dskinfo),        // output buffer 
                           NULL, 0,                // no output buffer 
                           &junk,                    // # bytes returned   
                           NULL
                         ); 

除了最后一个带有错误 1 ​​的代码(即不正确的函数)之外,所有的调用DeviceIoControl()都成功了。IOCTL_DISK_SET_PARTITION_INFO_EX这可能是什么原因?

如果我们注释掉最后一个调用,磁盘被初始化为原始磁盘,但这不符合我们的要求。

以上示例仅适用于 MBR 分区样式。我们找不到 GPT 的任何样本,...样式。如果有人知道,请给一个链接。

4

1 回答 1

1

您使用了错误的结构类型与IOCTL_DISK_SET_PARTITION_INFO_EX. 它需要一个SET_PARTITION_INFORMATION_EX结构,而不是一个PARTITION_INFORMATION_EX结构。

您可能不需要使用IOCTL_DISK_SET_PARTITION_INFO_EX,因为它只是设置分区类型,应该已经设置了IOCTL_DISK_SET_DRIVE_LAYOUT_EX. 不幸的是,您使用它设置了错误的分区类型。NTFS 分区具有分区类型PARTITION_IFS

乘以几乎肯定是错误的lgPartitionSize200如果lgPartitionSize假设扇区大小,那么您需要将其乘以磁盘的扇区大小。硬盘的扇区大小过去一直是 512 字节(0x200bytes),但现代硬盘使用的是 4096 字节的扇区大小。

正确创建分区表并不容易,像你所做的那样盲目地复制其他人的代码是行不通的。即使您解决了我上面提到的问题,您仍然可能会遇到其他问题。您确实需要了解如何布置分区的所有限制。

您可能要考虑使用该diskpart命令以编程方式初始化磁盘而不是 C++ 代码。

于 2014-09-13T19:13:58.297 回答