In section 1, we talked about two types of disk device names:
For physical drive x, the format is \. \ PhysicalDriveX. The number starts from 0, for example
Name |
Description |
\. \ PhysicalDrive0 |
Open the first physical drive |
\\. \ PhysicalDrive2 |
Open the third physical drive |
For logical partitions (volumes), the format is \. \ X:, for example
Name |
Description |
\. \: |
Open drive) |
\. \ C: |
Open disk C (logical partition of disk) |
How to find the physical drive numbers 0, 1, 2 ...... And logical partition numbers C, D, E ...... What is the relationship between them? This section describes how to obtain a physical drive letter by using a logical partition number. The next section describes how to identify the logical Partition Number contained by a physical drive number. Of course, there will certainly be other ways to implement the same function. You are welcome to add this.
First, we need to make it clear that the physical drive letter and the logical partition number should be one-to-many. For example, disk0 may contain three partitions: C, D, and E. So the function GetPhysicalDriveFromPartitionLetter discussed below returns a separate integer number. DeviceIoControl provides the operation code IOCTL_STORAGE_GET_DEVICE_NUMBER, which allows you to conveniently obtain the type and number of the device that is enabled.
The Code is as follows:
/*************************************** ***************************************
* Function: get disk's physical number from its drive letter
* E.g. C --> 0 (C: is on disk0)
* Input: letter, drive letter
* Output: N/
* Return: Succeed, disk number
* Fail,-1
**************************************** **************************************/
DWORD GetPhysicalDriveFromPartitionLetter (CHAR letter)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL result; // results flag
DWORD readed; // discard results
STORAGE_DEVICE_NUMBER number; // use this to get disk numbers
CHAR path [DISK_PATH_LEN];
Sprintf (path, "\\\\\ % c:", letter );
HDevice = CreateFile (path, // drive to open
GENERIC_READ | GENERIC_WRITE, // access to the drive
File_cmd_read | file_cmd_write, // share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attribute
If (hDevice = INVALID_HANDLE_VALUE) // cannot open the drive
{
Fprintf (stderr, "CreateFile () Error: % ld \ n", GetLastError ());
Return DWORD (-1 );
}
Result = DeviceIoControl (
HDevice, // handle to device
IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
& Number, // output buffer
Sizeof (number), // size of output buffer
& Readed, // number of bytes returned
NULL // OVERLAPPED structure
);
If (! Result) // fail
{
Fprintf (stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: % ld \ n", GetLastError ());
(Void) CloseHandle (hDevice );
Return (DWORD)-1;
}
// Printf ("% d \ n", number. DeviceType, number. DeviceNumber, number. PartitionNumber );
(Void) CloseHandle (hDevice );
Return number. DeviceNumber;
}
Code Analysis:
1. Generate a device name based on the Partition Number.
2. Call CreateFile to open the device and obtain the device handle.
3. Call the DeviceIoControl function whose operation code is IOCTL_STORAGE_GET_DEVICE_NUMBER. The output is the struct variable STORAGE_DEVICE_NUMBER.
Struct STORAGE_DEVICE_NUMBER is defined
Typedef struct _ STORAGE_DEVICE_NUMBER {
DEVICE_TYPE DeviceType;
ULONG DeviceNumber;
ULONG PartitionNumber;
} STORAGE_DEVICE_NUMBER, * PSTORAGE_DEVICE_NUMBER;
The DeviceNumber is the physical disk number we need.
4. Return DeviceNumber.
This article is from the "bunny Technology Workshop" blog