MFMT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:17k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. /*++
  11. Module Name:
  12.     mfmt.c
  13. Abstract:
  14.     This program is designed to show how to access a physical floppy
  15.     disk using the Win32 API set.
  16.     This program has two major functions.
  17.         - It can be used to display the geometry of a disk
  18.             mfmt -g a:
  19.         - It can be used to produce a disk image, or to write a disk
  20.           image to a floppy.
  21.             mfmt -c a: bootdisk         - produce a disk image of a:
  22.             mfmt -c bootdisk a:         - make a: identical to bootdisk image
  23.     This program is very very simple. Minimal error checking is done. It is
  24.     meant to provide an example of how to:
  25.         - Open a physical disk
  26.         - Read a disk's geometry
  27.         - Perform a low level format operation
  28.         - read and write physical sectors
  29. --*/
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <windows.h>
  33. #include <winioctl.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <memory.h>
  37. DISK_GEOMETRY SupportedGeometry[20];
  38. DWORD SupportedGeometryCount;
  39. BOOL
  40. GetDiskGeometry(
  41.     HANDLE hDisk,
  42.     PDISK_GEOMETRY lpGeometry
  43.     )
  44. {
  45.     DWORD ReturnedByteCount;
  46.     return DeviceIoControl(
  47.                 hDisk,
  48.                 IOCTL_DISK_GET_DRIVE_GEOMETRY,
  49.                 NULL,
  50.                 0,
  51.                 lpGeometry,
  52.                 sizeof(*lpGeometry),
  53.                 &ReturnedByteCount,
  54.                 NULL
  55.                 );
  56. }
  57. DWORD
  58. GetSupportedGeometrys(
  59.     HANDLE hDisk
  60.     )
  61. {
  62.     DWORD ReturnedByteCount;
  63.     BOOL b;
  64.     DWORD NumberSupported;
  65.     b = DeviceIoControl(
  66.                 hDisk,
  67.                 IOCTL_DISK_GET_MEDIA_TYPES,
  68.                 NULL,
  69.                 0,
  70.                 SupportedGeometry,
  71.                 sizeof(SupportedGeometry),
  72.                 &ReturnedByteCount,
  73.                 NULL
  74.                 );
  75.     if ( b ) {
  76.         NumberSupported = ReturnedByteCount / sizeof(DISK_GEOMETRY);
  77.         }
  78.     else {
  79.         NumberSupported = 0;
  80.         }
  81.     SupportedGeometryCount = NumberSupported;
  82.     return NumberSupported;
  83. }
  84. VOID
  85. PrintGeometry(
  86.     LPSTR lpDriveName,
  87.     PDISK_GEOMETRY lpGeometry
  88.     )
  89. {
  90.     LPSTR MediaType;
  91.     if (lpDriveName) {
  92.         printf("Geometry for Drive %sn",lpDriveName);
  93.         }
  94.     switch ( lpGeometry->MediaType ) {
  95.         case F5_1Pt2_512:  MediaType = "5.25, 1.2MB,  512 bytes/sector";break;
  96.         case F3_1Pt44_512: MediaType = "3.5,  1.44MB, 512 bytes/sector";break;
  97.         case F3_2Pt88_512: MediaType = "3.5,  2.88MB, 512 bytes/sector";break;
  98.         case F3_20Pt8_512: MediaType = "3.5,  20.8MB, 512 bytes/sector";break;
  99.         case F3_720_512:   MediaType = "3.5,  720KB,  512 bytes/sector";break;
  100.         case F5_360_512:   MediaType = "5.25, 360KB,  512 bytes/sector";break;
  101.         case F5_320_512:   MediaType = "5.25, 320KB,  512 bytes/sector";break;
  102.         case F5_320_1024:  MediaType = "5.25, 320KB,  1024 bytes/sector";break;
  103.         case F5_180_512:   MediaType = "5.25, 180KB,  512 bytes/sector";break;
  104.         case F5_160_512:   MediaType = "5.25, 160KB,  512 bytes/sector";break;
  105.         case RemovableMedia: MediaType = "Removable media other than floppy";break;
  106.         case FixedMedia:   MediaType = "Fixed hard disk media";break;
  107.         default:           MediaType = "Unknown";break;
  108.     }
  109.     printf("    Media Type %sn",MediaType);
  110.     printf("    Cylinders %d Tracks/Cylinder %d Sectors/Track %dn",
  111.         lpGeometry->Cylinders.LowPart,
  112.         lpGeometry->TracksPerCylinder,
  113.         lpGeometry->SectorsPerTrack
  114.         );
  115. }
  116. BOOL
  117. LowLevelFormat(
  118.     HANDLE hDisk,
  119.     PDISK_GEOMETRY lpGeometry
  120.     )
  121. {
  122.     FORMAT_PARAMETERS FormatParameters;
  123.     PBAD_TRACK_NUMBER lpBadTrack;
  124.     UINT i;
  125.     BOOL b;
  126.     DWORD ReturnedByteCount;
  127.     FormatParameters.MediaType = lpGeometry->MediaType;
  128.     FormatParameters.StartHeadNumber = 0;
  129.     FormatParameters.EndHeadNumber = lpGeometry->TracksPerCylinder - 1;
  130.     lpBadTrack = (PBAD_TRACK_NUMBER) LocalAlloc(LMEM_ZEROINIT,lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack));
  131.     for (i = 0; i < lpGeometry->Cylinders.LowPart; i++) {
  132.         FormatParameters.StartCylinderNumber = i;
  133.         FormatParameters.EndCylinderNumber = i;
  134.         b = DeviceIoControl(
  135.                 hDisk,
  136.                 IOCTL_DISK_FORMAT_TRACKS,
  137.                 &FormatParameters,
  138.                 sizeof(FormatParameters),
  139.                 lpBadTrack,
  140.                 lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack),
  141.                 &ReturnedByteCount,
  142.                 NULL
  143.                 );
  144.         if (!b ) {
  145.             LocalFree(lpBadTrack);
  146.             return b;
  147.             }
  148.         }
  149.     LocalFree(lpBadTrack);
  150.     return TRUE;
  151. }
  152. BOOL
  153. LockVolume(
  154.     HANDLE hDisk
  155.     )
  156. {
  157.     DWORD ReturnedByteCount;
  158.     return DeviceIoControl(
  159.                 hDisk,
  160.                 FSCTL_LOCK_VOLUME,
  161.                 NULL,
  162.                 0,
  163.                 NULL,
  164.                 0,
  165.                 &ReturnedByteCount,
  166.                 NULL
  167.                 );
  168. }
  169. BOOL
  170. UnlockVolume(
  171.     HANDLE hDisk
  172.     )
  173. {
  174.     DWORD ReturnedByteCount;
  175.     return DeviceIoControl(
  176.                 hDisk,
  177.                 FSCTL_UNLOCK_VOLUME,
  178.                 NULL,
  179.                 0,
  180.                 NULL,
  181.                 0,
  182.                 &ReturnedByteCount,
  183.                 NULL
  184.                 );
  185. }
  186. BOOL
  187. DismountVolume(
  188.     HANDLE hDisk
  189.     )
  190. {
  191.     DWORD ReturnedByteCount;
  192.     return DeviceIoControl(
  193.                 hDisk,
  194.                 FSCTL_DISMOUNT_VOLUME,
  195.                 NULL,
  196.                 0,
  197.                 NULL,
  198.                 0,
  199.                 &ReturnedByteCount,
  200.                 NULL
  201.                 );
  202. }
  203. DWORD
  204. _cdecl
  205. main(
  206.     int argc,
  207.     char *argv[],
  208.     char *envp[]
  209.     )
  210. {
  211.     char Drive[MAX_PATH];
  212.     HANDLE hDrive, hDiskImage;
  213.     DISK_GEOMETRY Geometry;
  214.     UINT i;
  215.     char c, *p;
  216.     LPSTR DriveName;
  217.     BOOL fUsage = TRUE;
  218.     BOOL fShowGeometry = FALSE;
  219.     BOOL fDiskImage = FALSE;
  220.     BOOL SourceIsDrive;
  221.     LPSTR Source, Destination, DiskImage;
  222.     if ( argc > 1 ) {
  223.         fUsage = FALSE;
  224.         while (--argc > 0 ) {
  225.             p = *++argv;
  226.             if (*p == '/' || *p == '-') {
  227.                 while (c = *++p)
  228.                 switch (toupper( c )) {
  229.                 case '?':
  230.                     fUsage = TRUE;
  231.                     break;
  232.                 case 'C':
  233.                     fDiskImage = TRUE;
  234.                     argc--, argv++;
  235.                     Source = *argv;
  236.                     argc--, argv++;
  237.                     Destination = *argv;
  238.                     break;
  239.                 case 'G':
  240.                     argc--, argv++;
  241.                     if ( (DriveName = *argv ) && *DriveName && 
  242.                          isalpha(*DriveName) )
  243.                         fShowGeometry = TRUE;
  244.                     else
  245.                                                 {
  246.                         printf( "MFMT: Missing drive letter after -Gn" );
  247.                                     DriveName = NULL;
  248.                         fUsage = TRUE;
  249.                         }
  250.                             break;
  251.                 default:
  252.                     printf("MFMT: Invalid switch - /%cn", c );
  253.                     fUsage = TRUE;
  254.                     break;
  255.                     }
  256.                 }
  257.             }
  258.         }
  259.     if ( fUsage ) {
  260.         printf("usage: MFMT switches n" );
  261.         printf("            [-?] display this messagen" );
  262.         printf("            [-g drive] shows disk geometryn" );
  263.         printf("            [-c source destination] produce diskimagen" );
  264.         ExitProcess(1);
  265.         }
  266.     if ( fShowGeometry ) {
  267.         sprintf(Drive,"\\.\%s",DriveName);
  268.         hDrive = CreateFile(
  269.                     Drive,
  270.                     GENERIC_READ | GENERIC_WRITE,
  271.                     FILE_SHARE_READ|FILE_SHARE_WRITE,
  272.                     NULL,
  273.                     OPEN_EXISTING,
  274.                     0,
  275.                     NULL
  276.                     );
  277.         if ( hDrive == INVALID_HANDLE_VALUE ) {
  278.             printf("MFMT: Open %s failed %dn",DriveName,GetLastError());
  279.             ExitProcess(1);
  280.             }
  281.         if ( LockVolume(hDrive) == FALSE ) {
  282.             printf("MFMT:Locking volume %s failed %dn", DriveName, GetLastError());
  283.             ExitProcess(1);
  284.             }
  285.         if ( !GetDiskGeometry(hDrive,&Geometry) ) {
  286.             printf("MFMT: GetDiskGeometry %s failed %dn",DriveName,GetLastError());
  287.             ExitProcess(1);
  288.             }
  289.         PrintGeometry(DriveName,&Geometry);
  290.         if ( !GetSupportedGeometrys(hDrive) ) {
  291.             printf("MFMT: GetSupportedGeometrys %s failed %dn",DriveName,GetLastError());
  292.             ExitProcess(1);
  293.             }
  294.         printf("nDrive %s supports the following disk geometriesn",DriveName);
  295.         for(i=0;i<SupportedGeometryCount;i++) {
  296.             printf("n");
  297.             PrintGeometry(NULL,&SupportedGeometry[i]);
  298.             }
  299.         printf("n");
  300.         ExitProcess(0);
  301.         }
  302.     if ( fDiskImage ) {
  303.         SourceIsDrive = FALSE;
  304.         if ( Source[strlen(Source)-1] == ':' ) {
  305.             SourceIsDrive = TRUE;
  306.             sprintf(Drive,"\\.\%s",Source);
  307.             DriveName=Source;
  308.             DiskImage = Destination;
  309.             }
  310.         if ( Destination[strlen(Destination)-1] == ':' ) {
  311.             if ( SourceIsDrive ) {
  312.                 printf("MFMT: Source and Destination cannot both be drivesn");
  313.                 ExitProcess(1);
  314.                 }
  315.             SourceIsDrive = FALSE;
  316.             sprintf(Drive,"\\.\%s",Destination);
  317.             DriveName=Destination;
  318.             DiskImage = Source;
  319.             }
  320.         else {
  321.             if ( !SourceIsDrive ) {
  322.                 printf("MFMT: Either Source or Destination must be a driven");
  323.                 ExitProcess(1);
  324.                 }
  325.             }
  326.         //
  327.         // Open and Lock the drive
  328.         //
  329.         hDrive = CreateFile(
  330.                     Drive,
  331.                     GENERIC_READ | GENERIC_WRITE,
  332.                     FILE_SHARE_READ|FILE_SHARE_WRITE,
  333.                     NULL,
  334.                     OPEN_EXISTING,
  335.                     0,
  336.                     NULL
  337.                     );
  338.         if ( hDrive == INVALID_HANDLE_VALUE ) {
  339.             printf("MFMT: Open %s failed %dn",DriveName,GetLastError());
  340.             ExitProcess(1);
  341.             }
  342.         if ( LockVolume(hDrive) == FALSE ) {
  343.             printf("MFMT: LockVolume %s failed %dn",DriveName,GetLastError());
  344.             ExitProcess(1);
  345.             }
  346.         if ( !GetDiskGeometry(hDrive,&Geometry) ) {
  347.             printf("MFMT: GetDiskGeometry %s failed %dn",DriveName,GetLastError());
  348.             ExitProcess(1);
  349.             }
  350.         if ( !GetSupportedGeometrys(hDrive) ) {
  351.             printf("MFMT: GetSupportedGeometrys %s failed %dn",DriveName,GetLastError());
  352.             ExitProcess(1);
  353.             }
  354.         //
  355.         // Open the disk image file
  356.         //
  357.         hDiskImage = CreateFile(
  358.                         DiskImage,
  359.                         GENERIC_READ | GENERIC_WRITE,
  360.                         0,
  361.                         NULL,
  362.                         SourceIsDrive ? CREATE_ALWAYS : OPEN_EXISTING,
  363.                         0,
  364.                         NULL
  365.                         );
  366.         if ( hDiskImage == INVALID_HANDLE_VALUE ) {
  367.             printf("MFMT: Open %s failed %dn",DiskImage,GetLastError());
  368.             ExitProcess(1);
  369.             }
  370.         //
  371.         // Now do the copy
  372.         //
  373.         {
  374.             LPVOID IoBuffer;
  375.             BOOL b;
  376.             DWORD BytesRead, BytesWritten;
  377.             DWORD FileSize;
  378.             DWORD VirtBufSize;
  379.             DWORD NumBufs;
  380.             //
  381.             // If we are copying from floppy to file, just do the copy
  382.             // Otherwise, we might have to format the floppy first
  383.             //
  384.             if ( SourceIsDrive ) {
  385.                 //
  386.                 // Device reads must be sector aligned. VirtualAlloc will
  387.                 // garuntee alignment
  388.                 //
  389.                 NumBufs = Geometry.Cylinders.LowPart;
  390.                 VirtBufSize =  Geometry.TracksPerCylinder *
  391.                                Geometry.SectorsPerTrack *
  392.                                Geometry.BytesPerSector;
  393.                 IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);
  394.                 if ( !IoBuffer ) {
  395.                     printf("MFMT: Buffer Allocation Failedn");
  396.                     ExitProcess(1);
  397.                     }
  398.                 for ( ;NumBufs > 0; NumBufs-- )
  399.                     {
  400.                     b = ReadFile(hDrive,IoBuffer, VirtBufSize, &BytesRead, NULL);
  401.                     if (b && BytesRead){
  402.                         b = WriteFile(hDiskImage,IoBuffer, BytesRead, &BytesWritten, NULL);
  403.                         if ( !b || ( BytesRead != BytesWritten ) ) {
  404.                             printf("MFMT: Fatal Write Error %dn",GetLastError());
  405.                             ExitProcess(1);
  406.                             }
  407.                         }
  408.                     else {
  409.                         printf("MFMT: Fatal Read Error %dn",GetLastError());
  410.                         ExitProcess(1);
  411.                         }
  412.                     }
  413.                 }
  414.             else {
  415.                 //
  416.                 // Check to see if the image will fit on the floppy. If it
  417.                 // will, then LowLevelFormat the floppy and press on
  418.                 //
  419.                 FileSize = GetFileSize(hDiskImage,NULL);
  420.                 b = FALSE;
  421.                 for(i=0;i<SupportedGeometryCount;i++) {
  422.                     NumBufs = SupportedGeometry[i].Cylinders.LowPart;
  423.                     VirtBufSize =  SupportedGeometry[i].TracksPerCylinder *
  424.                                    SupportedGeometry[i].SectorsPerTrack *
  425.                                    SupportedGeometry[i].BytesPerSector;
  426.                     if ( VirtBufSize*NumBufs >= FileSize ) {
  427.                         IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);
  428.                         if ( !IoBuffer ) {
  429.                             printf("MFMT: Buffer Allocation Failedn");
  430.                             ExitProcess(1);
  431.                             }
  432.                         //
  433.                         // Format the floppy
  434.                         //
  435.                         LowLevelFormat(hDrive,&SupportedGeometry[i]);
  436.                         for ( ;NumBufs > 0; NumBufs-- )
  437.                             {
  438.                             b = ReadFile(hDiskImage,IoBuffer, VirtBufSize, &BytesRead, NULL);
  439.                             if (b && BytesRead){
  440.                                 b = WriteFile(hDrive,IoBuffer, BytesRead, &BytesWritten, NULL);
  441.                                 if ( !b || ( BytesRead != BytesWritten ) ) {
  442.                                     printf("MFMT: Fatal Write Error %dn",GetLastError());
  443.                                     ExitProcess(1);
  444.                                     }
  445.                                 }
  446.                             else {
  447.                                 printf("MFMT: Fatal Read Error %dn",GetLastError());
  448.                                 ExitProcess(1);
  449.                                 }
  450.                             }
  451.                         b = TRUE;
  452.                         break;
  453.                      }
  454.                     }
  455.                 if ( !b ) {
  456.                     printf("MFMT: FileSize %d is not supported on drive %sn",FileSize,DriveName);
  457.                     ExitProcess(1);
  458.                     }
  459.                 }
  460.         }
  461.         //
  462.         // Dismounting forces the filesystem to re-evaluate the media id
  463.         // and geometry. This is the same as popping the floppy in and out
  464.         // of the disk drive
  465.         //
  466.         DismountVolume(hDrive);
  467.         UnlockVolume(hDrive);
  468.         ExitProcess(0);
  469.         }
  470.     return (0);
  471. }