MFMT.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:17k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /*++
- Module Name:
- mfmt.c
- Abstract:
- This program is designed to show how to access a physical floppy
- disk using the Win32 API set.
- This program has two major functions.
- - It can be used to display the geometry of a disk
- mfmt -g a:
- - It can be used to produce a disk image, or to write a disk
- image to a floppy.
- mfmt -c a: bootdisk - produce a disk image of a:
- mfmt -c bootdisk a: - make a: identical to bootdisk image
- This program is very very simple. Minimal error checking is done. It is
- meant to provide an example of how to:
- - Open a physical disk
- - Read a disk's geometry
- - Perform a low level format operation
- - read and write physical sectors
- --*/
- #include <stdlib.h>
- #include <stdio.h>
- #include <windows.h>
- #include <winioctl.h>
- #include <string.h>
- #include <ctype.h>
- #include <memory.h>
- DISK_GEOMETRY SupportedGeometry[20];
- DWORD SupportedGeometryCount;
- BOOL
- GetDiskGeometry(
- HANDLE hDisk,
- PDISK_GEOMETRY lpGeometry
- )
- {
- DWORD ReturnedByteCount;
- return DeviceIoControl(
- hDisk,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- lpGeometry,
- sizeof(*lpGeometry),
- &ReturnedByteCount,
- NULL
- );
- }
- DWORD
- GetSupportedGeometrys(
- HANDLE hDisk
- )
- {
- DWORD ReturnedByteCount;
- BOOL b;
- DWORD NumberSupported;
- b = DeviceIoControl(
- hDisk,
- IOCTL_DISK_GET_MEDIA_TYPES,
- NULL,
- 0,
- SupportedGeometry,
- sizeof(SupportedGeometry),
- &ReturnedByteCount,
- NULL
- );
- if ( b ) {
- NumberSupported = ReturnedByteCount / sizeof(DISK_GEOMETRY);
- }
- else {
- NumberSupported = 0;
- }
- SupportedGeometryCount = NumberSupported;
- return NumberSupported;
- }
- VOID
- PrintGeometry(
- LPSTR lpDriveName,
- PDISK_GEOMETRY lpGeometry
- )
- {
- LPSTR MediaType;
- if (lpDriveName) {
- printf("Geometry for Drive %sn",lpDriveName);
- }
- switch ( lpGeometry->MediaType ) {
- case F5_1Pt2_512: MediaType = "5.25, 1.2MB, 512 bytes/sector";break;
- case F3_1Pt44_512: MediaType = "3.5, 1.44MB, 512 bytes/sector";break;
- case F3_2Pt88_512: MediaType = "3.5, 2.88MB, 512 bytes/sector";break;
- case F3_20Pt8_512: MediaType = "3.5, 20.8MB, 512 bytes/sector";break;
- case F3_720_512: MediaType = "3.5, 720KB, 512 bytes/sector";break;
- case F5_360_512: MediaType = "5.25, 360KB, 512 bytes/sector";break;
- case F5_320_512: MediaType = "5.25, 320KB, 512 bytes/sector";break;
- case F5_320_1024: MediaType = "5.25, 320KB, 1024 bytes/sector";break;
- case F5_180_512: MediaType = "5.25, 180KB, 512 bytes/sector";break;
- case F5_160_512: MediaType = "5.25, 160KB, 512 bytes/sector";break;
- case RemovableMedia: MediaType = "Removable media other than floppy";break;
- case FixedMedia: MediaType = "Fixed hard disk media";break;
- default: MediaType = "Unknown";break;
- }
- printf(" Media Type %sn",MediaType);
- printf(" Cylinders %d Tracks/Cylinder %d Sectors/Track %dn",
- lpGeometry->Cylinders.LowPart,
- lpGeometry->TracksPerCylinder,
- lpGeometry->SectorsPerTrack
- );
- }
- BOOL
- LowLevelFormat(
- HANDLE hDisk,
- PDISK_GEOMETRY lpGeometry
- )
- {
- FORMAT_PARAMETERS FormatParameters;
- PBAD_TRACK_NUMBER lpBadTrack;
- UINT i;
- BOOL b;
- DWORD ReturnedByteCount;
- FormatParameters.MediaType = lpGeometry->MediaType;
- FormatParameters.StartHeadNumber = 0;
- FormatParameters.EndHeadNumber = lpGeometry->TracksPerCylinder - 1;
- lpBadTrack = (PBAD_TRACK_NUMBER) LocalAlloc(LMEM_ZEROINIT,lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack));
- for (i = 0; i < lpGeometry->Cylinders.LowPart; i++) {
- FormatParameters.StartCylinderNumber = i;
- FormatParameters.EndCylinderNumber = i;
- b = DeviceIoControl(
- hDisk,
- IOCTL_DISK_FORMAT_TRACKS,
- &FormatParameters,
- sizeof(FormatParameters),
- lpBadTrack,
- lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack),
- &ReturnedByteCount,
- NULL
- );
- if (!b ) {
- LocalFree(lpBadTrack);
- return b;
- }
- }
- LocalFree(lpBadTrack);
- return TRUE;
- }
- BOOL
- LockVolume(
- HANDLE hDisk
- )
- {
- DWORD ReturnedByteCount;
- return DeviceIoControl(
- hDisk,
- FSCTL_LOCK_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &ReturnedByteCount,
- NULL
- );
- }
- BOOL
- UnlockVolume(
- HANDLE hDisk
- )
- {
- DWORD ReturnedByteCount;
- return DeviceIoControl(
- hDisk,
- FSCTL_UNLOCK_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &ReturnedByteCount,
- NULL
- );
- }
- BOOL
- DismountVolume(
- HANDLE hDisk
- )
- {
- DWORD ReturnedByteCount;
- return DeviceIoControl(
- hDisk,
- FSCTL_DISMOUNT_VOLUME,
- NULL,
- 0,
- NULL,
- 0,
- &ReturnedByteCount,
- NULL
- );
- }
- DWORD
- _cdecl
- main(
- int argc,
- char *argv[],
- char *envp[]
- )
- {
- char Drive[MAX_PATH];
- HANDLE hDrive, hDiskImage;
- DISK_GEOMETRY Geometry;
- UINT i;
- char c, *p;
- LPSTR DriveName;
- BOOL fUsage = TRUE;
- BOOL fShowGeometry = FALSE;
- BOOL fDiskImage = FALSE;
- BOOL SourceIsDrive;
- LPSTR Source, Destination, DiskImage;
- if ( argc > 1 ) {
- fUsage = FALSE;
- while (--argc > 0 ) {
- p = *++argv;
- if (*p == '/' || *p == '-') {
- while (c = *++p)
- switch (toupper( c )) {
- case '?':
- fUsage = TRUE;
- break;
- case 'C':
- fDiskImage = TRUE;
- argc--, argv++;
- Source = *argv;
- argc--, argv++;
- Destination = *argv;
- break;
- case 'G':
- argc--, argv++;
- if ( (DriveName = *argv ) && *DriveName &&
- isalpha(*DriveName) )
- fShowGeometry = TRUE;
- else
- {
- printf( "MFMT: Missing drive letter after -Gn" );
- DriveName = NULL;
- fUsage = TRUE;
- }
- break;
- default:
- printf("MFMT: Invalid switch - /%cn", c );
- fUsage = TRUE;
- break;
- }
- }
- }
- }
- if ( fUsage ) {
- printf("usage: MFMT switches n" );
- printf(" [-?] display this messagen" );
- printf(" [-g drive] shows disk geometryn" );
- printf(" [-c source destination] produce diskimagen" );
- ExitProcess(1);
- }
- if ( fShowGeometry ) {
- sprintf(Drive,"\\.\%s",DriveName);
- hDrive = CreateFile(
- Drive,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- );
- if ( hDrive == INVALID_HANDLE_VALUE ) {
- printf("MFMT: Open %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- if ( LockVolume(hDrive) == FALSE ) {
- printf("MFMT:Locking volume %s failed %dn", DriveName, GetLastError());
- ExitProcess(1);
- }
- if ( !GetDiskGeometry(hDrive,&Geometry) ) {
- printf("MFMT: GetDiskGeometry %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- PrintGeometry(DriveName,&Geometry);
- if ( !GetSupportedGeometrys(hDrive) ) {
- printf("MFMT: GetSupportedGeometrys %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- printf("nDrive %s supports the following disk geometriesn",DriveName);
- for(i=0;i<SupportedGeometryCount;i++) {
- printf("n");
- PrintGeometry(NULL,&SupportedGeometry[i]);
- }
- printf("n");
- ExitProcess(0);
- }
- if ( fDiskImage ) {
- SourceIsDrive = FALSE;
- if ( Source[strlen(Source)-1] == ':' ) {
- SourceIsDrive = TRUE;
- sprintf(Drive,"\\.\%s",Source);
- DriveName=Source;
- DiskImage = Destination;
- }
- if ( Destination[strlen(Destination)-1] == ':' ) {
- if ( SourceIsDrive ) {
- printf("MFMT: Source and Destination cannot both be drivesn");
- ExitProcess(1);
- }
- SourceIsDrive = FALSE;
- sprintf(Drive,"\\.\%s",Destination);
- DriveName=Destination;
- DiskImage = Source;
- }
- else {
- if ( !SourceIsDrive ) {
- printf("MFMT: Either Source or Destination must be a driven");
- ExitProcess(1);
- }
- }
- //
- // Open and Lock the drive
- //
- hDrive = CreateFile(
- Drive,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- );
- if ( hDrive == INVALID_HANDLE_VALUE ) {
- printf("MFMT: Open %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- if ( LockVolume(hDrive) == FALSE ) {
- printf("MFMT: LockVolume %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- if ( !GetDiskGeometry(hDrive,&Geometry) ) {
- printf("MFMT: GetDiskGeometry %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- if ( !GetSupportedGeometrys(hDrive) ) {
- printf("MFMT: GetSupportedGeometrys %s failed %dn",DriveName,GetLastError());
- ExitProcess(1);
- }
- //
- // Open the disk image file
- //
- hDiskImage = CreateFile(
- DiskImage,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- SourceIsDrive ? CREATE_ALWAYS : OPEN_EXISTING,
- 0,
- NULL
- );
- if ( hDiskImage == INVALID_HANDLE_VALUE ) {
- printf("MFMT: Open %s failed %dn",DiskImage,GetLastError());
- ExitProcess(1);
- }
- //
- // Now do the copy
- //
- {
- LPVOID IoBuffer;
- BOOL b;
- DWORD BytesRead, BytesWritten;
- DWORD FileSize;
- DWORD VirtBufSize;
- DWORD NumBufs;
- //
- // If we are copying from floppy to file, just do the copy
- // Otherwise, we might have to format the floppy first
- //
- if ( SourceIsDrive ) {
- //
- // Device reads must be sector aligned. VirtualAlloc will
- // garuntee alignment
- //
- NumBufs = Geometry.Cylinders.LowPart;
- VirtBufSize = Geometry.TracksPerCylinder *
- Geometry.SectorsPerTrack *
- Geometry.BytesPerSector;
- IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);
- if ( !IoBuffer ) {
- printf("MFMT: Buffer Allocation Failedn");
- ExitProcess(1);
- }
- for ( ;NumBufs > 0; NumBufs-- )
- {
- b = ReadFile(hDrive,IoBuffer, VirtBufSize, &BytesRead, NULL);
- if (b && BytesRead){
- b = WriteFile(hDiskImage,IoBuffer, BytesRead, &BytesWritten, NULL);
- if ( !b || ( BytesRead != BytesWritten ) ) {
- printf("MFMT: Fatal Write Error %dn",GetLastError());
- ExitProcess(1);
- }
- }
- else {
- printf("MFMT: Fatal Read Error %dn",GetLastError());
- ExitProcess(1);
- }
- }
- }
- else {
- //
- // Check to see if the image will fit on the floppy. If it
- // will, then LowLevelFormat the floppy and press on
- //
- FileSize = GetFileSize(hDiskImage,NULL);
- b = FALSE;
- for(i=0;i<SupportedGeometryCount;i++) {
- NumBufs = SupportedGeometry[i].Cylinders.LowPart;
- VirtBufSize = SupportedGeometry[i].TracksPerCylinder *
- SupportedGeometry[i].SectorsPerTrack *
- SupportedGeometry[i].BytesPerSector;
- if ( VirtBufSize*NumBufs >= FileSize ) {
- IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);
- if ( !IoBuffer ) {
- printf("MFMT: Buffer Allocation Failedn");
- ExitProcess(1);
- }
- //
- // Format the floppy
- //
- LowLevelFormat(hDrive,&SupportedGeometry[i]);
- for ( ;NumBufs > 0; NumBufs-- )
- {
- b = ReadFile(hDiskImage,IoBuffer, VirtBufSize, &BytesRead, NULL);
- if (b && BytesRead){
- b = WriteFile(hDrive,IoBuffer, BytesRead, &BytesWritten, NULL);
- if ( !b || ( BytesRead != BytesWritten ) ) {
- printf("MFMT: Fatal Write Error %dn",GetLastError());
- ExitProcess(1);
- }
- }
- else {
- printf("MFMT: Fatal Read Error %dn",GetLastError());
- ExitProcess(1);
- }
- }
- b = TRUE;
- break;
- }
- }
- if ( !b ) {
- printf("MFMT: FileSize %d is not supported on drive %sn",FileSize,DriveName);
- ExitProcess(1);
- }
- }
- }
- //
- // Dismounting forces the filesystem to re-evaluate the media id
- // and geometry. This is the same as popping the floppy in and out
- // of the disk drive
- //
- DismountVolume(hDrive);
- UnlockVolume(hDrive);
- ExitProcess(0);
- }
- return (0);
- }