读书人

[求解]利用IOCTL_DISK_SET_DRIVE_LAYO

发布时间: 2013-01-01 14:04:19 作者: rapoo

[求解]利用IOCTL_DISK_SET_DRIVE_LAYOUT_EX给磁盘分区
先上一段代码, 该代码根据网上找到的修改了一下,注释(英文的)基本没删。
"\\\\.\\PhysicalDrive1" 是我的U盘的符号连接。。


DWORD func()
{
HANDLE hDrive = INVALID_HANDLE_VALUE;
BOOL Result; // used to read bad DeviceIoControl calls
DWORD dwRetCode = 0;
DWORD szReturned;
DWORD szNewLayout;
unsigned int SectorSize = 512;
LARGE_INTEGER DiskSize;
LARGE_INTEGER Part_1_size;
LARGE_INTEGER Part_2_size;

DRIVE_LAYOUT_INFORMATION_EX *dl = NULL;
CREATE_DISK disk;

DiskSize.QuadPart = 32768000; //我的U盘的总容量,字节数
Part_1_size.QuadPart = 32768000 / 2;
Part_2_size.QuadPart = 32768000 / 2;

int PartitionCount = 4;

// Very important! Size correctly this structure. Even if there's only
// one primary partition, you MUST size the buffer to contain
// AT LEAST 4 PARTITION_INFORMATION_EX!
szNewLayout = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
(PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX);

dl = (DRIVE_LAYOUT_INFORMATION_EX*) new BYTE[szNewLayout];

// Open handle to physical device
// NtCreateFile() function can be used too with "\\device\\harddisk1\\partiton0" path.
hDrive = CreateFile(
_T("\\\\.\\PhysicalDrive1"),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, //default security attributes
OPEN_EXISTING, // disposition
0,// file attributes
NULL);

if(!hDrive){
// handle the error
dwRetCode = GetLastError();
goto SetDriveLayout_Cleanup;
}

ZeroMemory(&disk,sizeof(CREATE_DISK));
disk.PartitionStyle = PARTITION_STYLE_MBR;
disk.Mbr.Signature = 0xA4B57300;// the signature can be randomly generated

// Create primary partition MBR
Result = DeviceIoControl(hDrive,IOCTL_DISK_CREATE_DISK,
&disk,sizeof(CREATE_DISK), NULL,0, &szReturned,NULL);

if(!Result){
dwRetCode = GetLastError();
goto SetDriveLayout_Cleanup;
}
Result = DeviceIoControl(hDrive,IOCTL_DISK_UPDATE_PROPERTIES,
NULL,0,NULL,0,&szReturned,NULL);

// set RewritePartition=true in every partition to force rewrite.
for (int item = 0; item < PartitionCount; item++){
dl->PartitionEntry[item].RewritePartition = 1;
dl->PartitionEntry[item].PartitionNumber = 0;
}

//Setup drive layout
ZeroMemory(dl, szNewLayout);

dl->PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
dl->PartitionEntry[0].StartingOffset.QuadPart = 32256; // 63扇区
dl->PartitionEntry[0].PartitionLength = Part_1_size;


dl->PartitionEntry[0].PartitionNumber = 1;
dl->PartitionEntry[0].RewritePartition = TRUE;
dl->PartitionEntry[0].Mbr.PartitionType = 0x07;// PARTITION_IFS (NTFS partition or logical drive)
dl->PartitionEntry[0].Mbr.BootIndicator = TRUE;
dl->PartitionEntry[0].Mbr.RecognizedPartition = 1;
dl->PartitionEntry[0].Mbr.HiddenSectors = 32256/SectorSize;
goto OPERATION_Continue;

dl->PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
dl->PartitionEntry[1].StartingOffset.QuadPart = Part_1_size.QuadPart + 32256i64;
dl->PartitionEntry[1].PartitionLength = Part_2_size;
dl->PartitionEntry[1].PartitionNumber = 0;
dl->PartitionEntry[1].RewritePartition = TRUE;
dl->PartitionEntry[1].Mbr.PartitionType = PARTITION_EXTENDED; //0x05
dl->PartitionEntry[1].Mbr.BootIndicator = FALSE;
dl->PartitionEntry[1].Mbr.RecognizedPartition = 1;
dl->PartitionEntry[1].Mbr.HiddenSectors = (32256i64 + Part_1_size.QuadPart)/SectorSize;


OPERATION_Continue:
// setup drive layout
dl->PartitionStyle = PARTITION_STYLE_MBR;
dl->PartitionCount = PartitionCount;// specify AT LEAST 4 partitions!!!
dl->Mbr.Signature = 0xA4B57300;

// Set layout
Result = DeviceIoControl(hDrive,
IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
&dl, szNewLayout,
NULL, 0,
&szReturned, NULL);

if(!Result) {
dwRetCode = GetLastError();
goto SetDriveLayout_Cleanup;
}

// update disk properties
Result = DeviceIoControl(hDrive,
IOCTL_DISK_UPDATE_PROPERTIES,
NULL,0, NULL,0, &szReturned, NULL);

SetDriveLayout_Cleanup:
if (hDrive != INVALID_HANDLE_VALUE )
CloseHandle(hDrive);
if (dl != NULL)
delete [] dl;

return dwRetCode;
}



在后面调用 IOCTL_DISK_SET_DRIVE_LAYOUT_EX 的时候,失败,GetLastError信息为:
0x00000018 程序发出命令,但命令长度不正确。

修改了各种相关数值,貌似都这一个结果,怎么办?
[解决办法]
友情帮顶。

读书人网 >VC/MFC

热点推荐