ReactOS 0.4.15-dev-7660-g0086d05
vfdrdwr.c
Go to the documentation of this file.
1/*
2 vfdrdwr.c
3
4 Virtual Floppy Drive for Windows NT platform
5 Kernel mode driver: Read and Write 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//
15// IRP_MJ_READ and IRP_MJ_WRITE dispatcher
16// Insert the IRP into the IRP queue list.
17// Actual operation is performed by the device thread
18//
19#define IO_READ_OFF(p) (p)->Parameters.Read.ByteOffset.QuadPart
20#define IO_READ_LEN(p) (p)->Parameters.Read.Length
21
26 IN PIRP Irp)
27{
29 PIO_STACK_LOCATION io_stack;
31
33
35
36#if DBG
37 if (DeviceObject && DeviceObject->DeviceExtension &&
38 ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->DeviceName.Buffer) {
39
40 VFDTRACE(VFDINFO, ("[VFD] %-40s %ws\n",
41 GetMajorFuncName(io_stack->MajorFunction),
42 ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->DeviceName.Buffer));
43 }
44 else {
45 VFDTRACE(VFDINFO, ("[VFD] %-40s %p\n",
46 GetMajorFuncName(io_stack->MajorFunction),
48 }
49#endif // DBG
50
51#ifdef VFD_PNP
52
53 if (device_extension->DeviceState != VFD_WORKING) {
54
55 // Device is not yet started or being removed, reject any IO request
56 // TODO: Queue the IRPs
57
58 VFDTRACE(VFDWARN, ("[VFD] Device not ready\n"));
59
61 goto complete_request;
62 }
63 else {
64 status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
65
66 if (!NT_SUCCESS(status)) {
67 VFDTRACE(0, ("[VFD] Acquire RemoveLock failed: %s\n", GetStatusName(status)));
68
69 goto complete_request;
70 }
71 }
72#endif // VFD_PNP
73
74/*
75 // Check if volume verification is required
76
77 if ((DeviceObject->Flags & DO_VERIFY_VOLUME) &&
78 !(io_stack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
79
80 status = STATUS_VERIFY_REQUIRED;
81 goto complete_request;
82 }
83*/
84
85 // Check if an image is opened
86
87 if (!device_extension->FileHandle &&
88 !device_extension->FileBuffer) {
89
91 goto complete_request;
92 }
93
94
95 // Check if write operation is allowed
96
97 if (io_stack->MajorFunction == IRP_MJ_WRITE &&
99
101 goto complete_request;
102 }
103
104
105 // Check for invalid parameters. It is an error for the starting offset
106 // + length to go past the end of the partition, or for the length or
107 // offset to not be a proper multiple of the sector size.
108 //
109 // Others are possible, but we don't check them since we trust the
110 // file system and they aren't deadly.
111
112 if ((IO_READ_OFF(io_stack) + IO_READ_LEN(io_stack)) >
114
115 VFDTRACE(VFDWARN,
116 ("[VFD] Offset:%I64u + Length:%u goes past the media size %lu\n",
117 IO_READ_OFF(io_stack), IO_READ_LEN(io_stack),
119
121 goto complete_request;
122 }
123
124 if (!VFD_SECTOR_ALIGNED((IO_READ_LEN(io_stack))) ||
125 !VFD_SECTOR_ALIGNED((IO_READ_OFF(io_stack)))) {
126
127 VFDTRACE(VFDWARN,
128 ("[VFD] Invalid Alignment Offset:%I64u Length:%u\n",
129 IO_READ_OFF(io_stack), IO_READ_LEN(io_stack)));
130
132 goto complete_request;
133 }
134
135 // If read/write data length is 0, we are done
136
137 if (IO_READ_LEN(io_stack) == 0) {
139 goto complete_request;
140 }
141
142 // It seems that actual read/write operation is going to take place
143 // so mark the IRP as pending, insert the IRP into queue list
144 // then signal the device thread to perform the operation
145
147
149 &device_extension->ListHead,
150 &Irp->Tail.Overlay.ListEntry,
151 &device_extension->ListLock);
152
154 &device_extension->RequestEvent,
155 (KPRIORITY) 0,
156 FALSE);
157
158 VFDTRACE(VFDINFO,("[VFD] %-40s - STATUS_PENDING\n",
159 GetMajorFuncName(io_stack->MajorFunction)));
160
161 return STATUS_PENDING;
162
163complete_request:
164
165 // complete the request immediately
166
167 Irp->IoStatus.Status = status;
168 Irp->IoStatus.Information = 0;
170
171 VFDTRACE(VFDWARN,("[VFD] %-40s - %s\n",
172 GetMajorFuncName(io_stack->MajorFunction),
173 GetStatusName(status)));
174
175 return status;
176}
177
178//
179// Substitute for MmGetSystemAddressForMdlSafe
180// for NT 4.0 DDK does not provide its equivqlent
181// originally written by Bruce Engle for filedisk
182//
183static PVOID
185 IN PMDL Mdl,
187{
188#if (VER_PRODUCTBUILD >= 2195)
189 if (OsMajorVersion >= 5) {
191 }
192 else {
193#endif // (VER_PRODUCTBUILD >= 2195)
194 CSHORT MdlMappingCanFail;
195 PVOID MappedSystemVa;
196
197 MdlMappingCanFail = (CSHORT)(Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL);
198
199 Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
200
201 MappedSystemVa = MmGetSystemAddressForMdl(Mdl);
202
203 if (!MdlMappingCanFail) {
204 Mdl->MdlFlags &= ~MDL_MAPPING_CAN_FAIL;
205 }
206
207 return MappedSystemVa;
208#if (VER_PRODUCTBUILD >= 2195)
209 }
210#endif // (VER_PRODUCTBUILD >= 2195)
211}
212
213//
214// Read sectors from image file or RAM disk buffer into read buffer
215//
216VOID
218 IN PDEVICE_EXTENSION DeviceExtension,
219 IN OUT PIRP Irp,
222{
223 PVOID buf;
224
225 VFDTRACE(VFDINFO,("[VFD] VfdReadData - IN\n"));
226
228 Irp->MdlAddress, NormalPagePriority);
229
230 if (!buf) {
231 VFDTRACE(0,
232 ("[VFD] MmGetSystemAddressForMdlPrettySafe\n"));
233
234 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
235 return;
236 }
237
238 if (DeviceExtension->FileHandle) {
239
240 // Read from image file
241 Irp->IoStatus.Status = ZwReadFile(
242 DeviceExtension->FileHandle,
243 NULL,
244 NULL,
245 NULL,
246 &Irp->IoStatus,
247 buf,
248 Length,
249 Offset,
250 NULL);
251
252 if (NT_SUCCESS(Irp->IoStatus.Status)) {
253 Irp->IoStatus.Information = Length;
254 }
255 else {
256 VFDTRACE(0,
257 ("[VFD] ZwReadFile - %s\n",
258 GetStatusName(Irp->IoStatus.Status)));
259 }
260 }
261 else if (DeviceExtension->FileBuffer) {
262
263 // Copy from RAM disk buffer
265 buf,
266 DeviceExtension->FileBuffer + Offset->QuadPart,
267 Length);
268
269 Irp->IoStatus.Status = STATUS_SUCCESS;
270 Irp->IoStatus.Information = Length;
271 }
272 else {
273 // no image opened
274 Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
275 }
276
277 VFDTRACE(VFDINFO,("[VFD] VfdReadData - %s\n",
278 GetStatusName(Irp->IoStatus.Status)));
279
280 return;
281}
282
283//
284// Write sectors from write buffer into image file or RAM image buffer
285//
286VOID
288 IN PDEVICE_EXTENSION DeviceExtension,
289 IN OUT PIRP Irp,
292{
293 PVOID buf;
294
295 VFDTRACE(VFDINFO,("[VFD] VfdWriteData - IN\n"));
296
298 Irp->MdlAddress, NormalPagePriority);
299
300 if (!buf) {
301 VFDTRACE(0,
302 ("[VFD] MmGetSystemAddressForMdlPrettySafe\n"));
303
304 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
305 return;
306 }
307
308 if (DeviceExtension->FileHandle) {
309
310 // Write into image file
311 Irp->IoStatus.Status = ZwWriteFile(
312 DeviceExtension->FileHandle,
313 NULL,
314 NULL,
315 NULL,
316 &Irp->IoStatus,
317 buf,
318 Length,
319 Offset,
320 NULL);
321
322 if (NT_SUCCESS(Irp->IoStatus.Status)) {
323 Irp->IoStatus.Information = Length;
324 }
325 else {
326 VFDTRACE(0,
327 ("[VFD] ZwWriteFile - %s\n",
328 GetStatusName(Irp->IoStatus.Status)));
329 }
330 }
331 else if (DeviceExtension->FileBuffer) {
332
333 // Deal with the modify flag
335 DeviceExtension->FileBuffer + Offset->QuadPart,
336 buf, Length) != Length) {
337 DeviceExtension->MediaFlags |= VFD_FLAG_DATA_MODIFIED;
338 }
339
340 // Copy into RAM image buffer
342 DeviceExtension->FileBuffer + Offset->QuadPart,
343 buf, Length);
344
345 Irp->IoStatus.Status = STATUS_SUCCESS;
346 Irp->IoStatus.Information = Length;
347 }
348 else {
349 // no image opened
350 Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
351 }
352
353 VFDTRACE(VFDINFO,("[VFD] VfdWriteData - %s\n",
354 GetStatusName(Irp->IoStatus.Status)));
355
356 return;
357}
LONG NTSTATUS
Definition: precomp.h:26
struct _device_extension device_extension
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG KPRIORITY
Definition: compat.h:803
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
IoMarkIrpPending(Irp)
@ NormalPagePriority
Definition: imports.h:56
enum _MM_PAGE_PRIORITY MM_PAGE_PRIORITY
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: ps.c:97
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
short CSHORT
Definition: umtypes.h:127
#define VFDTRACE(LEVEL, STRING)
Definition: vfddbg.h:72
ULONG OsMajorVersion
#define VFD_SECTOR_ALIGNED(b)
Definition: vfdio.h:46
#define VFD_SECTOR_TO_BYTE(s)
Definition: vfdio.h:45
#define IO_READ_OFF(p)
Definition: vfdrdwr.c:19
#define IO_READ_LEN(p)
Definition: vfdrdwr.c:20
VOID VfdReadData(IN PDEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp, IN ULONG Length, IN PLARGE_INTEGER Offset)
Definition: vfdrdwr.c:217
NTSTATUS NTAPI VfdReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: vfdrdwr.c:24
VOID VfdWriteData(IN PDEVICE_EXTENSION DeviceExtension, IN OUT PIRP Irp, IN ULONG Length, IN PLARGE_INTEGER Offset)
Definition: vfdrdwr.c:287
static PVOID MmGetSystemAddressForMdlPrettySafe(IN PMDL Mdl, IN MM_PAGE_PRIORITY Priority)
Definition: vfdrdwr.c:184
#define VFD_FLAG_DATA_MODIFIED
Definition: vfdtypes.h:69
#define VFD_FLAG_WRITE_PROTECTED
Definition: vfdtypes.h:68
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
#define IoAcquireRemoveLock(RemoveLock, Tag)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define MmGetSystemAddressForMdl(Mdl)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31