|
|
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.