In the previous section, we introduced some basic concepts and main APIs. At the beginning of this section, we will list and analyze some instances. I have tested all the code in this article in vs2008. You only need to replace a few macro definitions to compile and execute the code.
In the face of a new disk, the first thing we need to do is to initialize it. It is easy to manage windows disks in the system, but it is slightly complicated to implement in the program. The sample code in this section initializes a new hard disk and creates a partition on it.
The Code is as follows:
/*************************************** ***************************************
* Function: initialize the disk and create partitions
* Input: disk, disk name
* ParNum, partition number
* Output: N/
* Return: Succeed, 0
* Fail,-1
**************************************** **************************************/
DWORD CreateDisk (DWORD disk, WORD partNum)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL result; // results flag
DWORD readed; // discard results
DWORD ret;
WORD I;
CHAR diskPath [DISK_PATH_LEN];
DISK_GEOMETRY pdg;
DWORD sectorSize;
DWORD signature;
LARGE_INTEGER diskSize;
LARGE_INTEGER partSize;
BYTE actualPartNum;
DWORD layoutStructSize;
DRIVE_LAYOUT_INFORMATION_EX * dl;
CREATE_DISK newDisk;
Sprintf (diskPath, "\\\\\ PhysicalDrive % d", disk );
ActualPartNum = 4;
If (partNum> actualPartNum)
{
Return (WORD)-1;
}
HDevice = CreateFile (
DiskPath,
GENERIC_READ | GENERIC_WRITE,
File_pai_read | file_pai_write,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL
);
If (hDevice = INVALID_HANDLE_VALUE) // cannot open the drive
{
Fprintf (stderr, "CreateFile () Error: % ld \ n", GetLastError ());
Return DWORD (-1 );
}
// Create primary partition MBR
NewDisk. PartitionStyle = PARTITION_STYLE_MBR;
Signature = (DWORD) time (NULL); // get signature from current time
NewDisk. Mbr. Signature = signature;
Result = DeviceIoControl (
HDevice,
IOCTL_DISK_CREATE_DISK,
& NewDisk,
Sizeof (CREATE_DISK ),
NULL,
0,
& Readed,
NULL
);
If (! Result)
{
Fprintf (stderr, "IOCTL_DISK_CREATE_DISK Error: % ld \ n", GetLastError ());
(Void) CloseHandle (hDevice );
Return DWORD (-1 );
}
// Fresh the partition table
Result = DeviceIoControl (
HDevice,
IOCTL_DISK_UPDATE_PROPERTIES,
NULL,
0,
NULL,
0,
& Readed,
NULL
);
If (! Result)
{
Fprintf (stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: % ld \ n", GetLastError ());
(Void) CloseHandle (hDevice );
Return DWORD (-1 );
}
// Now create the partitions
Ret = GetDriveGeometry (diskPath, & pdg );
If (DWORD)-1 = ret)
{
Return ret;
}
SectorSize = pdg. BytesPerSector;
DiskSize. QuadPart = pdg. Cylinders. QuadPart * pdg. TracksPerCylinder *
Pdg. SectorsPerTrack * pdg. BytesPerSector; // calculate the disk size;
PartSize. QuadPart = diskSize. QuadPart/partNum;
LayoutStructSize = sizeof (DRIVE_LAYOUT_INFORMATION_EX) + (actualPartNum-1) * sizeof (PARTITION_INFORMATION_EX );
Dl = (DRIVE_LAYOUT_INFORMATION_EX *) malloc (layoutStructSize );
If (NULL = dl)
{
(Void) CloseHandle (hDevice );
Return (WORD)-1;
}
Dl-> PartitionStyle = (DWORD) PARTITION_STYLE_MBR;
Dl-> PartitionCount = actualPartNum;
Dl-> Mbr. Signature = signature;
// Clear the unused partitions
For (I = 0; I <actualPartNum; I ++ ){
Dl-> PartitionEntry [I]. RewritePartition = 1;
Dl-> PartitionEntry [I]. Mbr. PartitionType = PARTITION_ENTRY_UNUSED;
}
// Set the profile of the partitions
For (I = 0; I <partNum; I ++ ){
Dl-> PartitionEntry [I]. PartitionStyle = PARTITION_STYLE_MBR;
Dl-> PartitionEntry [I]. StartingOffset. QuadPart =
(PartSize. QuadPart * I) + (LONGLONG) (pdg. SectorsPerTrack) * (LONGLONG) (pdg. BytesPerSector); // 32256
Dl-> PartitionEntry [I]. PartitionLength. QuadPart = partSize. QuadPart;
Dl-> PartitionEntry [I]. PartitionNumber = I + 1;
Dl-> PartitionEntry [I]. RewritePartition = TRUE;
Dl-> PartitionEntry [I]. Mbr. PartitionType = PARTITION_IFS;
Dl-> PartitionEntry [I]. Mbr. BootIndicator = FALSE;
Dl-> PartitionEntry [I]. Mbr. RecognizedPartition = TRUE;
Dl-> PartitionEntry [I]. Mbr. HiddenSectors =
Pdg. SectorsPerTrack + (DWORD) (partSize. QuadPart/sectorSize) * I );
}
// Execute the layout
Result = DeviceIoControl (
HDevice,
IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
Dl,
LayoutStructSize,
NULL,
0,
& Readed,
NULL
);
If (! Result)
{
Fprintf (stderr, "IOCTL_DISK_SET_DRIVE_LAYOUT_EX Error: % ld \ n", GetLastError ());
Free (dl );
(Void) CloseHandle (hDevice );
Return DWORD (-1 );
}
// Fresh the partition table
Result = DeviceIoControl (
HDevice,
IOCTL_DISK_UPDATE_PROPERTIES,
NULL,
0,
NULL,
0,
& Readed,
NULL
);
If (! Result)
{
Fprintf (stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: % ld \ n", GetLastError ());
Free (dl );
(Void) CloseHandle (hDevice );
Return DWORD (-1 );
}
Free (dl );
(Void) CloseHandle (hDevice );
Sleep (3000); // wait the operations take effect
Return 0;
}
The CreateDisk function contains two parameters,
DWORD disk: Enter the physical drive letter. For more information, see section 1.
WORD partNum indicates the number of partitions to be created, partNum <= 4.
The function execution process is explained as follows:
*****************/
1. Create a device name based on disk, \. \ PhysicalDriveX. to escape the device name, "\" is written "\\".
2. Call CreateFile to open the device file and obtain the handle.
3. Call the DeviceIoControl function with the operation code IOCTL_DISK_CREATE_DISK to initialize the disk and create a partition table.
When IOCTL_DISK_CREATE_DISK operation code is used, lpInBuffer must fill in a CREATE_DISK structure parameter, including the Partition Table type and disk signature parameters. For details, see MSDN. In this example, create an MBR partition table. The signature is generated at the current time.
4. Refresh the partition table. Note: Any modification to the disk partition information in the program requires the DeviceIoControl function with the operation code IOCTL_DISK_UPDATE_PROPERTIES to be called to refresh the partition table, which is effective.
/**************** Create a partition *******************/
5. Call GetDriveGeometry to obtain the disk information. (For details about GetDriveGeometry, see the previous section ). Because the partition size information is required during partition creation, we calculate the total disk size and divide it by partNum to evenly distribute the number of bytes to each partition.
6. Allocate the DRIVE_LAYOUT_INFORMATION_EX struct space. We specify how to partition the hard disk by entering data in this struct. Struct is defined as follows:
Typedef struct _ DRIVE_LAYOUT_INFORMATION_EX {
DWORD PartitionStyle;
DWORD PartitionCount;
Union {
DRIVE_LAYOUT_INFORMATION_MBR;
DRIVE_LAYOUT_INFORMATION_GPT Gpt;
};
PARTITION_INFORMATION_EX PartitionEntry [1];
} DRIVE_LAYOUT_INFORMATION_EX,
* PDRIVE_LAYOUT_INFORMATION_EX;
Here, PartitionCount is a multiple of 4. to simplify the processing, we set it to 4.
In addition, pay attention to the PARTITION_INFORMATION_EX array PartitionEntry [1]. Although only one element is defined in the struct, the following must actually complement the PartitionCount-1 element. Therefore, the Code adds (actualPartNum-1) * sizeof (PARTITION_INFORMATION_EX) to the space allocated by DRIVE_LAYOUT_INFORMATION_EX * dl ).
7. Fill in data in the dl Of The DRIVE_LAYOUT_INFORMATION_EX struct space.
Set all partitions to PARTITION_ENTRY_UNUSED, and then specify the number of partitions allocated.
The recycle body then assigns a value to the PartitionEntry of each partition.
In addition to skipping the space occupied by the preceding partition, StartingOffset also adds 63 sectors (32256 bytes ).
PartitionNumber starts from 1.
Mbr. PartitionType = PARTITION_IFS indicates the NTFS format.
Mbr. HiddenSectors The number of hidden sectors to be allocated when the partition table is created on MSDN. I don't understand it very well. Please add it.
8. Call the DeviceIoControl function of the operation code IOCTL_DISK_SET_DRIVE_LAYOUT_EX to execute the partition. The parameter must be filled with the ready DRIVE_LAYOUT_INFORMATION_EX struct and size.
9. Refresh the partition table in the same principle as 4.
In addition, I added Sleep (3000) to the end of the function ). This is because I found that the partition creation operation takes some time to execute. If other related operations (such as formatting the partition) are followed in the future, the error that the partition does not exist may occur, so wait 3 seconds to make sure the execution is complete.
This section involves many types, but each type has a strong relevance. You can refer to MSDN For more details at any time.
This article is from the "bunny's technology Journey" blog