4 Virtual Floppy Drive for Windows NT platform
5 Kernel mode driver: disk format functions
7 Copyright (C) 2003-2005 Ken Kato
15 #pragma alloc_text(PAGE, VfdFormatCheck)
16 #pragma alloc_text(PAGE, VfdFormatTrack)
17 #endif // ALLOC_PRAGMA
20 // Media geometry constant table
22 // MediaTypes values added since Win NT DDK
24 #define F3_640_512 (MEDIA_TYPE)14
27 #define F3_1Pt2_512 (MEDIA_TYPE)17
31 extern DISK_GEOMETRY
const geom_tbl
[VFD_MEDIA_MAX
] = {
32 {{ 80 }, F3_1Pt44_512
, 2, 18, VFD_BYTES_PER_SECTOR
}, // default
33 {{ 40 }, F5_160_512
, 1, 8, VFD_BYTES_PER_SECTOR
}, // 160K
34 {{ 40 }, F5_180_512
, 1, 9, VFD_BYTES_PER_SECTOR
}, // 180K
35 {{ 40 }, F5_320_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 320K
36 {{ 40 }, F5_360_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 360K
37 {{ 80 }, F3_640_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 640k
38 {{ 80 }, F5_640_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 640k
39 {{ 80 }, F3_720_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 720K
40 {{ 80 }, F5_720_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 720K
41 {{ 82 }, RemovableMedia
, 2, 10, VFD_BYTES_PER_SECTOR
}, // 820K
42 {{ 80 }, F3_1Pt2_512
, 2, 15, VFD_BYTES_PER_SECTOR
}, // 1200K
43 {{ 80 }, F5_1Pt2_512
, 2, 15, VFD_BYTES_PER_SECTOR
}, // 1200K
44 {{ 80 }, F3_1Pt44_512
, 2, 18, VFD_BYTES_PER_SECTOR
}, // 1440K
45 {{ 80 }, RemovableMedia
, 2, 21, VFD_BYTES_PER_SECTOR
}, // 1680K DMF
46 {{ 82 }, RemovableMedia
, 2, 21, VFD_BYTES_PER_SECTOR
}, // 1720K DMF
47 {{ 80 }, F3_2Pt88_512
, 2, 36, VFD_BYTES_PER_SECTOR
}, // 2880K
49 DISK_GEOMETRY
const geom_tbl
[VFD_MEDIA_MAX
] = {
50 {{ {80} }, F3_1Pt44_512
, 2, 18, VFD_BYTES_PER_SECTOR
}, // default
51 {{ {40} }, F5_160_512
, 1, 8, VFD_BYTES_PER_SECTOR
}, // 160K
52 {{ {40} }, F5_180_512
, 1, 9, VFD_BYTES_PER_SECTOR
}, // 180K
53 {{ {40} }, F5_320_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 320K
54 {{ {40} }, F5_360_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 360K
55 {{ {80} }, F3_640_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 640k
56 {{ {80} }, F5_640_512
, 2, 8, VFD_BYTES_PER_SECTOR
}, // 640k
57 {{ {80} }, F3_720_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 720K
58 {{ {80} }, F5_720_512
, 2, 9, VFD_BYTES_PER_SECTOR
}, // 720K
59 {{ {82} }, RemovableMedia
, 2, 10, VFD_BYTES_PER_SECTOR
}, // 820K
60 {{ {80} }, F3_1Pt2_512
, 2, 15, VFD_BYTES_PER_SECTOR
}, // 1200K
61 {{ {80} }, F5_1Pt2_512
, 2, 15, VFD_BYTES_PER_SECTOR
}, // 1200K
62 {{ {80} }, F3_1Pt44_512
, 2, 18, VFD_BYTES_PER_SECTOR
}, // 1440K
63 {{ {80} }, RemovableMedia
, 2, 21, VFD_BYTES_PER_SECTOR
}, // 1680K DMF
64 {{ {82} }, RemovableMedia
, 2, 21, VFD_BYTES_PER_SECTOR
}, // 1720K DMF
65 {{ {80} }, F3_2Pt88_512
, 2, 36, VFD_BYTES_PER_SECTOR
}, // 2880K
70 // Parameter check for IOCTL_DISK_FORMAT_TRACK and IOCTL_DISK_FORMAT_TRACK_EX
74 PDEVICE_EXTENSION DeviceExtension
,
75 PFORMAT_PARAMETERS FormatParams
,
79 const DISK_GEOMETRY
*geometry
;
83 if (!DeviceExtension
->FileHandle
&&
84 !DeviceExtension
->FileBuffer
) {
85 return STATUS_NO_MEDIA_IN_DEVICE
;
90 if (DeviceExtension
->MediaFlags
& VFD_FLAG_WRITE_PROTECTED
) {
91 return STATUS_MEDIA_WRITE_PROTECTED
;
94 // Check input parameter size
96 if (InputLength
< sizeof(FORMAT_PARAMETERS
)) {
97 return STATUS_INVALID_PARAMETER
;
100 // Choose appropriate DISK_GEOMETRY for current image size
102 geometry
= DeviceExtension
->Geometry
;
105 return STATUS_DRIVER_INTERNAL_ERROR
;
108 // Input parameter sanity check
110 if ((FormatParams
->StartHeadNumber
> geometry
->TracksPerCylinder
- 1) ||
111 (FormatParams
->EndHeadNumber
> geometry
->TracksPerCylinder
- 1) ||
112 (FormatParams
->StartCylinderNumber
> geometry
->Cylinders
.LowPart
) ||
113 (FormatParams
->EndCylinderNumber
> geometry
->Cylinders
.LowPart
) ||
114 (FormatParams
->EndCylinderNumber
< FormatParams
->StartCylinderNumber
))
116 return STATUS_INVALID_PARAMETER
;
119 // If this is an EX request then make a couple of extra checks
121 if (ControlCode
== IOCTL_DISK_FORMAT_TRACKS_EX
) {
123 PFORMAT_EX_PARAMETERS exparams
;
125 if (InputLength
< sizeof(FORMAT_EX_PARAMETERS
)) {
126 return STATUS_INVALID_PARAMETER
;
129 exparams
= (PFORMAT_EX_PARAMETERS
)FormatParams
;
132 FIELD_OFFSET(FORMAT_EX_PARAMETERS
, SectorNumber
) +
133 exparams
->SectorsPerTrack
* sizeof(USHORT
))
135 return STATUS_INVALID_PARAMETER
;
138 if (exparams
->FormatGapLength
> geometry
->SectorsPerTrack
||
139 exparams
->SectorsPerTrack
!= geometry
->SectorsPerTrack
)
141 return STATUS_INVALID_PARAMETER
;
145 return STATUS_SUCCESS
;
150 // Actually, just fills specified range of tracks with fill characters
154 IN PDEVICE_EXTENSION DeviceExtension
,
155 IN PFORMAT_PARAMETERS FormatParams
)
157 const DISK_GEOMETRY
*geometry
;
159 PUCHAR format_buffer
;
160 LARGE_INTEGER start_offset
;
161 LARGE_INTEGER end_offset
;
164 VFDTRACE(0, ("[VFD] VfdFormatTrack - IN\n"));
166 ASSERT(DeviceExtension
!= NULL
);
168 geometry
= DeviceExtension
->Geometry
;
171 return STATUS_DRIVER_INTERNAL_ERROR
;
174 track_length
= geometry
->BytesPerSector
* geometry
->SectorsPerTrack
;
176 format_buffer
= (PUCHAR
)ExAllocatePoolWithTag(
177 PagedPool
, track_length
, VFD_POOL_TAG
);
179 if (format_buffer
== NULL
) {
180 VFDTRACE(0, ("[VFD] cannot allocate a format buffer\n"));
181 return STATUS_INSUFFICIENT_RESOURCES
;
184 RtlFillMemory(format_buffer
, track_length
, VFD_FORMAT_FILL_DATA
);
186 start_offset
.QuadPart
=
187 FormatParams
->StartCylinderNumber
* geometry
->TracksPerCylinder
* track_length
+
188 FormatParams
->StartHeadNumber
* track_length
;
190 end_offset
.QuadPart
=
191 FormatParams
->EndCylinderNumber
* geometry
->TracksPerCylinder
* track_length
+
192 FormatParams
->EndHeadNumber
* track_length
;
195 if (DeviceExtension
->FileHandle
) {
196 IO_STATUS_BLOCK io_status
;
198 status
= ZwWriteFile(
199 DeviceExtension
->FileHandle
,
209 if (!NT_SUCCESS(status
)) {
210 VFDTRACE(0, ("[VFD] ZwWriteFile - %s\n",
211 GetStatusName(status
)));
217 DeviceExtension
->FileBuffer
+ start_offset
.QuadPart
,
221 status
= STATUS_SUCCESS
;
224 start_offset
.QuadPart
+= track_length
;
226 while (start_offset
.QuadPart
<= end_offset
.QuadPart
);
228 ExFreePool(format_buffer
);
230 VFDTRACE(0, ("[VFD] VfdFormatTrack - OUT\n"));