ReactOS 0.4.15-dev-8428-g6910fa6
io.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 *
19 * PROJECT: ReactOS kernel
20 * FILE: ntoskrnl/cache/section/io.c
21 * PURPOSE: Implements section objects
22 *
23 * PROGRAMMERS: Rex Jolliff
24 * David Welch
25 * Eric Kohl
26 * Emanuele Aliberti
27 * Eugene Ingerman
28 * Casper Hornstrup
29 * KJK::Hyperion
30 * Guido de Jong
31 * Ge van Geldorp
32 * Royce Mitchell III
33 * Filip Navara
34 * Aleksey Bragin
35 * Jason Filby
36 * Thomas Weidenmueller
37 * Gunnar Andre' Dalsnes
38 * Mike Nordell
39 * Alex Ionescu
40 * Gregor Anich
41 * Steven Edwards
42 * Herve Poussineau
43 */
44
45/* INCLUDES *****************************************************************/
46
47#include <ntoskrnl.h>
48#include "newmm.h"
49#define NDEBUG
50#include <debug.h>
51#include <reactos/exeformat.h>
52
54
58{
60}
61
62/*
63
64Note:
65This completion function is really required. Paging io completion does almost
66nothing, including freeing the mdls.
67
68*/
69_Function_class_(IO_COMPLETION_ROUTINE)
72MiSimpleReadComplete(PDEVICE_OBJECT DeviceObject,
73 PIRP Irp,
75{
76 PMDL Mdl = Irp->MdlAddress;
77
78 /* Unlock MDL Pages, page 167. */
79 DPRINT("MiSimpleReadComplete %p\n", Irp);
80 while (Mdl)
81 {
82 DPRINT("MDL Unlock %p\n", Mdl);
84 Mdl = Mdl->Next;
85 }
86
87 /* Check if there's an MDL */
88 while ((Mdl = Irp->MdlAddress))
89 {
90 /* Clear all of them */
91 Irp->MdlAddress = Mdl->Next;
93 }
94
95 return STATUS_SUCCESS;
96}
97
98/*
99
100MiSimpleRead is a convenience function that provides either paging or non
101paging reads. The caching and mm systems use this in paging mode, where
102a completion function is required as above. The Paging BOOLEAN determines
103whether the read is issued as a paging read or as an ordinary buffered read.
104
105*/
106
108NTAPI
113 BOOLEAN Paging,
115{
117 PIRP Irp = NULL;
118 KEVENT ReadWait;
121
124 ASSERT(Buffer);
126
129 ReadStatus->Information = 0;
130
132
133 DPRINT("PAGING READ: FileObject %p <%wZ> Offset %08x%08x Length %ul\n",
135 &FileObject->FileName,
136 FileOffset->HighPart,
137 FileOffset->LowPart,
138 Length);
139
141
144 Buffer,
145 Length,
147 ReadStatus);
148
149 if (!Irp)
150 {
151 return STATUS_NO_MEMORY;
152 }
153
155
156 Irp->UserEvent = &ReadWait;
157 Irp->Tail.Overlay.OriginalFileObject = FileObject;
158 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
162 IrpSp->CompletionRoutine = MiSimpleReadComplete;
163
164 /* Non paging case, the FileObject will be dereferenced at completion */
165 if (!Paging)
167
169 if (Status == STATUS_PENDING)
170 {
171 DPRINT("KeWaitForSingleObject(&ReadWait)\n");
172 if (!NT_SUCCESS(KeWaitForSingleObject(&ReadWait,
173 Suspended,
175 FALSE,
176 NULL)))
177 {
178 DPRINT1("Warning: Failed to wait for synchronous IRP\n");
179 ASSERT(FALSE);
180 return Status;
181 }
182 }
183
184 DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
185 /* When "ReadStatus->Information > 0" is false and "ReadStatus->Status == STATUS_END_OF_FILE" is true
186 * it means that read pointer is out of file, so we must fail */
187 Status = ReadStatus->Status == STATUS_END_OF_FILE && ReadStatus->Information > 0 ? STATUS_SUCCESS : ReadStatus->Status;
188 return Status;
189}
190
191#ifdef NEWCC
192/*
193
194Convenience function for writing from kernel space. This issues a paging
195write in all cases.
196
197*/
198
200NTAPI
206 const char *File,
207 int Line)
208{
210 PIRP Irp = NULL;
211 KEVENT ReadWait;
214
217 ASSERT(Buffer);
219
222
223 DPRINT("PAGING WRITE: FileObject %p <%wZ> Offset 0x%I64x Length %lu (%s:%d)\n",
225 &FileObject->FileName,
226 FileOffset->QuadPart,
227 Length,
228 File,
229 Line);
230
232
235 Buffer,
236 Length,
238 ReadStatus);
239
240 if (!Irp)
241 {
242 return STATUS_NO_MEMORY;
243 }
244
246
247 Irp->UserEvent = &ReadWait;
248 Irp->Tail.Overlay.OriginalFileObject = FileObject;
249 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
253 IrpSp->CompletionRoutine = MiSimpleReadComplete;
254
255 DPRINT("Call Driver\n");
257 DPRINT("Status %x\n", Status);
258
259 if (Status == STATUS_PENDING)
260 {
261 DPRINT("KeWaitForSingleObject(&ReadWait)\n");
262 if (!NT_SUCCESS(KeWaitForSingleObject(&ReadWait,
263 Suspended,
265 FALSE,
266 NULL)))
267 {
268 DPRINT1("Warning: Failed to wait for synchronous IRP\n");
269 ASSERT(FALSE);
270 return Status;
271 }
272 }
273
274 DPRINT("Paging IO Done: %08x\n", ReadStatus->Status);
275 return ReadStatus->Status;
276}
277
279FAST_MUTEX MiWriteMutex;
280
281/*
282
283Function which uses MiSimpleWrite to write back a single page to a file.
284The page in question does not need to be mapped. This function could be
285made a bit more efficient by avoiding the copy and making a system space
286mdl.
287
288*/
289
291NTAPI
296 const char *File,
297 int Line)
298{
300 PVOID Hyperspace;
304
305 if (!PageBuffer) return STATUS_NO_MEMORY;
306
308 if (!Hyperspace)
309 {
310 ExFreePool(PageBuffer);
311 return STATUS_NO_MEMORY;
312 }
313 RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
315
316 DPRINT("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n",
317 &FileObject->FileName,
318 FileOffset->u.HighPart,
319 FileOffset->u.LowPart,
320 File,
321 Line);
322
325 PageBuffer,
326 Length,
327 &Iosb);
328
329 ExFreePool(PageBuffer);
330
331 if (!NT_SUCCESS(Status))
332 {
333 DPRINT1("MiSimpleWrite failed (%x)\n", Status);
334 }
335
336 return Status;
337}
338#endif
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
Definition: File.h:16
_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:33
static UCHAR ReadStatus(_In_ PUCHAR ReadDataPort)
Definition: hardware.c:167
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
return Iosb
Definition: create.c:4402
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define IoFreeMdl
Definition: fxmdl.h:89
Status
Definition: gdiplustypes.h:25
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define ASSERT(a)
Definition: mode.c:44
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define KernelMode
Definition: asm.h:34
NTSTATUS NTAPI _MiSimpleWrite(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, PIO_STATUS_BLOCK ReadStatus, const char *file, int line)
NTSTATUS NTAPI _MiWriteBackPage(PFILE_OBJECT FileObject, PLARGE_INTEGER Offset, ULONG Length, PFN_NUMBER Page, const char *File, int Line)
#define MiSimpleWrite(F, O, B, L, R)
Definition: newmm.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
KEVENT MpwThreadEvent
KEVENT CcpLazyWriteEvent
Definition: io.c:53
PDEVICE_OBJECT NTAPI MmGetDeviceObjectForFile(IN PFILE_OBJECT FileObject)
Definition: io.c:57
NTSTATUS NTAPI MiSimpleRead(PFILE_OBJECT FileObject, PLARGE_INTEGER FileOffset, PVOID Buffer, ULONG Length, BOOLEAN Paging, PIO_STATUS_BLOCK ReadStatus)
Definition: io.c:109
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:91
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:28
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: ncftp.h:79
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: iotypes.h:3314
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
FAST_MUTEX
Definition: extypes.h:17
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_SYNCHRONOUS_API
#define IRP_PAGING_IO
#define SL_INVOKE_ON_ERROR
Definition: iotypes.h:3329
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_SYNCHRONOUS_PAGING_IO
#define SL_INVOKE_ON_SUCCESS
Definition: iotypes.h:3328
#define IRP_NOCACHE
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Suspended
Definition: ketypes.h:420
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17