Q In the Demo of MSDN, the device name is changed to "A:" Take the A disk parameters, first use the resource manager to read the disc, then run this program can be successful, but after changing a disk, it will fail; CDROM0 "Take the CDROM parameters, no matter how it is. How to solve this problem?
A Take the floppy disk parameter is a formatted information from the floppy disk, that is, the read operation must be performed, which is different from the hard disk. Change the access method in CreateFile to generic_read.
IOCTL_DISK_GET_DRIVE_GEOMETRY This I / O control code, which is valid for the floppy disk and the hard disk, but for some removable media such as CD / DVD-ROM, TAPE, etc. It is necessary to take a CDROM parameter and have a different approach. IOCTL_STORAGE_GET_MEDIA_TYPES_EX can help us solve the problem.
Q Use these I / O control code, what kind of input output data format is required?
A DeviceioControl does not need to enter data when using these two control code.
IOCTL_DISK_GET_DRIVE_GEOMETRY directly outputs a Disk_geometry structure:
Typedef struct _disk_geometry {
Large_integer cylinders; // Cylindrical
Media_Type MediaType; // Media Type
DWORD TRACKSPERCYLINDER; / / number of tracks per cylinder
DWORD SECTORSPERTRACK; / / / / number of sectors per track
DWORD BYTESPERSECTOR; / / The number of bytes per sector
DISK_GEMETRY;
IOCTL_STORAGE_GET_MEDIA_TYPES_EX outputs a get_media_types structure:
TYPEDEF STRUCT _GET_MEDIA_TYPES {
DWORD DeviceType; // Device Type
DWORD MediaInfocount; // Media Information
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; // Cylindrical
Storage_Media_Type MediaType; // Media Type
DWORD TRACKSPERCYLINDER; / / number of tracks per cylinder
DWORD SECTORSPERTRACK; / / / / number of sectors per track
DWORD BYTESPERSECTOR; / / The number of bytes per sector
DWord NumberMediasIDes; // Media
DWORD MediaChacteristics; // Media Features
} Diskinfo; // hard disk information
Struct {
Large_integer cylinders; // Cylindrical
Storage_Media_Type MediaType; // Media Type
DWORD TRACKSPERCYLINDER; / / number of tracks per cylinder
DWORD SECTORSPERTRACK; / / / / number of sectors per track
DWORD BYTESPERSECTOR; / / The number of bytes per sector
DWord NumberMediasIDes; // Media
DWORD MediaChacteristics; // Media Features} RemovableDiskinfo; // "Mobile Disk" Information
Struct {
Storage_Media_Type MediaType; // Media Type
DWORD MediaChacteristics; // Media Features
DWORD CURRENTBLOCKSIZE; // Block size
} TAPEINFO; // Tape information
DEVICESPECIFIC;
DEVICE_MEDIA_INFO;
Where the CD-ROM belongs to the range of "movable disc". Note that the GET_MEDIA_TYPES structure itself defines a device_media_info, additional device_media_info requires another space of this structure.
Q Call Method I understand, please use VC to give an example to implement the long-awaited function?
A good, now demonstrate how to get the parameters of the floppy disk / hard disk / disc. When testing, remember to have a flopp / disc inserted in the drive!
First, use the MFC AppWizard to generate a single document application, named DiskGeometry, letting its view based on CeditView.
Then, add the following .h and .cpp files.
//
// getDiskGeometry.h
//
#if! defined (get_disk_geometry_h__)
#DEFINE GET_DISK_GEMETRY_H__
#iF _MSC_VER> 1000
#pragma overce
#ENDIF / / 100 m _ _ _
#include
Bool getDriveGeometry (Const Char * filename, Disk_geometry * PDG);
#ndif //! 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 defined enough space
#define Media_INFO_SIZE SIZEOF (GET_MEDIA_TYPES) 15 * SIZEOF (Device_Media_Info)
// filename - file name for the device
// PDG - Parameter buffer pointer
Bool getDriveGeometry (const char * filename, disk_geometry * pdg)
{
Handle HDevice; // Equipment handle
Bool Bresult; // Deviceiocontrol return result
GET_MEDIA_TYPES * PMT; // Internal output buffer
DWORD dwoutBytes; // Output data length
// Open the device
HDevice = :: createfile (filename, // file name
Generic_read, // Soft drive needs to read the disk
File_share_read | file_share_write, // shared method
NULL, / / Default security descriptor
Open_existing, // creation method
0, // No need to set the file attribute null); // No need to refer to the template file
IF (HDevice == Invalid_Handle_Value)
{
// Equipment can't open ...
Return False;
}
// Use ioctl_disk_get_drive_geometry to pick up the disk parameters
BRESULT = :: Deviceiocontrol (HDevice, // Equipment handle
IOCTL_DISK_GET_DRIVE_GEOMETRY, // Take the disk parameters
NULL, 0, // No need to enter data
PDG, SIZEOF (Disk_geometry), // Output Data Buffer
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
// If you fail, use ioctl_storage_get_media_types_ex to extract media type parameters
IF (! BRESULT)
{
PMT = (GET_MEDIA_TYPES *) New Byte [Media_Info_size];
BRESULT = :: Deviceiocontrol (HDevice, // Equipment handle
IOCTL_STORAGE_GET_MEDIA_TYPES_EX, // Reproduction Media Type Parameters
NULL, 0, // No need to enter data
PMT, Media_INFO_SIZE, / / Output Data Buffer
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
IF (BRESULT)
{
// Notes that the structure device_media_info is expanded on the basis of Structure Disk_geometry
/ / For the simplified program, use memcpy instead of the following multiple assignment statements:
// pdg-> mediatype = (Media_Type) PMT-> MediaInfo [0] .devicespecific.diskinfo.mediType;
// 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 the IDR_MAINFRAME of Toolbar, ID_GET_DISK_GEOMETRY. Open ClassWizard in DiskGeometryView
Add ID_GET_DISK_GEOMETRY's mapping function onGetDiskGeometry. Open DiskGeometryView.cpp and include header file getDiskGeometry.h.
Add the following code in ONGETDiskGeometry
Const char * szdevname [] = {
". //A:",
".//B:",
".//Physicaldrive0",
".//Physicaldrive1",
".//Physicaldrive2",
".//Physicaldrive3",
". //Cdrom0",
".//Cdrom1",
}
Disk_geometry DG;
Ulonglong disksize;
Bool Bresult;
CString strmsg;
CString stratmp;
For (int i = 0; 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.Bytespector; 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 is the last? Compile, run ... [related resources] This article Demo Source: DiskGeometry.zip (21kb) BHW98 column: http://www.9cbs.net/develop/author/netauthor/bhw98/ First release: 2003-02-18 Last revision: 2003-05-20