Deviceiocontrol 2: Obtain the disk/Hard Disk/disc parameters

Source: Internet
Author: User
QIn the demo of msdn, replace the device name with "A:" To obtain the parameters of disk A, read the disk with the resource manager, and then run the program successfully, however, after changing the disk, it will fail. If you change to "cdrom0", the CDROM parameter will not work in any case. How can this problem be solved?

AThe floppy disk is used to read formatted Information from a floppy disk, that is, the disk must be read. This is different from the hard disk. Change the access method in createfile to generic_read.
Ioctl_disk_get_drive_geometry is an I/O control code that is valid for floppy disks and hard disks. However, ioctl_disk_get_drive_geometry is useless for removable media such as CD/DVD-ROM and tape. To obtain the CDROM parameter, you must find another way. Ioctl_storage_get_media_types_ex can help us solve the problem.

QWhat input/output data format is required for using these I/O control codes?

AWhen deviceiocontrol uses these two control codes, no data is required.
Ioctl_disk_get_drive_geometry directly outputs a disk_geometry structure:

Typedef struct _ disk_geometry {
Large_integer cylinders; // Number of cylinders
Media_type mediatype; // media type
DWORD trackspercylinder; // number of tracks per cylinder
DWORD sectorspertrack; // number of sectors per track
DWORD bytespersector; // number of bytes per sector
} Disk_geometry;

Ioctl_storage_get_media_types_ex outputs a get_media_types structure:

Typedef struct _ get_media_types {
DWORD devicetype; // device type
DWORD mediainfocount; // number of media information items
Device_media_info mediainfo [1]; // media information
} Get_media_types;

Let's take a look at the definition of the device_media_info structure:

Typedef struct _ device_media_info {
Union {
Struct {
Large_integer cylinders; // Number of cylinders
Storage_media_type mediatype; // media type
DWORD trackspercylinder; // number of tracks per cylinder
DWORD sectorspertrack; // number of sectors per track
DWORD bytespersector; // number of bytes per sector
DWORD numbermediasides; // number of media faces
DWORD mediacharacteristics; // media features
} Diskinfo; // hard disk Information
Struct {
Large_integer cylinders; // Number of cylinders
Storage_media_type mediatype; // media type
DWORD trackspercylinder; // number of tracks per cylinder
DWORD sectorspertrack; // number of sectors per track
DWORD bytespersector; // number of bytes per sector
DWORD numbermediasides; // number of media faces
DWORD mediacharacteristics; // media features
} Removablediskinfo; // "removable disk" Information
Struct {
Storage_media_type mediatype; // media type
DWORD mediacharacteristics; // media features
DWORD currentblocksize; // block size
} Tapeinfo; // tape Information
} Devicespecific;
} Device_media_info;

The CD-ROM is within the range of removable disks. Note that the get_media_types structure only defines one device_media_info, and the additional device_media_info needs to be followed by another space in this structure.

QI have learned how to call the method. Please use VC as an example to implement the functions I have been waiting for a long time?

ANow, we will demonstrate how to obtain the parameters of a floppy disk, hard disk, or disc. During the test, remember to have a floppy disk/CD in the drive!
First, use MFC Appwizard to generate a single-document application named diskgeometry so that its view is based on ceditview.
Then, add the following. h and. cpp files.

//////////////////////////////////////// //////////////////////////////////////
// Getdiskgeometry. h
//////////////////////////////////////// //////////////////////////////////////

# If! Defined (get_disk_geometry_h __)
# Define get_disk_geometry_h __

# If _ msc_ver> 1000
# Pragma once
# Endif // _ msc_ver> 1000

# Include <winioctl. h>

Bool getdrivegeometry (const char * filename, disk_geometry * PDG );

# Endif //! Defined (get_disk_geometry_h __)

//////////////////////////////////////// //////////////////////////////////////
// Getdiskgeometry. cpp
//////////////////////////////////////// //////////////////////////////////////

# Include "stdafx. H"
# Include "getdiskgeometry. H"

// Ioctl_storage_get_media_types_ex may return more than one device_media_info, so sufficient space is defined.
# Define media_info_size sizeof (get_media_types) + 15 * sizeof (device_media_info)

