|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.