Q: In NT/2000/XP, I want to use VC to write applications to access hardware devices, such as obtaining disk parameters, reading and writing absolute sector data, and testing the actual drive.
Speed, etc. Where should I start?
A:
In NT/2000/XP, applications can use the API function deviceiocontrol
To access devices-to obtain information, send commands, and exchange data. This interface function is used to send the correct control code and data to the specified device driver. However
After analyzing the response, we can achieve our goal.
The function prototype of deviceiocontrol is:
Bool deviceiocontrol (
Handle hdevice, // device handle
DWORD dwiocontrolcode, // control code
Lpvoid lpinbuffer, // input data buffer pointer
DWORD ninbuffersize, // input data buffer Length
Lpvoid lpoutbuffer, // output data buffer pointer
DWORD noutbuffersize, // length of the output data buffer
Lpdword lpbytesreturned, // actual length of the output data unit
Lpoverlapped // overlapping operation structure pointer
);
The device handle is used to identify the device you are accessing.
Send different control codes to call different types of functions of the device driver. In the header file winioctl. H, the predefined standard device control codes are
Start with IOCTL or fsctl. For example, ioctl_disk_get_drive_geometry
Is the control code for the physical drive to take structural parameters (media type, number of cylinders, number of tracks per cylinder, number of sectors per track, etc.), fsctl_lock_volume
Is the control code for locking the volume of the logical drive.
Whether the input/output data buffer is required, the structure of the buffer, and the size of the byte space are determined by the different operation types of different devices. In the header file winioctl. H, some input/output data structures have been predefined for the standard device. Overlapping operation structure pointer settings
If it is null, deviceiocontrol will block the call. Otherwise, it should be designed asynchronously during programming.
Q: Where is the device handle obtained?
A:
API can be used for device handles
Function createfile. Its prototype is:
Handle createfile (
Lptstr lpfilename, // file name
DWORD dwdesiredaccess, // access mode DWORD dw1_mode, // share mode
Lpsecurity_attributes lpsecurityattributes, // security descriptor pointer
DWORD dwcreationdisposition, // Creation Method
DWORD dwflagsandattributes, // file attributes and flag
Handle htemplatefile // template file handle
);
Createfile
This function is very useful. Here we use it to "open" the device driver to get the device handle. After the operation is complete, use closehandle to close the device handle.
Different from common file names, the "file name" format of the device driver is fixed as ". devicename (note that this string is written as ". devicename "), devicename must be the same as the device name specified in the device driver.
Generally
When createfile obtains the device handle, the access mode parameter is set to 0 or generic_read | generic_write, And the sharing mode parameter is set
File_cmd_read | file_cmd_write. The creation method parameter is set to open_existing, and other parameters are set to 0 or null.
Q: But how do I know the device name?
A:
The names of some storage devices are defined by Microsoft and cannot be changed. The general list is as follows:
Floppy disk drive a:, B:
Logical drive C :,
D:, E :,......
Physical drive physicaldrivex
CD-ROM, DVD/ROM cdromx
Tape drive tapex
The physical drive does not include the soft drive and optical drive. The logical drive can be an IDE, SCSI, PCMCIA, or USB interface hard disk partition (volume), optical drive, Mo, CF card, or even a virtual disk. X = 0, 1, 2 ......
Other device names must use the guid of the driver interface.
This is not discussed here.
Q: How to Use deviceiocontrol
Access the device driver.
A:
Here is a demo program Excerpted from msdn to demonstrate how to use
Deviceiocontrol: obtain the basic parameters of the hard disk.
/* The code of interest is in the subroutine GetDriveGeometry. The
code in main shows how to interpret the results of the IOCTL call. */
#include
#include BOOL GetDriveGeometry(DISK_GEOMETRY *pdg)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL bResult; // results flag
DWORD junk; // discard results
hDevice = CreateFile(.PhysicalDrive0, // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform
NULL, 0, // no input buffer
pdg, sizeof(*pdg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
CloseHandle(hDevice);
return (bResult);
}
int main(int argc, char *argv[])
{
DISK_GEOMETRY pdg; // disk drive geometry structure
BOOL bResult; // generic results flag
ULONGLONG DiskSize; // size of the drive, in bytes
bResult = GetDriveGeometry (&pdg);
if (bResult)
{
printf(Cylinders = %I64d
, pdg.Cylinders);
printf(Tracks per cylinder = %ld
, (ULONG) pdg.TracksPerCylinder); printf(Sectors per track = %ld
, (ULONG) pdg.SectorsPerTrack);
printf(Bytes per sector = %ld
, (ULONG) pdg.BytesPerSector);
DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
(ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
printf(Disk size = %I64d (Bytes) = %I64d (Mb)
, DiskSize,
DiskSize / (1024 * 1024));
}
else
{
printf (GetDriveGeometry failed. Error %ld.
, GetLastError ());
}
return ((int)bResult);
}
Q: If you change the device name to "A:", A can be used.
If you change disk parameters to "cdrom0", you can use the "CDROM" parameter. Is that true?
A
:
You will not be answered for this question. Please try it.
Now let's summarize the three steps to access the device driver through deviceiocontrol: first use createfile
Get the device handle, and then use deviceiocontrol to perform I/O with the device. Do not forget to use closehandle to close the device handle.