// Filename -- Used for the device file name
// PDG -- parameter buffer pointer
Bool getdrivegeometry (const char * filename, disk_geometry * PDG)
{
Handle hdevice; // device handle
Bool bresult; // return result of deviceiocontrol
Get_media_types * PMT; // internal output buffer
DWORD dwoutbytes; // Output Data Length

// Open the device
Hdevice =: createfile (filename, // file name
Generic_read, // the disk needs to be read by the drive.
File_pai_read | file_pai_write, // Sharing Method
Null, // Default Security Descriptor
Open_existing, // Creation Method
0, // file attributes do not need to be set
Null); // you do not need to refer to the template file.

If (hdevice = invalid_handle_value)
{
// The device cannot be opened...
Return false;
}

// Use ioctl_disk_get_drive_geometry to retrieve disk Parameters
Bresult =: deviceiocontrol (hdevice, // device handle
Ioctl_disk_get_drive_geometry, // obtain disk Parameters
Null, 0, // no input data
PDG, sizeof (disk_geometry), // output data buffer
& Dwoutbytes, // Output Data Length
(Lpoverlapped) null); // use synchronous I/O

// If the request fails, use ioctl_storage_get_media_types_ex to obtain the media type parameter.
If (! Bresult)
{
PMT = (get_media_types *) New byte [media_info_size];

Bresult =: deviceiocontrol (hdevice, // device handle
Ioctl_storage_get_media_types_ex, // gets the media type parameter
Null, 0, // no input data
PMT, media_info_size, // output data buffer
& Dwoutbytes, // Output Data Length
(Lpoverlapped) null); // use synchronous I/O

If (bresult)
{
// Note that the device_media_info structure is extended based on the disk_geometry structure.
// To simplify the program, replace memcpy with the following assignment statements:
// PDG-> mediatype = (media_type) PMT-> mediainfo [0]. devicespecific. diskinfo. mediatype;
// PDG-> cylinders = PMT-> mediainfo [0]. devicespecific. diskinfo. cylinders;
// PDG-> trackspercylinder = PMT-> mediainfo [0]. devicespecific. diskinfo. trackspercylinder;
//......
: Memcpy (PDG, PMT-> mediainfo, sizeof (disk_geometry ));
}

Delete PMT;
}

// Close the device handle
: Closehandle (hdevice );

Return (bresult );
}

Then, add a button on idr_mainframe of the toolbar with the ID id_get_disk_geometry. Open classwizard, in diskgeometryview

Add the ing function ongetdiskgeometry of id_get_disk_geometry. Open diskgeometryview. cpp, including the header file getdiskgeometry. h.

In ongetdiskgeometry, add the following code:

Const char * szdevname [] =
{
"//. // :",
"//. // B :",
"////. // Physicaldrive0 ",
"////. // Physicaldrive1 ",
"////. // Physicaldrive2 ",
"////. // Physicaldrive3 ",
"//. // Cdrom0 ",
"//. // Cdrom1 ",
};
Disk_geometry DG;
Ulonglong disksize;
Bool bresult;
Cstring strmsg;
Cstring strtmp;

For (INT I = 0; I <sizeof (szdevname)/sizeof (char *); I ++)
{
Bresult = getdrivegeometry (szdevname [I], & DG );

Strtmp. Format ("/R/n % s result = % S/R/N", szdevname [I], bresult? "Success": "failure ");
Strmsg + = strtmp;

If (! Bresult) continue;

Strtmp. Format ("media type = % d/R/N", dg. mediatype );
Strmsg + = strtmp;

Strtmp. Format ("Cylinders = % i64d/R/N", dg. cylinders );
Strmsg + = strtmp;

Strtmp. Format ("tracks per cylinder = % LD/R/N", (ulong) DG. trackspercylinder );
Strmsg + = strtmp;

Strtmp. Format ("sectors per track = % LD/R/N", (ulong) DG. sectorspertrack );
Strmsg + = strtmp;

Strtmp. Format ("bytes per sector = % LD/R/N", (ulong) DG. bytespersector );
Strmsg + = strtmp;

Disksize = DG. Cylinders. quadpart * (ulong) DG. trackspercylinder *
(Ulong) DG. sectorspertrack * (ulong) DG. bytespersector;
Strtmp. Format ("disk size = % i64d (bytes) = % i64d (MB)/R/N", disksize, disksize/(1024*1024 ));
Strmsg + = strtmp;
}

Cedit & edit = geteditctrl ();

Edit. setwindowtext (strmsg );

Finally, what should I do? Compile and run ......

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.