ReactOS  0.4.14-dev-614-gbfd8a84
vfdfmt.c
Go to the documentation of this file.
1 /*
2  vfdfmt.c
3 
4  Virtual Floppy Drive for Windows NT platform
5  Kernel mode driver: disk format functions
6 
7  Copyright (C) 2003-2005 Ken Kato
8 */
9 
10 #include "imports.h"
11 #include "vfddrv.h"
12 #include "vfddbg.h"
13 
14 #ifdef ALLOC_PRAGMA
15 #pragma alloc_text(PAGE, VfdFormatCheck)
16 #pragma alloc_text(PAGE, VfdFormatTrack)
17 #endif // ALLOC_PRAGMA
18 
19 //
20 // Media geometry constant table
21 //
22 // MediaTypes values added since Win NT DDK
23 #ifndef F3_640_512
24 #define F3_640_512 (MEDIA_TYPE)14
25 #endif
26 #ifndef F3_1Pt2_512
27 #define F3_1Pt2_512 (MEDIA_TYPE)17
28 #endif
29 
30 #ifndef __REACTOS__
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
48 #else
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
66 #endif
67 };
68 
69 //
70 // Parameter check for IOCTL_DISK_FORMAT_TRACK and IOCTL_DISK_FORMAT_TRACK_EX
71 //
74  PDEVICE_EXTENSION DeviceExtension,
75  PFORMAT_PARAMETERS FormatParams,
76  ULONG InputLength,
78 {
79  const DISK_GEOMETRY *geometry;
80 
81  // Check media status
82 
83  if (!DeviceExtension->FileHandle &&
84  !DeviceExtension->FileBuffer) {
86  }
87 
88  // Media is writable?
89 
90  if (DeviceExtension->MediaFlags & VFD_FLAG_WRITE_PROTECTED) {
92  }
93 
94  // Check input parameter size
95 
96  if (InputLength < sizeof(FORMAT_PARAMETERS)) {
98  }
99 
100  // Choose appropriate DISK_GEOMETRY for current image size
101 
102  geometry = DeviceExtension->Geometry;
103 
104  if (!geometry) {
106  }
107 
108  // Input parameter sanity check
109 
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))
115  {
117  }
118 
119  // If this is an EX request then make a couple of extra checks
120 
122 
123  PFORMAT_EX_PARAMETERS exparams;
124 
125  if (InputLength < sizeof(FORMAT_EX_PARAMETERS)) {
127  }
128 
129  exparams = (PFORMAT_EX_PARAMETERS)FormatParams;
130 
131  if (InputLength <
132  FIELD_OFFSET(FORMAT_EX_PARAMETERS, SectorNumber) +
133  exparams->SectorsPerTrack * sizeof(USHORT))
134  {
136  }
137 
138  if (exparams->FormatGapLength > geometry->SectorsPerTrack ||
139  exparams->SectorsPerTrack != geometry->SectorsPerTrack)
140  {
142  }
143  }
144 
145  return STATUS_SUCCESS;
146 }
147 
148 //
149 // Format tracks
150 // Actually, just fills specified range of tracks with fill characters
151 //
152 NTSTATUS
154  IN PDEVICE_EXTENSION DeviceExtension,
155  IN PFORMAT_PARAMETERS FormatParams)
156 {
157  const DISK_GEOMETRY *geometry;
158  ULONG track_length;
159  PUCHAR format_buffer;
160  LARGE_INTEGER start_offset;
161  LARGE_INTEGER end_offset;
163 
164  VFDTRACE(0, ("[VFD] VfdFormatTrack - IN\n"));
165 
166  ASSERT(DeviceExtension != NULL);
167 
168  geometry = DeviceExtension->Geometry;
169 
170  if (!geometry) {
172  }
173 
174  track_length = geometry->BytesPerSector * geometry->SectorsPerTrack;
175 
176  format_buffer = (PUCHAR)ExAllocatePoolWithTag(
177  PagedPool, track_length, VFD_POOL_TAG);
178 
179  if (format_buffer == NULL) {
180  VFDTRACE(0, ("[VFD] cannot allocate a format buffer\n"));
182  }
183 
184  RtlFillMemory(format_buffer, track_length, VFD_FORMAT_FILL_DATA);
185 
186  start_offset.QuadPart =
187  FormatParams->StartCylinderNumber * geometry->TracksPerCylinder * track_length +
188  FormatParams->StartHeadNumber * track_length;
189 
190  end_offset.QuadPart =
191  FormatParams->EndCylinderNumber * geometry->TracksPerCylinder * track_length +
192  FormatParams->EndHeadNumber * track_length;
193 
194  do {
195  if (DeviceExtension->FileHandle) {
197 
198  status = ZwWriteFile(
199  DeviceExtension->FileHandle,
200  NULL,
201  NULL,
202  NULL,
203  &io_status,
204  format_buffer,
205  track_length,
206  &start_offset,
207  NULL);
208 
209  if (!NT_SUCCESS(status)) {
210  VFDTRACE(0, ("[VFD] ZwWriteFile - %s\n",
211  GetStatusName(status)));
212  break;
213  }
214  }
215  else {
217  DeviceExtension->FileBuffer + start_offset.QuadPart,
218  format_buffer,
219  track_length);
220 
222  }
223 
224  start_offset.QuadPart += track_length;
225  }
226  while (start_offset.QuadPart <= end_offset.QuadPart);
227 
228  ExFreePool(format_buffer);
229 
230  VFDTRACE(0, ("[VFD] VfdFormatTrack - OUT\n"));
231 
232  return status;
233 }
#define IN
Definition: typedefs.h:38
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS VfdFormatTrack(IN PDEVICE_EXTENSION DeviceExtension, IN PFORMAT_PARAMETERS FormatParams)
Definition: vfdfmt.c:153
#define VFD_BYTES_PER_SECTOR
Definition: vfdio.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK io_status
Definition: comm.c:54
ULONG BytesPerSector
Definition: ntdddisk.h:381
ULONG TracksPerCylinder
Definition: ntdddisk.h:379
NTSTATUS VfdFormatCheck(PDEVICE_EXTENSION DeviceExtension, PFORMAT_PARAMETERS FormatParams, ULONG InputLength, ULONG ControlCode)
Definition: vfdfmt.c:73
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
_IRQL_requires_same_ typedef _In_ ULONG ControlCode
Definition: wmitypes.h:55
ULONG StartCylinderNumber
Definition: ntdddisk.h:513
#define VFD_FLAG_WRITE_PROTECTED
Definition: vfdtypes.h:68
#define VFD_FORMAT_FILL_DATA
Definition: vfdio.h:51
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:377
ULONG SectorsPerTrack
Definition: ntdddisk.h:380
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
#define F3_1Pt2_512
Definition: vfdfmt.c:27
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
ULONG LowPart
Definition: typedefs.h:104
#define VFD_POOL_TAG
Definition: vfddrv.h:25
unsigned short USHORT
Definition: pedump.c:61
#define F3_640_512
Definition: vfdfmt.c:24
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
DISK_GEOMETRY const geom_tbl[VFD_MEDIA_MAX]
#define IOCTL_DISK_FORMAT_TRACKS_EX
Definition: cdrw_usr.h:173
struct _FORMAT_EX_PARAMETERS * PFORMAT_EX_PARAMETERS
unsigned int ULONG
Definition: retypes.h:1
ULONG EndCylinderNumber
Definition: ntdddisk.h:514
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG StartHeadNumber
Definition: ntdddisk.h:515
Definition: ps.c:97