This is my first article, hope to be useful. thanks everybody to support!
Windows Disk Management make we can know all partitions on a disk easily. For example, the disk1 includes C: and D:, the disk2 includes E: and F:. Now we can get a disk number of a specified partition by using drive letter.
The IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS control code is provided to retrieve the physical location and disk number of a specified partition on one or more disks.
A structure is declared as follows:
1 2 3 4 5
|
typedef struct _VOLUME_DISK_EXTENTS
{
DWORD NumberOfDiskExtents;
DISK_EXTENT Extents[ANYSIZE_ARRAY];
} VOLUME_DISK_EXTENTS;
|
This structure hold a result which IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS is executed by DeviceIoControl. In which, NumberOfDiskExtents represents that this partition was inclued in the number of disk. Usually, if a partition exists in a basic disk, its value is 1. however, a partition exists in dynamic disk and it is a striped or spanned volume. In this case, and its value is greater than 1 to represent a available size of the array Extents.
The structure DISK_EXTENT declaring is the below:
1 2 3 4 5 6
|
typedef struct _DISK_EXTENT
{
DWORD DiskNumber;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER ExtentLength;
} DISK_EXTENT;
|
In this structure DiskNumber is a disk number that the partition lies, so the DiskNumber is a member we desire the most. The member StartingOffset is a start physical location of this partition(in bytes), this is, the location of DBR.
Related example source code is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
//-----------------------------
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <winioctl.h>
typedef struct _DISK_EXTENT
{
DWORD DiskNumber;
LARGE_INTEGER StartingOffset;
LARGE_INTEGER ExtentLength;
} DISK_EXTENT, *PDISK_EXTENT;
typedef struct _VOLUME_DISK_EXTENTS
{
DWORD NumberOfDiskExtents;
DISK_EXTENT Extents[ANYSIZE_ARRAY];
} VOLUME_DISK_EXTENTS, *PVOLUME_DISK_EXTENTS;
#define IOCTL_VOLUME_BASE ((DWORD) āVā)
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS \
CTL_CODE(IOCTL_VOLUME_BASE, 0, \
METHOD_BUFFERED, FILE_ANY_ACCESS)
int _tmain(int argc, TCHAR* argv[])
{
TCHAR szPath[MAX_PATH] = {0};
_stprintf(szPath, _T("\\\\.\\%c:"), _T(āC'));
HANDLE hHandle = CreateFile(szPath
, GENERIC_READ|GENERIC_WRITE
, FILE_SHARE_WRITE|FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL);
if (hHandle == INVALID_HANDLE_VALUE)
{
_tprintf(_T("Open %s failed\n"), szPath);
return -1;
}
VOLUME_DISK_EXTENTS volumeDiskExtents;
DWORD dwBytesReturned = 0;
BOOL bResult = DeviceIoControl(hHandle
, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
, NULL
, 0
, &volumeDiskExtents
, sizeof(volumeDiskExtents)
, &dwBytesReturned
, NULL);
CloseHandle(hHandle);
if (!bResult)
{
_tprintf(_T("Failed to issue the control code!\n"));
return -1;
}
_tprintf(_T("The below is a information about %s\n"),
szPath);
for (DWORD n = 0;
n < volumeDiskExtents.NumberOfDiskExtents;
++n)
{
PDISK_EXTENT pDiskExtent =
&volumeDiskExtents.Extents[n];
_tprintf(_T("Disk number: %d\n")
, pDiskExtent->DiskNumber);
_tprintf(_T("DBR start sector: %I64d\n")
, pDiskExtent->StartingOffset.QuadPart
/512);
}
return 0;
}
|
By the above example code, hope you can understand the usage of this control code. This section code can be compiled successfully on Visual C++6.0 environment.
Author by Wobin.Mei , on June 20th, 2009
My blog is
wobinmei.blog.com