Annotation of mstools/samples/floppy/mfmt.c, revision 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.