Annotation of mstools/samples/floppy/mfmt.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.