Battle DeviceIocontrol 2: Get the parameters of floppyhard diskdisc

zhaozj2021-02-16  45

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

转载请注明原文地址:https://www.9cbs.com/read-23678.html

New Post(0)