Q DOS Command Diskcopy gives me a deep impression, now there are many "clone" software that can be copied for disk. I want to make disk mirror files, should DeviceioControl should be very useful?
A Yes. Here, a fabrication file is made, and the function is similar to example "DiskCopy".
This example implements the core code of its function as follows:
// Open disk
Handle OpenDisk (LPCTSTR FileName)
{
Handle hdisk;
// Open the device
hdisk = :: createfile (filename, // file name
Generic_read | generic_write, // Read and write
File_share_read | file_share_write, // shared method
NULL, / / Default security descriptor
Open_existing, // creation method
0, // Do not set file properties
NULL); // Do not need to refer to the template file
Return hdisk;
}
// Get disk parameters
Bool getDiskGeometry (Handle Hdisk, Pdisk_geometry LpGeometry)
{
DWORD DWOUTBYTES;
Bool Bresult;
// Use ioctl_disk_get_drive_geometry to pick up the disk parameters
BRESULT = :: DeviceIocontrol (hdisk, // device handle
IOCTL_DISK_GET_DRIVE_GEOMETRY, // Take the disk parameters
NULL, 0, // No need to enter data
LpGeometry, SizeOf (Disk_geometry), // Output Data Buffer
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
Return BRESULT;
}
/ / Start reading the disk from the specified track
Bool ReadTracks (Handle Hdisk, Pdisk_geometry LpGeetry, LPVOID PBUF, DWORD DWSTARTCYLINDER, DWORD DWCYLINDERNUMBER)
{
DWORD VIRTBUFSIZE;
DWORD BYTESREAD;
// Size
Virtbufsize = lpGeometry-> TRACKSPERCYLINDER * LPGEOMETRY-> SECTORSPERTRACK * LPGEMETRY-> BYTESPERSector;
// offset
:: setFilePointer (HDisk, Virtbufsize * DWStartcyLinder, Null, File_Begin);
Return :: readfile (hdisk, pbuf, virtbufsize * dwcylindernumber, & bytesread, null);
}
/ / Start writing a disk from the specified track
Bool WriteTracks (Handle Hdisk, Pdisk_geometry LpGeetry, LPVOID PBUF, DWORD DWSTARTCYLINDER, DWORD DWCYLINDERNUMBER)
{
DWORD VIRTBUFSIZE;
DWORD BYTESWRITTEN
// Size virtbufsize = lpGeometry-> TRACKSPERCYLINDER * LPGEMETRY-> SECTORSPERTRACK * LPGEMETRY-> BYTESPERSector;
// offset
:: setFilePointer (HDisk, Virtbufsize * DWStartcyLinder, Null, File_Begin);
Return :: Writefile (HDisk, Pbuf, Virtbufsize * dwcylindernumber, & byteswritten, null);
}
/ / Start formatting disk from the specified track
Bool LowlevelFormattracks (Handle Hdisk, Pdisk_geometry LpGeometry, DWORD DWSTARTCYLINDER, DWORD DWCYLINDERNUMBER)
{
Format_Parameters formatparameters;
PBAD_TRACK_NUMBER LPBADTRACK;
DWORD DWOUTBYTES;
DWORD DWBUFSIZE;
Bool Bresult;
FormatParameters.MediaType = lpGeometry-> MediaType;
FormatParameters.startcylindernumber = dwstartcylinder;
FormatParameters.endcylinderNumber = DWStartcyLinder DWCYLINDERNUMBER - 1;
FormatParameters.startheadnumber = 0;
FormatParameters.endheadnumber = lpGeometry-> TRACKSPERCYLINDER - 1;
Dwbufsize = lpGeometry-> TRACKSPERCYLINDER * SIZEOF (BAD_TRACK_NUMBER);
LPBADTRACK = (PBAD_TRACK_NUMBER) New Byte [dwbufsize];
// Use ioctl_disk_format_tracks to low-level formatting continuous tracks
BRESULT = :: DeviceIocontrol (hdisk, // device handle
IOCTL_DISK_FORMAT_TRACKS, // low-level formatting
& FormatParameters, SIZEOF (FormatParameters), // Enter data buffer
LPBADTRACK, DWBUFSIZE, / / Output Data Buffer
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
DELETE LPBADTRACK;
Return BRESULT;
}
// lock the volume
Bool LockVolume (Handle HDisk)
{
DWORD DWOUTBYTES;
Bool Bresult;
// Lock with FSCTL_LOCK_VOLUME
BRESULT = :: DeviceIocontrol (hdisk, // device handle
FSCTL_LOCK_VOLUME, / / Lock
NULL, 0, // No need to enter data
NULL, 0, // do not need to output data
& dwoutbytes, // Output Data Length (LPOVERLAPPED) NULL); // Synchronous I / O
Return BRESULT;
}
// Unlock the roll
Bool UnlockVolume (Handle Hdisk)
{
DWORD DWOUTBYTES;
Bool Bresult;
// open the lock with fsctl_unlock_volume
BRESULT = :: DeviceIocontrol (hdisk, // device handle
FSCTL_UNLOCK_VOLUME, / / ON Lock
NULL, 0, // No need to enter data
NULL, 0, // do not need to output data
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
Return BRESULT;
}
// remove the volume
/ / This action makes the system reconscribed disks, equivalent to re-insert
Bool DismountVolume (Handle Hdisk)
{
DWORD DWOUTBYTES;
Bool Bresult;
// Unload the volume with fsctl_dismount_volume
BRESULT = :: DeviceIocontrol (hdisk, // device handle
FSCTL_DISMOUNT_VOLUME, / / Unloading
NULL, 0, // No need to enter data
NULL, 0, // do not need to output data
& dwoutBytes, // Output data length
(LPOVERLAPPED) NULL); // Synchronous I / O
Return BRESULT;
}
The step of saving the floppy disk into a mirror file is simple to describe: 1. Creating an empty mirror file. 2, call OpenDisk to open the floppy disk. Success transfer 3, failing to turn 8. 3, call LockVolume to lock the volume. Success transfer 4, failing to turn 7. 4, call GetDiskGeometry to get parameters. Success transfer 5, failure 6. 5. Write the disk parameters into the image file as the file header. The readTracks calls the cylinder to read the data, saved in the mirror file. The number of cycles is equal to the number of cylinders. 6, call UNLOCKVOLUME to unlock the roll. 7, call CloseDisk to turn off the floppy disk. 8, close the image file.
The step of loading the mirror file into the floppy disk is: 1. Open the image file. 2, call OpenDisk to open the floppy disk. Success transfer 3, failing to turn 11. 3, call LockVolume to lock the volume. Success transfer 4, failure 10. 4, call GetDiskGeometry to get parameters. Success transfer 5, failing to turn 9. 5. Read the file header from the mirror file, and determine whether the two disk parameters are consistent. Do not match 6, otherwise turn 7. 6. Call the LowLevelFormatTracks to press the floppy disk. The number of cycles is equal to the number of cylinders. Success to 7, failure to turn 8. 7, read the data from the mirror file and call WRITETRACKS to write the disk by cylinder. The number of cycles is equal to the number of cylinders. 8. Call DISMOUNTVOLUME to remove the volume. 9, call unlockvolume to unlock the roll. 10. Call the CloseDisk to turn off the floppy disk. 11, close the mirror file.
Q I noticed that disk read and write and formatting is made according to the cylinder, what is the reason?
A does not have a particular reason, just because the process can be easily displayed in this example. One thing needs to be particularly mentioned. When reading and writing disk data according to absolute address, the "minimum unit" is a sector, and the address must align with the sector, and the length is also equal to the integer multiple of the sector length. For example, 512 bytes per sector, then the starting address and data length should be talented by 512.
Q I suddenly produced a great idea, using a disk using the absolute address, including the U disk, Mo, instead of using the ready-made file system, isn't it possible to confidential data?
A of course, as long as you like it. Don't do test on your system disk, otherwise ... you can't blame BHW98, no remind you!
Q I know how to test the transmission speed of the optical drive, use the above method, read a certain length of data, remove the time required, should it be?
A can. But use IOCTL_STORAGE_GET_MEDIA_TYPES_EX when using the disc parameter, we have explored.
[related resources]
This article Demo Source: FLOPPYIMAGE.ZIP (16KB) Example of Microsoft: VS6Samples.exe (134,518kb) BHW98 column: http://www.9cbs.net/develop/author/netauthor/bhw98/
First release: 2003-02-19 Last revision: 2003-05-20