ReactOS 0.4.16-dev-338-g34e76ad
reqtools.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/reqtools.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/*
46 This file contains functions used by fault.c to do blocking resource
47 acquisition. To call one of these functions, fill out your
48 MM_REQUIRED_RESOURCES with a pointer to the desired function and configure
49 the other members as below.
50 */
51
52/* INCLUDES *****************************************************************/
53
54#include <ntoskrnl.h>
55#include "newmm.h"
56#define NDEBUG
57#include <debug.h>
58
59#define DPRINTC DPRINT
60
61VOID
64
65/*
66
67Blocking function to acquire zeroed pages from the balancer.
68
69Upon entry:
70
71Required->Amount: Number of pages to acquire
72Required->Consumer: consumer to charge the page to
73
74Upon return:
75
76Required->Pages[0..Amount]: Allocated pages.
77
78The function fails unless all requested pages can be allocated.
79
80 */
86{
87 ULONG i;
89
90 for (i = 0; i < Required->Amount; i++)
91 {
92 DPRINTC("MiGetOnePage(%s:%d)\n", Required->File, Required->Line);
94 TRUE,
95 &Required->Page[i]);
96 if (!NT_SUCCESS(Status))
97 {
98 while (i > 0)
99 {
101 Required->Page[i-1]);
102 i--;
103 }
104 return Status;
105 }
106 }
107
108 return Status;
109}
110
111/*
112
113Blocking function to read (part of) a page from a file.
114
115Upon entry:
116
117Required->Context: a FILE_OBJECT to read
118Required->Consumer: consumer to charge the page to
119Required->FileOffset: Offset to read at
120Required->Amount: Number of bytes to read (0 -> 4096)
121
122Upon return:
123
124Required->Page[Required->Offset]: The allocated and read in page
125
126The indicated page is filled to Required->Amount with file data and zeroed
127afterward.
128
129 */
130
132NTAPI
135 PMM_REQUIRED_RESOURCES RequiredResources)
136{
137 PFILE_OBJECT FileObject = RequiredResources->Context;
138 PPFN_NUMBER Page = &RequiredResources->Page[RequiredResources->Offset];
139 PLARGE_INTEGER FileOffset = &RequiredResources->FileOffset;
141 PVOID PageBuf = NULL;
143 IO_STATUS_BLOCK IOSB;
144 UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
145 PMDL Mdl = (PMDL)MdlBase;
147
148 DPRINTC("Pulling page %I64x from %wZ to %Ix\n",
149 FileOffset->QuadPart,
150 &FileObject->FileName,
151 *Page);
152
153 Status = MmRequestPageMemoryConsumer(RequiredResources->Consumer,
154 TRUE,
155 Page);
156
157 if (!NT_SUCCESS(Status))
158 {
159 DPRINT1("Status: %x\n", Status);
160 return Status;
161 }
162
165 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
166
169 if (Status == STATUS_PENDING)
170 {
172 Status = IOSB.Status;
173 }
174 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
175 {
176 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
177 }
178
180 if (!PageBuf)
181 {
182 MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
183 return STATUS_NO_MEMORY;
184 }
185
186 RtlZeroMemory((PCHAR)PageBuf+RequiredResources->Amount,
187 PAGE_SIZE-RequiredResources->Amount);
188
190
191 DPRINT("Read Status %x (Page %x)\n", Status, *Page);
192
193 if (!NT_SUCCESS(Status))
194 {
195 MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
196 DPRINT("Status: %x\n", Status);
197 return Status;
198 }
199
200 return STATUS_SUCCESS;
201}
202
203/*
204
205Blocking function to read a swap page into a memory page.
206
207Upon entry:
208
209Required->Consumer: consumer to charge the page to
210Required->SwapEntry: swap entry to use
211
212Upon return:
213
214Required->Page[Required->Offset]: Populated page
215
216*/
217
219NTAPI
223{
225
227 TRUE,
228 &Resources->Page[Resources->Offset]);
229 if (!NT_SUCCESS(Status))
230 {
231 DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
232 return Status;
233 }
234
236 Resources->Page[Resources->Offset]);
237 if (!NT_SUCCESS(Status))
238 {
239 DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
240 return Status;
241 }
242
244 Resources->SwapEntry);
245
246 DPRINT1("MiSwapInPage(%x,%x)\n",
247 Resources->Page[Resources->Offset],
248 Resources->SwapEntry);
249
250 return Status;
251}
252
253/*
254
255A way to write a page without a lock acquired using the same blocking mechanism
256as resource acquisition.
257
258Upon entry:
259
260Required->Page[Required->Offset]: Page to write
261Required->Context: FILE_OBJECT to write to
262Required->FileOffset: offset to write at
263
264This always does a paging write with whole page size. Note that paging IO
265doesn't change the valid data length of a file.
266
267*/
268
270NTAPI
274{
275 DPRINT1("MiWriteFilePage(%x,%x)\n",
276 Required->Page[Required->Offset],
277 Required->FileOffset.LowPart);
278
279 return MiWriteBackPage(Required->Context,
280 &Required->FileOffset,
281 PAGE_SIZE,
282 Required->Page[Required->Offset]);
283}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
UCHAR KIRQL
Definition: env_spec_w32.h:591
#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
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1201
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define KernelMode
Definition: asm.h:34
#define MiWriteBackPage(F, O, L, P)
Definition: newmm.h:156
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN _Inout_ PMM_REQUIRED_RESOURCES Required
Definition: newmm.h:210
_In_ PMEMORY_AREA MemoryArea
Definition: newmm.h:207
@ NotificationEvent
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
NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:204
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:484
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:313
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
NTSTATUS NTAPI MiWriteFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Required)
Definition: reqtools.c:271
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:111
#define DPRINTC
Definition: reqtools.c:59
NTSTATUS NTAPI MiReadFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES RequiredResources)
Definition: reqtools.c:133
NTSTATUS NTAPI MiGetOnePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Required)
Definition: reqtools.c:83
NTSTATUS NTAPI MiSwapInPage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Resources)
Definition: reqtools.c:220
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
LARGE_INTEGER FileOffset
Definition: newmm.h:60
PFN_NUMBER Page[2]
Definition: newmm.h:62
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
PVOID PMDL
Definition: usb.h:39
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2274
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
MDL
Definition: mmtypes.h:117
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char UCHAR
Definition: xmlstorage.h:181